Compose 中的环境变量配置

Compose 中的环境变量配置

环境变量的重要性

在 Docker Compose 中,环境变量用于:

  • 配置数据库连接信息
  • 在不同环境(开发/测试/生产)间切换配置
  • 避免在 Compose 文件中写死敏感信息
  • 实现配置的复用和覆盖

五种设置环境变量的方式

方式一:直接在 service 中设置

services:
  app:
    image: myapp
    environment:
      - NODE_ENV=production
      - DEBUG=false
      - DB_HOST=db.example.com
      - DB_PORT=5432

或者使用数组格式(等效):

environment:
  NODE_ENV: production
  DEBUG: "false"
  DB_HOST: db.example.com
  DB_PORT: "5432"

方式二:使用 env_file

services:
  app:
    image: myapp
    env_file:
      - ./config/common.env
      - ./config/production.env

env_file 的格式(每行一个 KEY=VALUE):

# common.env
APP_NAME=myapp
APP_VERSION=1.0.0

# production.env
NODE_ENV=production
DB_HOST=prod-db.internal
DB_PORT=5432

方式三:使用 .env 文件(替换变量)

# docker-compose.yml
services:
  app:
    image: myapp:${TAG:-latest}
    ports:
      - "${HOST_PORT}:80"
    environment:
      - DB_URL=postgres://${DB_USER}:${DB_PASS}@db:5432/${DB_NAME}

对应的 .env 文件:

# .env(与 docker-compose.yml 同目录)
TAG=1.0.0
HOST_PORT=8080
DB_USER=postgres
DB_PASS=s3cret
DB_NAME=myapp

方式四:使用 shell 环境变量

# 在启动 Compose 前设置环境变量
export TAG=2.0.0
export HOST_PORT=3000

# Compose 文件中的 ${TAG} 会自动替换
docker compose up -d

方式五:命令行覆盖

# 在运行时指定环境变量
TAG=2.0.0 HOST_PORT=3000 docker compose up -d

# 使用 --env-file 参数
docker compose --env-file .env.production up -d

环境变量的优先级

当多种方式同时使用时,优先级如下(从高到低):

  1. Shell 环境变量export 设置的)
  2. Compose 文件中的 environment 字段
  3. env_file 指定的文件
  4. .env 文件
  5. Dockerfile 中的 ENV

.env 文件详解

.env 文件是 Compose 项目中最常用的变量注入方式。

文件位置

默认情况下,.env 文件必须放在 docker-compose.yml 同目录下。

project/
├── docker-compose.yml
├── .env              # 默认位置
└── .env.production   # 通过 --env-file 指定

使用不同的 .env 文件

# 指定不同的环境文件
docker compose --env-file .env.production up -d
docker compose --env-file .env.staging up -d

.env 文件示例

# .env
# 项目配置
COMPOSE_PROJECT_NAME=myapp

# 服务版本
NGINX_TAG=alpine
APP_TAG=1.2.0
DB_TAG=15-alpine

# 端口
HTTP_PORT=80
HTTPS_PORT=443
APP_PORT=3000

# 数据库
DB_NAME=myapp
DB_USER=appuser
DB_PASS=${DB_PASSWORD:-changeme}

# 日志
LOG_LEVEL=info
LOG_DIR=/var/log/app

在 Compose 文件中使用变量

变量引用语法

services:
  web:
    image: nginx:${NGINX_TAG:-latest}
    ports:
      - "${HTTP_PORT}:80"

  app:
    image: myapp:${APP_TAG}
    environment:
      - NODE_ENV=${NODE_ENV:-development}
      - DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@db:5432/${DB_NAME}

变量语法说明:

语法 说明 示例
${VAR} 替换变量值 ${TAG}
${VAR:-default} 变量未设置时使用默认值 ${PORT:-8080}
${VAR:?error} 变量未设置时报错 ${DB_PASS:? Database password required}

变量在 volumes 中的使用

services:
  app:
    volumes:
      - ${DATA_PATH:-./data}:/app/data
      - ./config/${ENV:-dev}/app.conf:/etc/app.conf:ro

生产环境的最佳实践

敏感信息处理

绝对不要把敏感信息写死在 docker-compose.yml 中!

# ❌ 错误:敏感信息硬编码
services:
  db:
    environment:
      POSTGRES_PASSWORD: my_super_secret_password

# ✅ 正确:通过变量注入
services:
  db:
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}

使用 Docker Secrets(Swarm 模式)

services:
  db:
    image: postgres:15
    secrets:
      - db_password
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

多环境配置

# base.yml
services:
  app:
    image: myapp
    env_file:
      - ./env/${ENV}.env

# .env.production
NODE_ENV=production
LOG_LEVEL=warn

# .env.development
NODE_ENV=development
LOG_LEVEL=debug

面试常考

Q:environment 和 env_file 有什么区别?

A:environment 直接在 Compose 文件中定义变量(可硬编码或引用变量)。env_file 从外部文件读取变量。推荐将变量定义从 Compose 文件中分离出来,使用 env_file 或 .env 文件。

Q:.env 文件中的变量能在 environment 字段中使用吗?

A:可以。.env 中的变量可以在 Compose 文件的任何位置使用(包括 environment、ports、volumes 等),语法为 ${VAR_NAME}

Q:如何根据环境加载不同的配置?

A:通过多个 .env 文件配合 --env-file 参数:docker compose --env-file .env.production up -d。或者使用多个 Compose 文件:docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容