[一、Dockerfile 是什么](#一、Dockerfile 是什么)
[二、Dockerfile 文件结构](#二、Dockerfile 文件结构)
[三、常用 Dockerfile 指令详解](#三、常用 Dockerfile 指令详解)
[四、Dockerfile 构建流程](#四、Dockerfile 构建流程)
[1️⃣ 编写 Dockerfile](#1️⃣ 编写 Dockerfile)
[2️⃣ 构建镜像](#2️⃣ 构建镜像)
[3️⃣ 验证构建结果](#3️⃣ 验证构建结果)
[五、Dockerfile 实战一:自定义 Nginx 镜像](#五、Dockerfile 实战一:自定义 Nginx 镜像)
[六、Dockerfile 实战二:Spring Boot 应用镜像](#六、Dockerfile 实战二:Spring Boot 应用镜像)
[七、Dockerfile 实战三:多阶段构建(优化镜像体积)](#七、Dockerfile 实战三:多阶段构建(优化镜像体积))
[八、Dockerfile 优化技巧](#八、Dockerfile 优化技巧)
[九、Dockerfile 调试与验证](#九、Dockerfile 调试与验证)
[十、示例:自定义 LNMP 环境](#十、示例:自定义 LNMP 环境)
[十一、.dockerignore 文件](#十一、.dockerignore 文件)
前言
在前面几章中,我们通过 docker run
拉取官方镜像来运行容器。 但在实际企业环境中,我们往往需要 自定义镜像 ------ 例如将自己的应用、配置文件、环境变量、依赖包都打包成一个镜像,方便快速部署。
Docker 官方为此提供了标准化的构建文件: 👉 Dockerfile
一、Dockerfile 是什么
Dockerfile 是一个包含 镜像构建指令 的文本文件, 每一条指令都代表构建镜像的一层(Layer)。
💡 一句话理解: Dockerfile = 自动化的镜像配方。
二、Dockerfile 文件结构
基本语法格式:
# 注释行
INSTRUCTION argument
指令区分大小写,通常写为大写。
三、常用 Dockerfile 指令详解
指令 | 作用 | 示例 |
---|---|---|
FROM | 指定基础镜像 | FROM centos:7 |
MAINTAINER | 镜像维护者信息(已过时,用 LABEL 替代) | LABEL maintainer="uuz" |
LABEL | 添加元数据标签 | LABEL version="1.0" |
RUN | 执行命令 | RUN yum -y install nginx |
WORKDIR | 设置工作目录 | WORKDIR /usr/local/app |
COPY | 从宿主机复制文件到镜像 | COPY app.jar /app/app.jar |
ADD | 类似 COPY,但支持解压和 URL | ADD nginx.tar.gz /usr/local/ |
EXPOSE | 声明容器暴露端口 | EXPOSE 8080 |
ENV | 设置环境变量 | ENV JAVA_HOME=/usr/local/java |
ENTRYPOINT | 容器启动时执行命令(固定入口) | ENTRYPOINT ["java", "-jar", "app.jar"] |
CMD | 提供默认参数(可被覆盖) | CMD ["--server.port=8080"] |
USER | 指定运行用户 | USER nginx |
VOLUME | 定义挂载点 | VOLUME ["/data"] |
四、Dockerfile 构建流程
1️⃣ 编写 Dockerfile
创建一个新目录并进入:
mkdir /opt/dockerfile-demo && cd /opt/dockerfile-demo
创建文件:
vim Dockerfile
2️⃣ 构建镜像
docker build -t mynginx:1.0 .
说明:
-t
指定镜像名和标签
.
表示当前目录(包含 Dockerfile)
3️⃣ 验证构建结果
docker images
运行容器:
docker run -d -p 8080:80 mynginx:1.0
五、Dockerfile 实战一:自定义 Nginx 镜像
# 使用基础镜像
FROM nginx:latest
# 维护者信息
LABEL maintainer="docker-study"
# 复制网页文件到镜像中
COPY index.html /usr/share/nginx/html/index.html
# 暴露端口
EXPOSE 80
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
构建镜像:
docker build -t mynginx:v1 .
启动容器:
docker run -d -p 8080:80 mynginx:v1
访问测试:
http://localhost:8080
六、Dockerfile 实战二:Spring Boot 应用镜像
项目结构示例:
springboot-app/
├── Dockerfile
├── app.jar
Dockerfile 内容:
FROM openjdk:8-jdk-alpine
LABEL maintainer="docker-study"
WORKDIR /app
COPY app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
构建镜像:
docker build -t springboot-app:v1 .
运行容器:
docker run -d -p 8080:8080 springboot-app:v1
✅ 一条命令打包并运行 Spring Boot 应用。
七、Dockerfile 实战三:多阶段构建(优化镜像体积)
场景: 构建 Go / Node / Java 应用时,编译环境庞大,不适合直接放入生产镜像。
解决方法:多阶段构建
# 第一阶段:编译阶段
FROM golang:1.19 AS builder
WORKDIR /build
COPY . .
RUN go build -o app .
# 第二阶段:运行阶段
FROM alpine:3.19
WORKDIR /app
COPY --from=builder /build/app .
EXPOSE 8080
ENTRYPOINT ["./app"]
✅ 优点:最终镜像只有运行程序,无需编译依赖。 典型用于 Java、Go、前端项目。
八、Dockerfile 优化技巧
优化点 | 方法 | 示例 |
---|---|---|
减少层数 | 合并多条 RUN 指令 | RUN apt-get update && apt-get install -y vim |
清理缓存 | 构建后删除临时文件 | RUN rm -rf /var/lib/apt/lists/* |
合理使用 .dockerignore | 排除无关文件 | node_modules/ , .git/ |
选择轻量镜像 | 使用 alpine 系列 | FROM nginx:alpine |
多阶段构建 | 编译与运行分离 | COPY --from=builder ... |
九、Dockerfile 调试与验证
查看构建历史
docker history mynginx:1.0
模拟逐层构建
docker run -it --rm <image_id> /bin/sh
进入容器调试
docker exec -it <container_id> /bin/bash
十、示例:自定义 LNMP 环境
FROM centos:7
RUN yum -y install epel-release && \
yum -y install nginx mysql php php-fpm && \
mkdir -p /usr/share/nginx/html
COPY index.php /usr/share/nginx/html/index.php
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建并运行:
docker build -t lnmp:v1 .
docker run -d -p 80:80 lnmp:v1
十一、.dockerignore 文件
防止无关文件进入镜像,提高构建效率。
示例:
.git
node_modules
*.log
tmp/
⚙️ 与
.gitignore
类似,用于排除不需要打包的文件。
十二、总结
通过本篇学习,你应掌握:
✅ Dockerfile 的语法与构建原理
✅ 常用指令与组合使用方式
✅ 构建自定义镜像的实战命令
✅ 镜像优化技巧与多阶段构建
✅ 实战案例:Nginx 与 Spring Boot 构建