R / Richie全部文章 ↑

Linux · 2 分钟阅读

07. Dockerfile 指令详解

COPY

把上下文里的文件复制进镜像。

COPY package.json /usr/src/app/
COPY hom* /mydir/
COPY hom?.txt /mydir/
COPY --chown=55:mygroup files* /mydir/
  • 支持多源、通配符
  • 目标路径是绝对或相对 WORKDIR
  • 保留文件元数据(权限、时间戳)
  • --chown 指定属主

ADD

COPY 的超集:额外支持远端 URL 下载、自动解压 tar/gzip/bzip2/xz。

FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /

想要自动解压就用 ADD,否则都用 COPY——ADD 的 URL 下载会让缓存频繁失效。

CMD

容器启动的默认命令。一个 Dockerfile 只能有一条 CMD,多条以最后一条为准。

# exec 形式(推荐)
CMD ["nginx", "-g", "daemon off;"]

# shell 形式
CMD nginx -g "daemon off;"

容器里的应用必须前台运行(PID 1 不能 fork 完就退出)。

ENTRYPOINT

容器启动的固定入口点,参数 docker run image args 会追加到后面。

ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
docker run myimage -g "daemon off;"
# 实际执行:nginx -g "daemon off;"
# 覆盖 ENTRYPOINT
docker run --entrypoint=/bin/bash myimage

ENV

ENV VERSION=1.0 \
    DEBUG=on \
    NAME="Happy Feet"

构建期 + 运行期都可用:$VAR 或 ${VAR}。

支持 ENV 的指令:ADD COPY ENV EXPOSE LABEL USER WORKDIR VOLUME STOPSIGNAL ONBUILD。

VOLUME

声明匿名卷挂载点:

VOLUME /data
VOLUME ["/var/log/app", "/var/lib/app"]
# 运行时覆盖
docker run -v mydata:/data myimage

EXPOSE

EXPOSE 80 443

仅声明端口,不会自动映射。运行时还得 -p 80:80 或 -P 随机端口。

WORKDIR

WORKDIR /app

后续 RUN / CMD / ENTRYPOINT / COPY 都以这个目录为基准。别用 RUN cd——它只影响当条 RUN。

USER

RUN groupadd -r app && useradd -r -g app app
USER app

减少用 root 跑服务的攻击面。需要从 root 切到非 root 时用 gosu 而非 su -c:

COPY --from=gosu /gosu /usr/local/bin/
ENTRYPOINT ["gosu", "app", "node", "server.js"]

HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
    CMD curl -fs http://localhost/health || exit 1
退出码 含义
0 healthy
1 unhealthy
2 保留,不要用

查看状态:

docker inspect --format '{{json .State.Health}}' web | python -m json.tool

完整示例

FROM nginx:1.27

RUN apt-get update \
    && apt-get install -y --no-install-recommends curl \
    && rm -rf /var/lib/apt/lists/*

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
    CMD curl -fs http://localhost/ || exit 1

COPY ./html /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

参考