Dockerfile usage and case demonstration

What is a Dockerfile?

A Dockerfile is a text file used to build an image. The text contains instructions and instructions for building an image.

Why use a Dockerfile

Question: Many images are officially provided in dockerhub to meet all our services, why do we need custom images?

Core function: In the future, users can package their own applications into images, so that our applications can be run in containers. The official images can also be extended to package the images of our production applications.

Dockerfile format

two types of rows

  • Comment lines starting with #
  • Instruction lines starting with a dedicated "Instruction"

Dockerfile common instructions

Official build reference

instructiondescribe
FROMSpecifies the base lmage to use when building a new lmage. Usually it must be the first valid instruction of the Dockerfile, but an ARG instruction can also appear in front of it
LABELMetadata attached to Image, key-value format; usually followed by MAINTAINER to describe author information
ENVSet environment variables in key-value format, which can be called by subsequent commands, and these variables will also exist in the Container running based on the newly generated Ilmage
ARGDefines a variable dedicated to the build process, but only valid for subsequent calls to the indicator, whose value can be passed with the command-line option "--build-arg"
RUNRun the specified command based on the lmage defined in FROM, and the generated result will be used as an image layer of the new Image and can be used by subsequent instructions
CMDWhen running the Container based on the lmage generated by the Dockerfile, CMD can specify the default running program in the container, so it should only be defined once
ENTRYPONTSimilar to the function of the CMD instruction, but cannot be overridden by the application program to be run specified by the command line, and the content of CMD will be used as the parameter of the program defined in the instruction when it coexists with CMD
WORKDIRSet the working directory for commands such as RUN, CMD, ENTRPOINT, COPY, and ADD
COPYCopy the file or directory on the host or in the build result of the previous stage (the --from option is required) to generate a new image layer
ADDSimilar in function to the COPY directive, but ADD additionally supports the use of URL-specified resources as source files
VOLUMESpecifies the directory expected to be used as the Volume when running the Container based on the newly generated Image
EXPOSESpecifies the port that is expected to be exposed when running the Container based on the newly generated Image, but the actual exposure depends on the options of the "docket run" command, supporting TCP and UDP protocols
USERSpecify the runner identity UID, and an optional GID, for the application to be run in the RUN, CMD, and ENTRYPOING instructions following this instruction in the Dockerfile
ONBUILDTrigger, which takes effect when a new image built by this Dockerfile is used as the base image with the FROM instruction in another Dockerfile

FROM

FROM : Customized images are all FROM-based images (FROM must be the first line of Docker's non-empty beginning)

grammar:
FROM <base image>

LABEL MAINTAINER

LABEL MAINTAINER : the author who added the mirror

grammar:
LABEL MAINTAINER [author] [Mail]

ENV

ENV : Set the environment variable and define the environment variable, then in the subsequent instructions, this environment variable can be used.

grammar:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

ARG

ARG : Construction parameter, the same as ENV. But the scope is different. The environment variable set by ARG is only valid in the Dockerfile, that is to say, it is only valid during the docker build process, and this environment variable does not exist in the built image.

grammar:
ARG <parameter name>[=<Defaults>]

RUN

RUN: Used to execute the command line command that follows. There are two formats:

  • shell format:

    grammar:
    RUN <command line command>
    # <command line command> is equivalent to a shell command operating at the terminal.
    
  • exec format:

    grammar: 
    RUN ["executable file", "parameter 1", "parameter 2"]
    # E.g:
    # RUN ["./test.php", "dev", "offline"] is equivalent to RUN ./test.php dev offline
    

CMD

Similar to the RUN instruction, it is used to run the program, but the time point of the two runs is different:

  • CMD is run when docker run.
  • RUN is in docker build.
  • Function: Specify the program to be run by default for the started container. When the program runs, the container ends. The program specified by the CMD directive can be overridden by the program to be run specified in the docker run command line parameter.

Note: If there are multiple CMD instructions in the Dockerfile, only the last one will take effect.

grammar: 
CMD <shell Order> 
CMD ["<executable or command>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # This way of writing is to provide default parameters for the program specified by the ENTRYPOINT instruction

ENTRYPONT

Similar to the CMD command, but it will not be overridden by the commands specified by the command line parameters of docker run, and these command line parameters will be sent as parameters to the program specified by the ENTRYPOINT command.

However, if you run docker run with the --entrypoint option, it will override the program specified by the ENTRYPOINT directive.

Advantages: When executing docker run, you can specify the parameters required for ENTRYPOINT to run.

Note: If there are multiple ENTRYPOINT directives in the Dockerfile, only the last one will take effect.

grammar:
ENTRYPOINT <shell Order>
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

WORKDIR

WORKDIR : Specifies the working directory. The working directory, specified with WORKDIR, will exist at every level of the build image. (The working directory specified by WORKDIR must be created in advance).
In the process of docker build building an image, each RUN command is a new layer. Only directories created via WORKDIR persist.

WORKDIR <working directory path>

COPY

COPY : Copy command, copy files or directories from the context directory to the specified path in the container.

grammar:
COPY [--chown=<user>:<group>] <source path 1>...  <Target path>
COPY [--chown=<user>:<group>] ["<source path 1>",...  "<Target path>"]

ADD

ADD: The ADD command is similar to COPY (under the same requirements, COPY is officially recommended). The functions are also similar, with the following differences:

Advantages of ADD: If the <source file> is a tar compressed file, and the compression format is gzip, bzip2 and xz, it will be automatically copied and decompressed to <target path>; and the source file directory can be a URL
Disadvantage of ADD: tar archives cannot be copied without decompression. Will invalidate the image build cache, which may make image builds slower. Whether to use it or not can be determined according to whether it needs to be automatically decompressed.

grammar:
ADD <src> <dest>

VOLUME

VOLUME : Defines anonymous data volumes. If you forget to mount the data volume when starting the container, it will be automatically mounted to the anonymous volume.

effect:

  • Avoid important data loss due to container restart, which is very fatal.
  • Avoid constantly growing containers.
grammar:
VOLUME ["<path 1>", "<path 2>"...]
VOLUME <path>

EXPOSE

EXPOSE: Just declare the port.

effect:

  • Help mirror users understand the daemon port of this mirror service to facilitate configuration mapping.
  • When using random port mapping at runtime, that is, when docker run -P, the port of EXPOSE will be automatically mapped randomly.
grammar:
EXPOSE <port 1> [<port 2>...]

USER

USER : used to specify the user and user group to execute subsequent commands, here is only to switch the user for subsequent command execution (the user and user group must already exist in advance).

grammar:
USER <username>[:<user group>]

ONBUILD

ONBUILD : Used to delay the execution of build commands. Simply put, the command specified with ONBUILD in the Dockerfile will not be executed during the process of building the image this time (assuming the image is test-build). When a new Dockerfile uses the previously built image FROM test-build , when the Dockerfile of the new image is built, the command specified by ONBUILD in the Dockerfile of test-build will be executed.

grammar:
ONBUILD <other instructions>

case presentation

project directory

[root@podman httpd]# tree
.
├── Dockerfile
├── packges
│   ├── apr-1.7.0.tar.gz
│   ├── apr-util-1.6.1.tar.gz
│   └── httpd-2.4.54.tar.gz
└── scripts
    └── entrypoint.sh

2 directories, 5 files

entrypoint.sh script file content:

[root@podman httpd]# cat scripts/entrypoint.sh 
#!/bin/bash

sed -i '/#ServerName/s/#//g' /usr/local/apache/conf/httpd.conf

exec "$@"

[root@podman httpd]# chmod +x scripts/entrypoint.sh 

dockerfile for making httpd image based on centos

[root@podman httpd]# vim Dockerfile 
FROM centos

LABEL MAINTAINER='wjh 3285552779@qq.com'

ENV apr_version=1.7.0 apr_util_version=1.6.1 httpd_version=2.4.54
ENV PATH /usr/local/apache/bin:$PATH

ADD packages/httpd-${httpd_version}.tar.gz        /usr/src
ADD packages/apr-${apr_version}.tar.gz            /usr/src
ADD packages/apr-util-${apr_util_version}.tar.gz  /usr/src
ADD scripts/entrypoint.sh /

RUN rm -f /etc/yum.repos.d/* && \
    curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo && \
    sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo && \
    yum clean all && yum makecache && \
    yum -y install make gcc gcc-c++ openssl-devel pcre-devel expat-devel libtool libxml2-devel &&\
    useradd -r -M -s /sbin/nologin apache && \
    cd /usr/src/apr-${apr_version} &&\
    sed -i '/$RM "$cfgfile"/d' configure &&\
    ./configure --prefix=/usr/local/apr && \
    make && make install && \
    cd /usr/src/apr-util-${apr_util_version} &&\
    ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr &&\
    make && make install &&\
    cd /usr/src/httpd-${httpd_version} &&\
    ./configure --prefix=/usr/local/apache \
    --enable-so \
    --enable-ssl \
    --enable-cgi \
    --enable-rewrite \
    --with-zlib \
    --with-pcre \
    --with-apr=/usr/local/apr \
    --with-apr-util=/usr/local/apr-util/ \
    --enable-modules=most \
    --enable-mpms-shared=all \
    --with-mpm=prefork && \
    make && make install && \
    yum clean all && \
    yum -y remove gcc gcc-gcc+ make && \
    rm -rf /tmp/* /usr/src/*

WORKDIR /usr/local/apache

EXPOSE 80

CMD ["httpd","-D","FOREGROUND"]
ENTRYPOINT ["/bin/bash","/entrypoint.sh"]

Explanation: Lines 41 to 43 delete some unnecessary files to reduce the size of the image.

Create an image

[root@podman httpd]# podman build -t httpd:v2.0 .

mirror test

[root@podman httpd]# podman run -d --name web3 -p 80:80 httpd:v2.0
da8ddafdddfc53fc3c60184db7e35d3ad6f3443b12a89ef69eb0971db16af979
[root@podman httpd]# podman ps
CONTAINER ID  IMAGE                 COMMAND               CREATED         STATUS             PORTS               NAMES
da8ddafdddfc  localhost/httpd:v2.0  httpd -D FOREGROU...  20 seconds ago  Up 21 seconds ago  0.0.0.0:80->80/tcp  web3
[root@podman httpd]# podman inspect -l | grep -i 'ipaddr'
               "IPAddress": "10.88.0.3",
                         "IPAddress": "10.88.0.3",
[root@podman httpd]# curl 10.88.0.3
<html><body><h1>It works!</h1></body></html>

Upload to docker hub:

[root@podman httpd]# podman tag httpd:v2.0 docker.io/wjh0077/httpd:v2.0
[root@podman httpd]# podman login docker.io 
Username: wjh0077
Password: 
Login Succeeded!
[root@podman httpd]# podman tag httpd:v2.0 docker.io/wjh0077/httpd:v2.0
[root@podman httpd]# podman logout 
Removed login credentials for docker.io

Tags: Front-end Operation & Maintenance server Podman

Posted by Bizzle on Wed, 31 Aug 2022 03:35:41 +0300