核心思路是运行时注入环境差异而非修改镜像。通过.env文件管理环境变量、挂载外部配置文件、构建阶段用arg参数化、网络与存储动态适配,实现同一镜像在不同环境安全复用。

核心思路是把环境差异抽离出镜像,让同一镜像能通过外部配置适配不同环境。关键不在于改镜像,而在于“运行时注入”。
用 .env 文件统一管理环境变量
在项目根目录放一个 .env 文件,按环境区分(如 .env.dev、.env.test、.env.prod),内容示例:
NODE_ENV=developmentAPI_BASE_URL=http://localhost:3001DB_HOST=host.docker.internal
启动容器时用 env_file 加载:
docker run --env-file .env.test my-app
这样镜像本身不打包任何环境逻辑,只读取运行时传入的变量。
挂载外部配置文件替代硬编码
避免把 config.json 打进镜像。把配置文件放在宿主机或配置中心,启动时挂载进去:
- 开发环境挂载本地
./config/dev/app.json到容器内/app/config/app.json - 测试环境挂载
./config/test/app.json,路径一致,内容不同 - Docker Compose 中写法:
volumes: ["./config/test/:/app/config/"]
应用启动时直接读取挂载路径下的文件,无需重新构建镜像。
构建阶段用 ARG + 多阶段分离环境逻辑
如果某些配置必须在构建时决定(比如前端打包目标 API 地址),可用 ARG 传参,但不写死值:
ARG CONFIG_ENV=dev COPY config/$CONFIG_ENV.json /app/config/app.json
构建时指定:
docker build --build-arg CONFIG_ENV=test -t my-app:test .docker build --build-arg CONFIG_ENV=prod -t my-app:prod .
注意:这种做法仅用于构建期静态资源,运行时仍优先走挂载或环境变量。
网络与存储也按环境动态适配
不同环境的数据库地址、缓存服务、持久化路径往往不同,这些全靠外部控制:
- 用
docker run -e DB_HOST=redis-test替代写死在代码里 - 测试环境用
tmpfs卷模拟内存存储,生产环境挂载 NFS 或云盘 - 通过 compose 的
profiles或不同 yml 文件(docker-compose.test.yml)切换服务依赖
镜像只声明它需要什么服务名(如 redis),具体连哪个实例由运行时网络配置决定。











