在 Docker 中,如何配置和管理环境变量? 在 Docker 中环境变量是配置容器行为、传递敏感信息如数据库密码、API 密钥以及实现“一次构建到处运行”12-Factor App 原则的关键机制。配置和管理环境变量主要有以下几种方式按推荐程度和使用场景分类一、在镜像构建时定义 (Dockerfile)这是设置默认值或非敏感配置的最佳方式。1. 使用ENV指令在Dockerfile中定义环境变量该变量会永久保存在镜像层中容器启动时自动加载。FROM node:18-alpine # 设置默认环境变量 ENV NODE_ENVproduction ENV APP_PORT3000 ENV LOG_LEVELinfo WORKDIR /app COPY . . CMD [node, server.js]特点值被硬编码在镜像中。容器启动时如果外部没有覆盖则使用此值。注意不要在此处存储敏感信息如密码因为任何人都可以通过docker history或docker inspect查看到。2. 使用ARG指令 (构建时变量)ARG仅在构建镜像时有效构建完成后变量消失不会进入最终镜像除非用ENV复制。ARG VERSION1.0.0 FROM node:18-alpine # 将构建参数转换为环境变量可选 ENV APP_VERSION${VERSION}用法docker build --build-arg VERSION2.0.0 -t my-app .用途用于在构建时动态注入版本号、Git Commit Hash 等不用于运行时配置。二、在容器运行时指定 (docker run)这是最灵活的方式允许在不重新构建镜像的情况下修改配置。1. 使用-e或--env标志直接在命令行覆盖或添加环境变量。# 覆盖镜像中的默认值dockerrun-d-eNODE_ENVdevelopment-eDB_HOSTlocalhost my-app# 添加新变量dockerrun-d-eAPI_KEYsecret123 my-app2. 使用--env-file标志 (推荐)将环境变量存储在本地文件中避免命令行过长或泄露敏感信息。步骤创建.env文件不要提交到 Git# .env 文件内容NODE_ENVproductionDB_HOSTdb.example.comDB_PASSWORDsuper_secret_passwordAPI_KEYabc-123-xyz启动容器dockerrun-d--env-file .env my-app优点便于管理大量变量。可以将.env文件加入.gitignore防止敏感信息泄露。不同环境开发、测试、生产只需切换不同的.env文件。三、使用 Docker Compose 管理 (多容器场景)在微服务或多容器应用中docker-compose.yml是管理环境变量的标准方式。1. 直接在environment中定义version:3.8services:web:image:my-appenvironment:-NODE_ENVproduction-DB_HOSTdb-DB_PORT54322. 使用env_file引入外部文件version:3.8services:web:image:my-appenv_file:-.env.productiondb:image:postgresenv_file:-.env.db3. 变量替换 (Interpolation)Docker Compose 支持从宿主机的环境变量或.env文件中读取值并替换到 YAML 中。宿主机变量${DB_PASSWORD}默认值${DB_PASSWORD:-default_pass}services:web:image:my-appenvironment:-DB_PASSWORD${DB_PASSWORD}# 读取宿主机的 DB_PASSWORD-LOG_LEVEL${LOG_LEVEL:-info}# 如果宿主机没设默认为 info四、敏感信息管理 (Docker Secrets)重要对于生产环境中的密码、密钥等敏感数据严禁使用ENV或--env明文传递因为它们会出现在进程列表ps aux、镜像层和日志中。解决方案使用Docker Secrets(仅限 Swarm 模式) 或挂载文件。1. Docker Swarm Secrets# 1. 创建 Secretechosuper_secret_password|dockersecret create db_password -# 2. 部署服务时挂载dockerservicecreate--namedb--secretdb_password postgres容器内访问Secret 会被挂载到/run/secrets/db_password文件中容器读取该文件内容即可。2. 普通 Docker 的替代方案 (挂载文件)如果不在 Swarm 模式下可以手动将敏感文件挂载到容器内# 本地创建 secret 文件echosecret.db_pass# 启动容器挂载dockerrun-d-v$(pwd)/.db_pass:/run/secrets/db_pass:ro my-app应用代码需修改为读取/run/secrets/db_pass文件而不是读取环境变量。五、在容器内查看和验证1. 查看容器环境变量# 查看指定容器的所有环境变量dockerexeccontainer_idenv# 或者dockerinspectcontainer_id--format{{range .Config.Env}}{{println .}}{{end}}2. 调试技巧如果变量未生效检查顺序DockerfileENV是默认值。docker run -e或--env-file会覆盖ENV。Docker Compose中的environment会覆盖镜像默认值。优先级运行时指定 构建时默认。六、最佳实践总结场景推荐方式原因非敏感默认配置Dockerfile(ENV)提供合理的默认值减少启动参数。敏感信息 (密码/Key)--env-file(开发) /Docker Secrets(生产)避免硬编码防止泄露。多环境配置docker-composeenv_file轻松切换开发/测试/生产配置。构建时参数ARG仅在构建阶段有效不污染镜像。动态配置运行时-e或 ConfigMap (K8s)无需重新构建镜像即可调整行为。安全警告永远不要将包含密码的.env文件提交到 Git 仓库。务必在.gitignore中添加.env .env.* *.secret