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;"]