什么是 Dockerfile?
Dockerfile 是一个构建指令文件,用于定义如何构建 Docker 镜像。它包含了一系列指令,告诉 Docker 如何:
- 选择基础镜像
- 安装依赖
- 复制文件
- 设置环境变量
- 运行命令
- 配置容器启动方式
多阶段构建(Multi-Stage Build)
为什么使用多阶段构建?
传统单阶段构建:
源代码 + 构建工具 + 依赖 + 构建产物 = 大镜像(~1GB+)
多阶段构建:
[阶段1] 源代码 + 构建工具 + 依赖 → 构建产物
[阶段2] 只复制构建产物 → 小镜像(~200MB)
优势:
✅ 减小镜像体积:最终镜像不包含构建工具和源代码
✅ 提高安全性:运行时不包含构建工具和源代码
✅ 优化构建缓存:依赖安装和代码构建分离,缓存更高效
两个阶段
| 阶段 | 作用 | 包含内容 | 最终产物 |
|---|---|---|---|
| 构建阶段 (builder) | 编译和打包应用 | Node.js、pnpm、源代码、依赖 | .next/standalone、 .next/static |
| 运行阶段 (runner) | 运行应用 | Node.js、构建产物 | 可运行的容器 |
构建阶段(Builder Stage)
基础镜像选择
FROM ${REGISTRY}/open-source/node:18-alpine as builder
作用:
- 选择 Node.js 18 作为基础镜像
- 使用 Alpine Linux(体积小,~5MB)
as builder给这个阶段命名,后续可以引用
构建时环境变量
ARG NEXT_PUBLIC_MAGIC_OFFICIAL_DEFAULT_LANG
ARG NEXT_PUBLIC_MAGIC_OFFICIAL_CDN_DOMAIN
ARG NEXT_PUBLIC_MAGIC_OFFICIAL_PUBLIC_CDN_DOMAIN
ARG NEXT_PUBLIC_MAGIC_OFFICIAL_ENV
ARG NEXT_PUBLIC_MAGIC_OFFICIAL_SERVICE_URL
ENV NEXT_PUBLIC_MAGIC_OFFICIAL_DEFAULT_LANG=${NEXT_PUBLIC_MAGIC_OFFICIAL_DEFAULT_LANG}
ENV NEXT_PUBLIC_MAGIC_OFFICIAL_CDN_DOMAIN=${NEXT_PUBLIC_MAGIC_OFFICIAL_CDN_DOMAIN}
ENV NEXT_PUBLIC_MAGIC_OFFICIAL_PUBLIC_CDN_DOMAIN=${NEXT_PUBLIC_MAGIC_OFFICIAL_PUBLIC_CDN_DOMAIN}
ENV NEXT_PUBLIC_MAGIC_OFFICIAL_ENV=${NEXT_PUBLIC_MAGIC_OFFICIAL_ENV}
ENV NEXT_PUBLIC_MAGIC_OFFICIAL_SERVICE_URL=${NEXT_PUBLIC_MAGIC_OFFICIAL_SERVICE_URL}
作用:
-
ARG(构建参数)作用域:仅在构建阶段(Builder Stage)有效
生命周期:构建完成后消失,不会保留在最终镜像中
用途:传递构建时的参数
-
ENV(环境变量)作用域:构建阶段和运行阶段都有效
生命周期:会保留在最终镜像中,容器运行时也可用
用途:设置应用运行时的环境变量
-
注意:这些值会被"烧录"到构建产物中,导致镜像与环境耦合
-
“烧录” = 构建时将值写入镜像,运行时无法更改
优点:客户端静态配置可以提前确定
缺点:环境相关配置不应烧录,否则会导致镜像与环境耦合
烧录的解决方案:运行容器时通过-e传入环境变量
-
运行容器时传入环境变量,覆盖镜像内的ENV
docker run -e NEXT_PUBLIC_CDN_DOMAIN=https://cdn.prod.example.com your-image:latest
//这种方式既保留了 ENV 的可用性,又避免了镜像与环境耦合,是生产环境的常用最佳实践。
运行阶段(Runner Stage):从 “构建产物” 到 “可运行容器”
仅保留应用运行必需的内容(Node.js 运行时 + 构建产物),剔除所有构建相关的依赖 / 源码,最终生成轻量、安全的可运行镜像。
常见模式 ARG:允许构建时传入不同的值 + ENV:确保值保留在镜像中,运行时可用
1. 定义 ARG(构建参数)
ARG NEXT_PUBLIC_CDN_DOMAIN
2. 将 ARG 转换为 ENV(保留在镜像中)
ENV NEXT_PUBLIC_CDN_DOMAIN=${NEXT_PUBLIC_CDN_DOMAIN}
构建时
docker build --build-arg NEXT_PUBLIC_CDN_DOMAIN=https://cdn.example.com .
结果:
- 构建时:ARG 的值传递给 ENV
- 构建后:ENV 的值保留在镜像中
- 运行时:容器可以访问 $NEXT_PUBLIC_CDN_DOMAIN