通过本课件,你将掌握:
Dockerfile 的本质与作用:理解其作为“镜像构建脚本”的核心价值;
关键指令详解:FROM、COPY、RUN、CMD、ENTRYPOINT 等的正确用法与区别;
最佳实践原则:如何编写高效、安全、可维护的 Dockerfile;
完整实战案例:从零构建 Jenkins 镜像并运行容器;
常见问题排查:识别构建失败原因并优化构建性能;
Dockerfile vs Docker Compose:明确两者定位差异,避免混淆。
Dockerfile 是一个纯文本文件,包含一系列指令(instructions),用于自动化构建 Docker 镜像。
你可以把它想象成一份烹饪食谱:
食材 = 基础操作系统、代码、依赖库;
步骤 = 安装软件、复制文件、设置环境;
成品 = 可在任何支持 Docker 的环境中运行的标准化镜像。
✅ 关键价值:“一次构建,处处运行” —— 开发、测试、生产环境行为完全一致。
每条指令都会创建一个新的镜像层(Layer),Docker 利用层缓存机制加速后续构建。
FROM 设定基础镜像(必须是第一条)FROM ubuntu:22.04
FROM openjdk:11-jdk # 推荐使用官方语言镜像🔍 建议:优先选择官方镜像(如
python:3.11-slim、node:18-alpine),体积小、安全性高。
COPY 复制本地文件到镜像中(推荐使用)COPY app.py /app/
COPY . /app/ # 复制当前目录所有内容✅ 优点:语义清晰、仅支持本地路径,安全且可预测。
ADD 功能更强但慎用ADD https://example.com/app.tar.gz /app/ # 支持远程 URL
ADD archive.tar.gz /app/ # 自动解压 .tar.gz⚠️ 最佳实践:除非需要自动解压或下载远程文件,否则一律用
COPY。ADD行为隐式,易引发意外。
RUN 执行构建时命令(安装依赖等)RUN apt-get update && apt-get install -y curl
RUN pip install -r requirements.txt💡 技巧:将多个命令合并为一行(用
&&连接),减少镜像层数,减小体积。
CMD 容器启动时默认执行的命令(可被覆盖)CMD ["python", "app.py"]
CMD ["nginx", "-g", "daemon off;"]🔄 特点:可在
docker run时被替换:docker run my-app echo "Hello" # 覆盖 CMD
ENTRYPOINT 容器主进程入口(不可被覆盖)ENTRYPOINT ["java", "-jar", "app.jar"]🔒 特点:
docker run后的参数会追加到 ENTRYPOINT 后:docker run my-java-app --debug # 实际执行: java -jar app.jar --debug
CMD vs ENTRYPOINT 对比📌 推荐模式:
ENTRYPOINT ["python", "app.py"] CMD ["--port", "8080"] # 默认参数,可被覆盖
🚫 注意:
MAINTAINER已废弃,请改用LABEL maintainer=...。
Dockerfile# 使用官方 OpenJDK 11 作为基础镜像
FROM openjdk:11-jdk
# 添加元数据(替代 MAINTAINER)
LABEL maintainer="Lusifer" \
env="production"
# 设置环境变量
ENV APP_HOME=/data/app
# 创建应用目录
RUN mkdir -p $APP_HOME
# 下载 Jenkins WAR 文件(仅在此演示,生产建议 COPY 本地文件)
ADD https://ftp.yz.yamagata-u.ac.jp/pub/misc/jenkins/war/2.397/jenkins.war $APP_HOME/
# 设置工作目录
WORKDIR $APP_HOME
# 声明容器暴露端口
EXPOSE 8080
# 启动 Jenkins
CMD ["java", "-jar", "jenkins.war"]# 在 Dockerfile 所在目录执行
docker build -t jenkins-custom:2.397 .🔍
.表示构建上下文为当前目录。
docker run -d -p 8080:8080 --name jenkins jenkins-custom:2.397浏览器打开:http://localhost:8080 → 进入 Jenkins 初始化页面。
利用层缓存:将不常变的指令(如 apt-get install)放在前面;
合并 RUN 指令:减少层数;
使用 .dockerignore:排除无关文件(如 node_modules/, .git/);
选择小体积基础镜像:如 alpine、-slim 版本。
协作关系:
先用 Dockerfile 构建
web-app和db镜像,再用 Docker Compose 定义它们如何互联、暴露端口、挂载卷。
Dockerfile 是声明式脚本,用于自动化构建可移植镜像;
指令顺序影响缓存效率,合理排序可加速 CI/CD;
优先使用 COPY 而非 ADD,ENTRYPOINT + CMD 组合更灵活;
避免在 Dockerfile 中硬编码敏感信息(密码、密钥);
Dockerfile 负责“造车”,Docker Compose 负责“开车上路”。
为什么在 Dockerfile 中不建议使用 latest 标签作为基础镜像?
如何让容器以非 root 用户身份运行,提升安全性?
如果 COPY . /app 复制了大量无关文件,会导致什么问题?如何解决?
📘 延伸阅读: