Dockerfile详细配置(以node为例)

161 阅读6分钟

1.FROM表示设置要制作的镜像基于哪个镜像

FROM指令必须是整个Dockerfile的第一个指令,如果指定的镜像不存在默认会自动从Docker Hub上下载。
格式:
  FROM <image>
  FROM <image>:<tag>
  FROM <image>@<digest>
:latest表示是最新版本
FROM node:12.22.1

2.ONBUILD设置镜像触发器

当该镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被触发
格式:
ONBUILD [INSTRUCTION]
例:

    ONBUILD ADD . /app/src
    ONBUILD RUN /usr/local/bin/python-build --dir /app/src

3.LABEL用于为镜像添加元数据

格式: LABEL <key>=<value> <key>=<value> <key>=<value>...
注:
使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔 例:

LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"

LABEL author="Bin" version="1.0" description="这是一个Bin app"

4.USER设置启动容器时用户,可以是 用户名 或 UID

格式:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
例:
USER www
使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户 镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户 USER Bin

5.VOLUME创建一个具有指定名称的挂载数据卷,可持久化该目录

格式: VOLUME [PATH,...]
例:

    VOLUME ["/data"]
    VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

注:
一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

  1. 卷可以容器间共享和重用<br/>
    
  2. 容器并不一定要和其它容器共享卷<br/>
    
  3. 修改卷后会立即生效<br/>
    
  4. 对卷的修改不会对镜像产生影响<br/>
    
  5. 卷会一直存在,直到没有任何容器在使用它<br/>
    

作用:

  • 避免重要的数据,因容器重启而丢失
  • 避免容器不断变大

6.ARG用于定义变量,与ENV作用相同,不过ARG变量不会像ENV变量那样持久化到构建好的镜像中

格式: ARG <name>[=<default value>]
例:

    ARG site
    ARG build_user=www

注: Docker 有一组预定义的ARG变量,您可以在 Dockerfile 中没有相应指令的情况下使用这些变量

    HTTP_PROXY
    http_proxy
    HTTPS_PROXY
    https_proxy
    FTP_PROXY
    ftp_proxy
    NO_PROXY
    no_proxy

使用:

    docker build --build-arg site=xxx .
    docker build --build-arg build_user .
    docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com .

ARG build_user=Bin

7.STOPSIGNAL 指令设置将被发送到容器退出的系统调用信号

格式: STOPSIGNAL signal

  • 该信号可以是与内核 syscall 表中的位置匹配的有效无符号数字(例如9),也可以是 SIGNAME 格式的信号名称(例如 SIGKILL)
  • 默认的 stop-signal 是 SIGTERM,在docker stop的时候会给容器内PID为1的进程发送这个signal,通过--stop-signal 可以设置自己需要的signal
  • 主要目的是为了让容器内的应用程序在接收到signal之后可以先处理一些事物,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,默认时间是10s

8.RUN用于在镜像容器中执行命令

其有以下两种命令执行方式: shell执行: RUN <command>
exec执行: RUN ["executable", "param1", "param2"]
注: RUN指令创建的中间镜像会被缓存,并会在下次构建中使用
如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
RUN mkdir /node

9.ADD将本地文件添加到容器文件系统中

在容器中:tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
格式: ADD <src> <dest>
ADD ["<src>","<dest>"] 用于支持包含空格的路径
例:
ADD hom* /mydir/ 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/ ? 替代一个单字符,例如:"home.txt"
ADD . /node/

10.COPY功能类似ADD,但是容器中:不会自动解压文件,也不能访问网络资源

COPY . /node/

11.WORKDIR工作目录,类似于cd命令

格式: WORKDIR PATH
例:

    WORKDIR /a  这时工作目录为/a
    WORKDIR b  这时工作目录为/a/b
    WORKDIR c  这时工作目录为/a/b/c

注:
通过WORKDIR设置工作目录后,Dockerfile中 WORKDIR 后面的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行
在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录
WORKDIR /node

12.ENV设置环境变量

格式:
ENV <key> <value> 之后的所有内容均会被视为其的组成部分,一次只能设置一个变量
ENV <key>=<value> <key>=<value> <key>=<value>... 可以设置多个变量,每个变量为一个=的键值对,如果中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
配置环境变量
ENV HOST=0.0.0.0 PORT=7004

13.EXPOSE暴露给主机可访问的容器端口

格式:
EXPOSE <port> [<port>...]
注:

  • 可以指定端口是监听TCP还是UDP,如果不指定协议,默认为TCP
  • EXPOSE并不会让容器的端口访问到主机。要使容器可访问主机,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
    例:
    EXPOSE 80 443
    EXPOSE 8080
    EXPOSE 11211/tcp 11211/udp

容器对外暴露的端口号(笔者的nestjs运行的端口号是3000)
EXPOSE 7004/udp

14.ENTRYPOINT指定容器启动程序及参数

格式:

ENTRYPOINT ["executable", "param1", "param2"] 可执行文件, 优先
ENTRYPOINT command param1 param2 shell内部命令

注:

  • ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT
  • 而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT
  • Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
  • 如果要覆盖的话,需要通过docker run --entrypoint 来指定
  • 当指定了 ENTRYPOINT 后, CMD 的内容作为参数传给 ENTRYPOINT 指令,实际执行时,将变为:
    <ENTRYPOINT> <CMD>
    例:
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]
    最后启动时执行指令为:top -b -c
    ENTRYPOINT ["node"]

15.CMD构建容器时调用,也就是在容器启动时才执行的命令

  • 但是一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD
  • CMD主要用于container时启动指定的服务,当docker run command的命令匹配到CMD command时,会替换CMD执行的命令
    格式:
CMD ["executable","param1","param2"] 执行可执行文件,优先
CMD ["param1","param2"] 设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数
CMD command param1 param2 执行shell内部命令

例:

CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]

注:
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令
CMD ["/node/app.js"]