多阶段构建是生产环境标配,核心是分离构建与运行阶段:构建阶段用完整镜像编译打包,运行阶段用极简镜像仅复制产物,剔除源码、开发依赖、构建工具和root权限,保留运行必需文件并启用非root用户与内建健康检查。

多阶段构建不是“高级技巧”,而是生产环境的标配做法。它解决的核心问题很实在:让最终上线的镜像只装运行必需的东西,不带编译器、源码、测试工具、开发配置——既小又干净,还安全。
明确拆分构建与运行两个阶段
一个 Dockerfile 里写两个 FROM,前面负责“造东西”,后面负责“跑东西”。构建阶段用功能完整的镜像(比如 node:18、maven:3.8-openjdk-17 或 python:3.11-slim),完成依赖安装、代码编译、打包;运行阶段换用极简镜像(比如 node:18-alpine、openjdk:17-jre-slim 或 python:3.11-slim-bookworm),只 COPY 上一阶段生成的产物。
- 构建阶段不做最终交付,只是“工厂”
- 运行阶段不装任何构建工具,连 gcc、make、npm 都不该存在
- 用 COPY --from=builder 精确复制需要的文件,比如 /app/dist、/install 或 /target/*.jar
只保留运行时真正需要的文件
最终镜像里不该出现这些:
- 源码目录(src/、test/、.ts 或 .py 文件)
- 开发依赖(devDependencies、eslint、jest、pytest)
- 构建缓存(node_modules/.cache、~/.m2、pip cache)
- 配置文件(tsconfig.json、webpack.config.js、pyproject.toml)
只留下:编译产物(dist/、target/、__pycache__ 以外的 .pyc)、生产依赖(node_modules 中非 dev 的包)、启动脚本和健康检查逻辑。
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
默认不用 root 用户运行
构建阶段可以用 root,但运行阶段必须切换成普通用户:
- 在运行阶段镜像中创建专用用户,比如 groupadd -g 1001 -r app && useradd -r -u 1001 -g app appuser
- 用 chown -R appuser:app /app 设置权限
- 最后加一行 USER appuser,强制进程以非 root 身份启动
这样即使应用被攻破,攻击者也无法直接提权或修改系统关键路径。
健康检查要轻量、无外部依赖
别在镜像里为了健康检查再装 curl 或 wget:
- Node.js 项目可用 node -e "require('http').get(...)"
- Python 项目用 python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
- Java Spring Boot 可用内置 Actuator 的 HTTP 端点,配合简单 shell 脚本调用
健康检查命令本身应内建在运行时语言能力中,不引入新二进制、不增加攻击面。










