Docker is very hot, if you don’t understand Dockerfile, you are OUT~

♥ Foreword

Foreword: Docker has been very popular in recent years. If you want to play Docker well, you can't get around the Dockerfile. This is the same as if you want to play a Linux server well and you can't get around the shell. Today we will talk about how to write Dockerfile and what those instructions mean.

First, let's look at a simple Dockerfile

#这个Dockerfile作用是打一个python3项目环境
FROM python:3-alpine
WORKDIR /app
ADD . /app
RUN pip3 install -r requirements.txt -i https://pypi.douban.com/simple
CMD ["python3", "main.py"]


#这个Dockerfile作用Dockerfile部署django项目
FROM centos:7
MAINTAINER haili
ADD requeriments.txt /home
WORKDIR /home
RUN yum update && yum -y install mysql && yum -y install python3-pip && pip3 install -r requirements.txt 
ADD autoTest /home/
WORKDIR /home/autoTest
EXPOSE 8000
ENTRYPOINT uwsgi --ini uwsgi.ini

If you want to learn automated testing, here I recommend a set of videos for you. This video can be said to be the first interface automation testing tutorial on the entire network at station B. At the same time, the number of online users has reached 1,000, and there are notes to collect and various Lu Dashen Technical Exchange: 798478386      

[Updated] The most detailed collection of practical tutorials for automated testing of Python interfaces taught by station B (the latest version of actual combat)_哔哩哔哩_bilibili [Updated] The most detailed collection of practical tutorials for automated testing of Python interfaces taught by station B (actual combat) The latest version) has a total of 200 videos, including: 1. [Interface Automation] The current market situation of software testing and the ability standards of testers. , 2. [Interface Automation] Fully skilled in the Requests library and the underlying method call logic, 3. [Interface Automation] interface automation combat and the application of regular expressions and JsonPath extractors, etc. For more exciting videos, please pay attention to the UP account. https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from=333.337&vd_source=488d25e59e6c5b111f7a1a1a16ecbe9a 

2. Dockerfile writing rules

  1. Instructions are case-insensitive, in order to distinguish the habit of using uppercase

  2. The first line of a Dockerfile non-comment line must be FROM

  3. The file name must be Dockerfile

  4. Dockerfile specifies a dedicated directory as the workspace

  5. All files that import mappings must be in this workspace directory

  6. Support hidden files (.dockeringore) under the Dockerfile workspace directory

  7. (.dockeringore) is used to store files that do not need to be packaged and imported into the image, and the root directory is the workspace directory

  8. Each instruction will generate a mirror layer. If there are more mirror layers, the execution efficiency will be slower. If it can be written as a specified one, it will be written as one.

3. Detailed explanation of Dockerfile instructions
1. FROM: base image
 1.1、FROM是Dockerfile文件开篇第一个非注释行代码
 1.2、用于为镜像文件构建过程指定基础镜像,后续的指令都基于该基础镜像环境运行
 1.3、基础镜像可以是任何一个镜像文件
 1.4、docker build 会在docker宿主机上查找指定的文件,如未找到会自动去Docker Hub Registry上拉取
 1.5、如果没找到对应的镜像就会返回错误信息
2. MAINTAINER: mirror author information
2.1、废弃了,使用LABLE替代

3.LABLE: image description information

3.1、LABLE author="haili"

4. COPY: copy files from the Docker host to the created new image file

4.1、COPY <src> <dest>
4.2、COPY ["<src>",.... "<dest>"]
4.3、<src>:要复制的源文件或目录,支持使用通配符
     1、<src>必须是build上下文中的路径,不能是其父目录路径
     2、如果<src>是目录,则其内部文件和子目录都会被递归复制,但是<src>目录本身不会被复制
     3、如果指定了多个<src>,或者<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾
4.4、<dest>:目标路径,即正在创建的images的文件系统路径
     1、建议使用绝对路径,否则COPY指定以WORKDIR为其实路径
     2、如果<dest>不存在,将会被自动创建,包括其父目录路径一起创建
4.5、复制文件
     COPY testFile /mnt
4.6、复制目录
     COPY testDir /mnt/testDir
     1、testDir下所有文件和目录都会被递归复制
     2、目标路径要写testDir,否则会复制到/mnt下
5. ADD: Similar to the COPY command, ADD supports tar files and URL paths
5.1、ADD <src> <dest>
5.2、ADD ["<src>",.... "<dest>"]
5.3、如果<src>为URL切<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<fimename>,如果<dest>以/结尾,则文件名URL指定的文件将被下载并保存为<dest>/fimename
5.4、如果<src>是一个压缩文件(tar),会被解压为一个目录,但是通过URL下载的tar文件不会被解压
5.5、如果是多个<src>,或者是同一个<src>使用了通配符,则<dest>必须是以/结尾的目录,如果<dest>不以/结尾,则<src>会被作为一个普通文件,<src>内容讲被写入到<dest>

6. WORKDIR: used to specify and set the working directory for all RUN, CMD, ENTRYPOINT, COPY, ADD in the Dockerfile

6.1、WORKDIR /mnt,如果目录不存在会自动创建,包括他的父目录
6.2、一个Dockerfile中WORKDIR可以出现多次,其路径也可以为相对路径,相对路径是基于前一个WORKDIR路径
6.3、WORKDIR也可以调用ENV指定的变量
6.4:举例
     from python:latest
     workdir /mnt
     run touch a.txt
     workdir /usr
     run touch b.txt

7. VOLUME: Data volume, used to create a mount point directory in the image to mount volumes on the Docker host or volumes on other containers

7.1、VOLUM mount_point
7.2、VOLUM ["mount_point1","mount_point2"]
7.3、如果挂载点目录下有文件存在,docker run命令会在卷挂载完成后将所有文件复制到容器中
8. EXPOSE: Open the specified listening port for the container to communicate with the outside world
8.1、EXPOSE <port> </portocol>
     1、<port>:端口号
     2、</portocol>:协议类型,默认为TCP协议
     EXPOSE 8080/tcp 8081/udp
8.2、不会直接对外暴露这里的端口,只有在run的时候加上-P(大写)才会将EXPOSE的端口暴露出去

9. ENV: Used to define the required environment variables for the image, which can be called by other commands in the Dockerfile (ENV, ADD, COPY, RUN, CMD)

9.1、ENV key value
     1、key之后的所有内容都会被视为value,因此,一次只能设置一个变量 
9.2、ENV key=value
     1、可以设置多个变量,每个key=value键值对为一个变量
     2、如果value中包含空格需要用反斜杠转义,也可以对value加引号进行标识,反斜杠也可以用于续行
9.3、调用格式:$variable_name 或 ${variable_name}
9.4、定义多个变量建议使用第二种方式,以便在同一层中完成
9.5、举例
     ENV DOC_DIR=/mnt/doc
     COPY index.html ${DOC_DIR:-/mnt/doc} 
     #-:如果DOC_DIR不存在则使用-后面的默认值
     #+:如果DOC_DIR存在则使用+后面的值

10. RUN: The shell command that needs to be executed when building the docker build image is run by default "/bin/sh -c"

10.1、docker build过程中需要执行的命令
10.2、RUN是在镜像构建完成之后运行结束
10.3、RUN执行的命令只能基于基础镜像的命令,执行之前先要确定基础镜像是否有该命令
10.4、一个Dockerfile可以写多个RUN
    语法一、RUN command1 && command2....  
          1、通常是shell命令且以"/bin/sh -c"来运行它,此时运行为shell的子进程
          2、进程在容器中的PID!=1,不能接收unix信号,当使用docker stop 将无法接收到
          3、RUN echo "test_demo" > a.txt 此时可以使用shell特性
    语法二、RUN ["executable","param1","param2"]
          1、executable为要运行的命令
          2、param1为命令运行的参数
          3、不会以"/bin/sh -c"运行(非shell子进程),因此不支持shell操作符如变量替换和通配符(?,*等)
          4、如果运行命令需要依赖shell特性可以增加参数,手动启动为shell的子进程
             RUN ["/bin/bash","-c","executable","param1"]
          5、list中的参数要使用双引号
11. CMD: Start the container to specify the program or command to run by default, and run by default "/bin/sh -c"
11.1、docker run过程中需要执行的命令
11.2、CMD运行结束后容器就将终止
11.3、CMD指定的命令将可以被 docker run 最后面的命令覆盖
11.4、一个Dockerfile写多个CMD只有最后一个CMD会生效
    语法一、CMD command
           1、通常是shell命令且以"/bin/sh -c"来运行它,此时运行为shell的子进程,能使用shell操作符
           2、进程在容器中的PID!=1,不能接收unix信号,当使用docker stop 将无法接收到
           3、CMD /bin/httpd -f -h ${httpd}
              此时在运行容器的时候加-it参数无法进入交互式模式,需要使用docker exec进入交互模式
    语法二、CMD ["executable","param1","param2"]
           1、不会以"/bin/sh -c"运行(非shell子进程),因此不支持shell操作符如变量替换和通配符(?,*等)
           2、如果运行命令需要依赖shell特性可以增加参数,手动启动为shell的子进程
              CMD ["/bin/bash","-c","executable","param1","param2"](有问题,不能启动容器)
    语法三、CMD ["param1","param2"]
           1、需要结合ENTRYPOINT指令提供默认参数使用
12. ENTRYPOINT: The function of the type CMD instruction, which is used to specify the default running program or command for the container
1、与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数覆盖,这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序
2、docker run命令的 --entrypoint选项参数可以覆盖ENTRYPOINT指令指定的程序
3、一个Dockerfile中可以有多个ENTRYPOINT,但是只有最后一个会生效
4、ENTRYPOINT主要用于shell作为启动其他进程的父进程,后面跟的参数被当成子进程来启动
    语法一:ENTRYPOINT command
    语法二:ENTRYPOINT  ["/bin/bash","param1","param2"]

13.CMD and ENTRYPOINT exist in Dockerfile at the same time

1、CMD的值会当做参数传递给ENTRYPOINT
2、实现使用shell子进程启动httpd
3、如果docker run再传入参数,是传给ENTRYPOINT的,因为ENTRYPOINT有自己的参数,此时CMD参数会被ducker run后面跟的参数覆盖,并不是覆盖ENTRYPOINT的参数,要覆盖ENTRYPOINT的参数需要使用--entrypoint选项
    CMD ["/bin/httpd/","-f"]
    ENTRYPOINT /bin/bash -c -h
    通过传参启动容器
    FROM python:latest
    LABLE auth="haili"
    ENV NGX_DOC_ROOT='/data/web/html'
    ADD entrypoint.sh /bin/
    CMD ['/usr/sbin/nginx','-g','daemon off;']
    ENTRYPOINT ['/bin/sh','-c','/bin/entrypoint.sh']
    1、先执行ENTRYPOINT,然后讲CMD的值当做参数传给ENTRYPOINT进行执行

14.USER: Specify the user of the program specified by any RUN, CMD, and ENTRYPOINT instructions in the Dockerfile when running the image

1、使用用户名或者UID
2、默认情况下container的运行身份为root用户
3、USER UID | user_name
4、UID 和 user_name必须存在/etc/passwd当中,否则会报错

15.HEALTHCHECK: health check, define a command to check whether the working status of the main process is healthy

15.1、HEALTHCHECK参数
    1、--interval=DURATION(default 30s) 健康检查间隔时间
    2、--timeout=DURATION(default 30s) 超时时间
    3、--start-period=DURATION(default 0s) 容器启动多久后执行健康检查
    4、--retries=N(default 30s) 检测次数
15.2、检查结果
    0:成功
    1:失败
    2:预留字段

15.3、举例
     HEALTHCHECK --interval=5m --timeout=5s CMD curl -f http://localhost:8080 ||exit1
16.SHELL: Specify the shell program to run RUN, CMD, ENTRYPOINT
17.OPSIGNAL: Send a signal to the main process
18. ARG: Parameters in the docker build process
 18.1、定义pyton镜像作者,通过参数传入
    FROM python
    ARG author="latest"
    LABLE author="${author}"
    18.2、使用
    docker build --build-arg author="haili"
    18.3、常用在docker build 过程中替换参数

19.ONBUILD: used to define a trigger in the Dockerfile

19.1、Dockerfile1中加一个ONBUILD add file,当docker build -t=testpython Dockerfile1的时候ONBUILD指令不会被执行,Dockerfile2中FROM testpython(Dockerfile1构建后生成的镜像),当运行docker build -t=test Dockerfile2的时候Dockerfile1中的ONBUILD add file会被执行
19.2、Dockerfile用于build镜像文件,此镜像文件可以作为base image被另外一个Dockerfile作为FROM参数使用,并以之构建新的镜像文件
19.3、在后面这个Dockerfile中的FROM指令在build过程中被执行时,将触发创建其base image的Dockerfile中ONBUILD指定定义的触发器
19.4、尽管任何指令都可以注册为触发器指令,但是ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令
19.5、使用包含ONBUILD指令的Dockerfile构建镜像应该使用特殊标签如,python:1.0-onbuild
19.6、ONBUILD指令中使用ADD COPY指令要格外小心,因为新构建过程山下文缺少指定的源文件就会

Guess you like

Origin blog.csdn.net/caixiangting/article/details/132233927