The preparation and construction of the Dockerfile

The basic wording

  # 说明该镜像以哪个镜像为基础
  FROM    ubuntu:latest
  # 构建者的基本信息
  MAINTAINER  wwt 
  # 拷贝文件到指定目录或文件,如果目录不存在则自动创建(目的位置需要为绝对路径或者相对于workdir)
  # 如果<src>是目录,则复制目录的整个内容(目录本身不被复制,只是其内容)
  # <src>必须是上下文根目录的想退路径,可以使用通配符
  # 如果<dest>不以/结尾,则表示把<src>中的内容写入dest文件
  # <src>可以指定多个,此时dest必须是目录
  COPY <src> <dest>
  # 指定下面所有指令的工作目录,也是我们进入容器后的目录
  WORKDIR /go/src/
  #创建容器卷,匿名映射到宿主机
  VOLUME ["/data1","/data2"]
  # 在build这个镜像时执行的操作,默认为/bin/sh
  RUN apt update && \
  apt install git
  # 要使用不同的shell,而不是/bin/sh,请使用在所需shell中传递的exec形式
  # exec格式必须使用双引号(因为被当成json解析)
  RUN [“/bin/bash”,“-c”,“echo hello”]
  # 设置环境变量  
  ENV <key1>=<val1> <key2>=<val2> 
  # 暴露端口
  EXPOSE  22 80
  # 健康检查;1.12版本引入
  # 每60秒检查一次,3秒无响应则视为失败,失败3次后容器状态变为unhealthy
  HEALTHCHECK --interval=60s--timeout=3s --retries=3 \ 
  CMD curl -fs http://localhost/ || exit 1 # 检查命令;0成功,1失败
  # 设置后后面指令运行用户;该用户必须事先已经存在
  USER wwt
  # 默认启动命令,可以在docker run时覆盖;只有最后一个CMD有效
  CMD ["ls", "-a", "-l"] # exec格式
  CMD ls -a -l # shell格式
  • Infrequently modified layer in the front layer should be frequently modified to take advantage of caching
  • The number of layers there is a maximum limit, it is best not to use the RUN command in each shell prefix, but into one
    • Use &&the command required for each series up
    • End of the line to add \a command line mode transducer
  • ADDCommand and COPYthe biggest difference is that the command will automatically extract the compressed file and access to remote file
    • More recommended RUN wgetinstead ADDget
    • Recommended volume share files, rather than add files to the mirror
  • EXPOSEExposed ports need at start -Prandomly mapped to the host port parameters
    • Do not use -Pparameters are not exposed
    • To post a --linkconnector receptacle, which must be exposed to the port dockerfile
  • CMDOr RUNis exec format , the reference is not an environment variable
    • If you want to use environment variables, should be revised to CMD ["/bin/sh", "-c", "ls", "-a", "-l"]
    • shell format is actually a shell process execution, shell environment variables are resolved
  • If you want to run a daemon , should be exec format execution
    • If executed in shell form, shell process exits at the start after executing the command, the vessel will be over
    • init process (pid = 1)) when executing shell format is a shell, and the instruction is not to be executed
    • docker stopIt can not be suspended because it sends SIGTERMa signal only accepted init process
  • If there are simultaneous ENTRYPOINTand CMDcommand, CMDas an ENTRYPOINTargument
  • Only one in Dockerfile CMDorENTRYPOINT
    • If you list more than one CMD, only the last one CMDwill take effect
  • After the environment variable is set, subsequent commands (e.g. RUN) may be used as
  • CMD, VOLUMEAnd other parameters can be when you start covering
  • WORKDIRAnd ENV, as in the setup is complete on next command
    • You can set up multiple times WORKDIRto affect different commands
    • If a relative path, it will be relative to the previous WORKDIRpath instructions
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd # 输出/a/b/c
  • Each container line command and the command line is not the same execution environment
    • So if subsequent commands rely on the front there should be written on the same line
    • E.gRUN apt update && apt install -y ssh
# 容器构建完成后会发现不存在 /app/world.txt文件
RUN cd /app
RUN echo "hello" > world.txt
  • By VOLUME, if you try to make changes to the volume after mounted directories, these changes will not take effect
    • Because each layer of the temporary image is constructed by commit, but will not be saved when a mounted volume commit
    • Solution
      • Create and modify mount folder, copy will thereafter when mounting the already existing content to the volume of
      • The command may be modified in ENTRYPOINT, or CMDbecause these instructions are executed when the container starts
RUN mkdir /data && touch /data/file
RUN chmod +x /data/file
VOLUME /data

# 或者
VOLUME /data
CMD touch /data/file && chmod +x /data/file
  • Version 1.12 introduces the health check optionHEALTHCHECK [选项] CMD <命令>
    • Before, Docker engine can only be judged by whether the container is in an abnormal state in the container main process exits. If the program locks up or an infinite loop, the application process does not quit, but the container has been unable to provide the service.
    • Output health check commands (including stdout and stderr) will be stored in a healthy state, you could use docker inspect to see
      • docker inspect --format '{{json .State.Health}}' <docker>

Here Insert Picture Description
Here Insert Picture Description

Construction of multi-stage

  • Docker v17.05 开始支持
  • 镜像体积更小
FROM golang:1.9-alpine as builder
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld/
RUN go get -d -v github.com/go-sql-driver/mysql
COPY app.go .
RUN GOARCH=amd64 GOOS=linux go build app .


FROM alpine:latest as prod
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/go/helloworld/app .
CMD ["./app"] 

  • 一个Dockerfile中可以存在多个FROM, 最后一个FROM生成最终镜像
  • 使用as来为某一阶段命名,例如上面的builder
  • 只想构建builder阶段的镜像时,go bulid增加 --target=builder 参数即可
  • COPY --from 不但可以从前置阶段中拷贝,还可以直接从一个已经存在的镜像中拷贝
    • 例如COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

通过Dockerfile构建镜像

docker build -t wwt/ubuntu:git .
# 使用Dockerfile.debug在当前目录构建镜像
docker build -f Dockerfile.debug .
# 把/home/me/myapp用作构建上下文的根
docker build -f /home/me/myapp/dockerfiles/debug /home/me/myapp
  • -t指定要创建的镜像名
  • 最后的.表示使用当前目录构建上下文(context)
  • 默认在context的根目录寻找Dockerfile
    • 也可以使用-f参数指定Dockerfile 的绝对路径
  • 构建新镜像时,每一层指令都会构建一个临时镜像
    • 每个指令都会利用上一层的临时镜像创建出一个临时容器,并在临时容器中执行指令,然后通过commit生成临时镜像
    • 如果构建失败,可以利用上一层的临时镜像创建容器,并手动执行接下来的命令来调试错误
  • 构建由Docker守护程序运行,而不是由CLI运行。构建过程所做的第一件事是将整个context (递归地) 发送给守护进程

常用镜像

busybox

  • 含有许多常用Linux工具,体积很小

alpine

  • 推荐使用 Alpine 替代Ubuntu 做为基础镜像环境
    • 镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等
  • alpine提供了自己的包管理工具 apk
    • By https://pkgs.alpinelinux.org/packages on the website package information
    • If the installer does not require the main index, but the index test or community, you can use the following methods installation package
echo "http://dl-4.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
apk --update add --no-cache <package> 
  • apk commonly used commands
apk update #更新最新本地镜像源
apk upgrade #升级软件
apk add --upgrade busybox #指定升级部分软件包
apk search #查找所以可用软件包
apk search -v #查找所有可用软件包及其描述内容
apk search -v 'acf*' #通过软件包名称查找软件包
apk search -v -d 'docker' #通过描述文件查找特定的软件包
apk info #列出所有已安装的软件包

ubuntu

  • When you try to directly use when apt-get install a software, you will be prompted E: Unable to locate package
    • Docker in the production of mirror cleared apt to streamline warehouse information, so you need to execute apt updatea command to update the repository information

reference

Published 161 original articles · won praise 19 · views 50000 +

Guess you like

Origin blog.csdn.net/winter_wu_1998/article/details/103648349