Dockerfile 常用命令及典型案例整理
Dockerfile 常用命令及典型案例整理
核心命令解析
1. FROM:指定基础镜像(必选指令)
- 语法:
FROM <镜像名>[:<标签>] [AS <构建阶段名>] - 主要功能:定义构建新镜像的基础,所有指令均基于基础镜像执行。
- 使用场景:必须作为Dockerfile的第一条非注释指令(ARG除外),用于选择官方、版本明确且轻量级的镜像作为基础。
- 示例:
FROM python:3.11-alpine AS builder
2. WORKDIR:设置工作目录
- 语法:
WORKDIR <路径> - 主要功能:为后续的RUN、CMD、ENTRYPOINT、COPY、ADD指令设置默认工作目录,类似Linux的cd命令。
- 使用场景:避免在RUN指令中使用
cd切换目录,提高Dockerfile的可读性和可维护性。 - 示例:
WORKDIR /app
3. COPY:本地文件复制到镜像
- 语法:
COPY <源路径> <目标路径> - 主要功能:将Dockerfile所在目录(或子目录)的文件/目录复制到镜像中,不支持自动解压。
- 使用场景:绝大多数文件复制场景,操作明确、可预测。
- 示例:
COPY ./app /app
4. ADD:增强版复制
- 语法:
ADD <源路径> <目标路径> - 主要功能:功能与COPY类似,但额外支持自动解压本地tar压缩文件和远程URL下载(不推荐用于URL下载,建议使用RUN + curl/wget)。
- 使用场景:需要自动解压本地tar压缩文件时使用。
- 示例:
ADD https://example.com/file.tar.gz /tmp
5. RUN:构建时执行命令
- 语法:
- Shell格式:
RUN <命令> - Exec格式:
RUN ["可执行文件", "参数1", "参数2"]
- Shell格式:
- 主要功能:在镜像构建过程中执行命令(如安装软件、配置环境),执行结果会被固化到镜像层中。
- 使用场景:安装系统依赖、配置环境变量等构建阶段操作。
- 最佳实践:合并多个RUN命令减少镜像层数,清理构建过程中的临时文件。
- 示例:
RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*
6. CMD:容器启动时执行命令
- 语法:
- Exec格式(推荐):
CMD ["可执行文件", "参数1", "参数2"] - Shell格式:
CMD command param1 param2
- Exec格式(推荐):
- 主要功能:定义容器启动后默认执行的命令,若
docker run后指定了命令,会覆盖CMD指令。 - 使用场景:定义容器的默认启动命令,允许用户在运行时灵活修改。
- 示例:
CMD ["python", "app.py"]
7. ENTRYPOINT:容器入口点
- 语法:
- Exec格式(推荐):
ENTRYPOINT ["可执行文件", "参数1", "参数2"] - Shell格式:
ENTRYPOINT command param1 param2
- Exec格式(推荐):
- 主要功能:与CMD类似,但
docker run后指定的参数会作为ENTRYPOINT的参数,而非覆盖它。 - 使用场景:适合固定启动流程的工具类镜像,如Nginx、MySQL等。
- 最佳实践:与CMD结合使用,ENTRYPOINT指定主程序,CMD传递默认参数。
- 示例:
ENTRYPOINT ["python", "app.py"]
8. ENV:设置环境变量
- 语法:
ENV <key> <value>ENV <key>=<value> ...
- 主要功能:定义环境变量,该变量在“构建阶段”和“容器运行阶段”均有效。
- 使用场景:配置应用运行时所需的环境变量,如数据库连接信息、端口号等。
- 示例:
ENV NODE_ENV=production
9. ARG:构建时参数
- 语法:
ARG <参数名>=<默认值> - 主要功能:定义构建过程中使用的临时参数,容器运行时不可见,可通过
docker build --build-arg动态传递。 - 使用场景:在构建过程中动态配置参数,如版本号、构建环境等。
- 示例:
ARG VERSION=1.0
10. EXPOSE:声明端口
- 语法:
EXPOSE <端口1> <端口2>... - 主要功能:声明容器运行时“打算监听”的端口,仅为文档说明,不实际映射到宿主机。
- 使用场景:告知使用者容器需要哪些端口,与
docker run -p配合使用。 - 示例:
EXPOSE 8080
11. VOLUME:定义匿名卷
- 语法:
VOLUME <路径>["路径2"] - 主要功能:在镜像中创建匿名数据卷,用于持久化容器内数据,避免容器删除后数据丢失。
- 使用场景:持久化数据库数据、日志文件等动态数据。
- 示例:
VOLUME /data
12. USER:指定运行用户
- 语法:
USER <用户名>["UID"] - 主要功能:指定后续RUN、CMD、ENTRYPOINT指令的执行用户,以及容器启动时的默认用户。
- 使用场景:提升安全性,避免以root用户运行容器。
- 示例:
USER appuser
13. LABEL:添加元数据
- 语法:
LABEL <key>=<value> <key>=<value> ... - 主要功能:为镜像添加描述性元数据(如作者、版本、描述),便于镜像管理与识别。
- 使用场景:标注镜像的基本信息,方便团队协作和镜像维护。
- 示例:
LABEL maintainer="your@email.com"
14. HEALTHCHECK:健康检查
- 语法:
HEALTHCHECK --interval=<时间> --timeout=<时间> --retries=<次数> CMD <健康检查命令>
- 主要功能:定期检查容器内应用的健康状态,若连续失败,Docker会将容器状态标记为unhealthy。
- 使用场景:确保容器内应用正常运行,及时发现并处理故障。
- 示例:
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/ || exit 1
15. ONBUILD:触发器
- 语法:
ONBUILD <指令> - 主要功能:定义镜像作为其他镜像基础时执行的指令,不会在当前构建中执行,而是在基于此镜像的子镜像构建中执行。
- 使用场景:构建将作为基础使用的镜像,如框架模板镜像。
- 示例:
ONBUILD COPY . /app/src
典型案例展示
案例1:基础Node.js应用部署
1 | # 使用官方Node.js镜像作为基础 |
关键步骤解释:
- 使用
node:18-alpine轻量级基础镜像,减小镜像体积。 - 先复制
package*.json文件并安装依赖,利用Docker缓存机制,仅在依赖变更时重新安装。 - 复制应用代码,暴露3000端口,定义容器启动命令。
案例2:Go应用多阶段构建
1 | # 阶段1:构建阶段 |
关键步骤解释:
- 第一阶段使用Go官方镜像进行编译,生成二进制文件。
- 第二阶段使用轻量级的Alpine镜像,仅复制编译好的二进制文件,大幅减小最终镜像体积。
- 暴露8080端口,定义容器启动命令。
案例3:前端项目部署(Vue/React)
1 | # 基础镜像(轻量,约20MB) |
关键步骤解释:
- 使用
nginx:alpine轻量级基础镜像,减少镜像体积和攻击面。 - 删除默认Nginx配置,复制自定义配置文件,解决前端路由刷新404问题。
- 复制前端打包后的静态文件到Nginx默认目录,暴露80端口,启动Nginx服务。
案例4:Spring Boot应用镜像
1 | # 第一阶段:编译(用带Maven的JDK镜像,仅用于打包) |
关键步骤解释:
- 第一阶段使用Maven镜像编译Spring Boot项目,生成jar包。
- 第二阶段使用仅含JRE的轻量镜像,复制jar包并启动应用。
- 指定JVM参数优化性能,暴露8080端口。
最佳实践总结
一、镜像体积优化
使用轻量级基础镜像:优先选择Alpine、distroless、scratch等轻量级基础镜像,替代Ubuntu/CentOS全量系统镜像。
多阶段构建分离环境:构建阶段使用完整工具链(如含编译器的镜像),运行阶段仅保留运行必需组件(如二进制文件、精简运行时)。
清理构建缓存:安装系统依赖后立即清理缓存,避免冗余文件。
1
2RUN apt-get update && apt-get install -y gcc \
&& apt-get clean && rm -rf /var/lib/apt/lists/*语言专属精简:
- Java:使用分层JAR,仅复制运行必需层。
- Python:安装依赖时加
--no-cache-dir,避免缓存。 - Node.js:分离生产依赖(
npm ci --only=production),清理npm缓存。
二、分层与缓存优化
- 按“变更频率”分层:高频变更文件(如应用代码)放顶层,低频变更文件(如依赖、系统配置)放底层,利用Docker分层缓存减少重建耗时。
- 精准控制文件复制:使用
.dockerignore排除无关文件(如.git、tests/、node_modules),按需复制文件而非全量复制。 - 启用BuildKit:支持并行构建、远程缓存,加速多环境/团队构建。
三、安全加固
固定基础镜像版本:使用明确的版本号而非
latest标签,确保构建可复现、漏洞可追溯。非root用户运行:创建低权限用户,禁止容器以root启动。
1
2RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser移除无用工具:删除sh/bash/curl/wget等非必需二进制,缩小攻击面。
扫描镜像漏洞:使用Trivy、Clair等工具扫描镜像中的已知漏洞。
四、其他最佳实践
- 优先使用COPY:除非需要自动解压本地tar压缩文件,否则一律使用COPY替代ADD。
- 合并RUN指令:减少镜像层数,在最后清理包管理器缓存。
- 设置健康检查:定期检查容器内应用的健康状态,确保服务可用性。
- 添加元数据:使用LABEL添加镜像元数据(如维护者、版本、描述信息),便于镜像管理与识别。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Nosaw博客!
评论







