关键在于用 ARG 控制构建阶段行为、ENV 决定运行时逻辑,通过同一 Dockerfile 构建多环境镜像,并由 entrypoint.sh 统一分发启动命令;构建时传参(如 --build-arg APP_ENV=dev),运行时可选覆盖,配合 Docker Compose 实现环境无缝切换。

用 Dockerfile 实现不同环境下的启动差异化,关键不是写多个 Dockerfile,而是通过构建参数(ARG)和运行时环境变量(ENV)协同控制镜像行为,让同一份 Dockerfile 构建出适配 dev / test / prod 的镜像,并在容器启动时执行对应逻辑。
用 ARG 控制构建阶段行为
构建时传入环境标识,决定编译、配置复制等操作:
-
ARG APP_ENV=production声明可传参的环境变量,默认值为production - 配合
COPY指令按需加载配置文件,例如:COPY config/${APP_ENV}.env ./env/.env - 可在构建阶段执行条件命令,比如开发环境安装调试工具:
RUN if [ "$APP_ENV" = "development" ]; then apt-get update && apt-get install -y curl vim; fi
用 ENV + CMD 实现运行时差异化启动
构建完成后,镜像内固定一个通用入口脚本,由 ENV 决定实际行为:
- 先设置运行时环境:
ENV NODE_ENV=${APP_ENV} \APP_ENV=${APP_ENV} - 把启动逻辑统一交给 shell 脚本(如
entrypoint.sh),再用CMD ["./entrypoint.sh"]调用 -
entrypoint.sh内容示例:#!/bin/shif [ "$APP_ENV" = "development" ]; thenexec npm run develif [ "$APP_ENV" = "production" ]; thenexec npm startelseexec "$@"fi
构建与运行分离:一次构建,多环境部署
避免为每个环境单独维护 Dockerfile,提升复用性和可信度:
- 构建时指定环境:
docker build --build-arg APP_ENV=development -t myapp:dev .docker build --build-arg APP_ENV=production -t myapp:prod . - 运行时仍可覆盖(但不推荐用于核心逻辑):
docker run -e APP_ENV=test myapp:prod—— 此时APP_ENV会覆盖构建时值,触发 entrypoint 中对应分支 - 真正解耦的关键:构建参数决定静态资源(配置、依赖、工具),环境变量决定运行时行为(启动命令、日志级别、连接地址)
配合 Docker Compose 实现无缝切换
在 compose 文件中注入构建参数和运行时变量,形成端到端环境链路:
-
docker-compose.yml中定义服务基础结构,不硬编码环境细节 -
docker-compose.dev.yml中添加:services:app:build:args:- APP_ENV=developmentenvironment:- APP_ENV=development - 启动即生效:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up


















