🐳 Docker Compose 高级指南:环境变量、Command、自定义配置与一键启动实践

260 阅读2分钟

目标:通过 .env、command、挂载卷,实现开发环境常用服务的集中配置、灵活自定义启动、一键部署与持久化。

目录

  1. 环境变量 .env 自定义启动
  2. command 命令自定义启动
  3. 挂载卷配合 command 实现自定义启动
  4. 整体实践:一键启动所有服务
  5. 总结

1. 环境变量 .env 自定义启动

Docker 官方镜像通常支持环境变量在容器初始化时自动配置服务。

示例:PostgreSQL

.env 文件内容:

POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydatabase
POSTGRES_PORT=5432

Docker Compose 配置:

postgres:
  image: postgres:16
  container_name: postgres
  restart: always
  env_file:
    - .env
  ports:
    - "${POSTGRES_PORT}:5432"
  volumes:
    - ./pgdata:/var/lib/postgresql/data
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
  • 特点

    • 自动创建用户、数据库

    • 适合简单初始化

    • 适合多人共享 .env 集中管理

⚠️ 环境变量仅在第一次启动容器时生效,已有数据卷不会重新初始化。


2. command 命令自定义启动

当服务需要自定义启动参数时,可使用 command 覆盖镜像默认启动逻辑。

示例:PostgreSQL 调整最大连接数

postgres:
  image: postgres:16
  container_name: postgres
  env_file:
    - .env
  command: ["postgres", "-c", "max_connections=200"]
  • command 覆盖默认 CMD

  • 可与环境变量结合,保持初始化逻辑

其他服务示例:Redis

redis:
  image: redis:7
  command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--maxmemory", "256mb"]

3. 挂载卷配合 command 实现自定义启动

可将本地配置文件挂载到容器内,然后在 command 中引用,实现动态更新配置:

Redis 使用本地配置文件

本地 redis.conf:

bind 0.0.0.0
requirepass redispass
maxmemory 256mb
maxmemory-policy allkeys-lru

Compose 配置:

redis:
  image: redis:7
  container_name: redis
  volumes:
    - ./redis-data:/data
    - ./redis.conf:/usr/local/etc/redis/redis.conf
  command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  ports:
    - "${REDIS_PORT}:6379"
  • 修改本地 redis.conf 后重启容器即可生效

PostgreSQL 使用自定义配置文件

本地 postgresql.conf:

max_connections = 200
shared_buffers = 512MB

Compose 配置:

postgres:
  image: postgres:16
  container_name: postgres
  env_file:
    - .env
  volumes:
    - ./pgdata:/var/lib/postgresql/data
    - ./postgresql.conf:/etc/postgresql/postgresql.conf
  command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]

4. 整体实践:一键启动所有服务

整合环境变量、command、自定义配置文件,示例包括 PostgreSQL、Redis、Kafka、Elasticsearch、Nginx。

.env 文件

# PostgreSQL
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
POSTGRES_DB=mydatabase
POSTGRES_PORT=5432

# Redis
REDIS_PORT=6379
REDIS_PASSWORD=redispass

# Kafka
KAFKA_BROKER_ID=1
KAFKA_PORT=9092
KAFKA_ADVERTISED_HOST_NAME=localhost
ZOOKEEPER_PORT=2181

# Elasticsearch
ELASTIC_VERSION=8.15.1
ELASTIC_PORT=9200
ELASTIC_PASSWORD=elasticpass

# Nginx
NGINX_PORT=8080

docker-compose.yml

version: "3.9"

services:
  # PostgreSQL
  postgres:
    image: postgres:16
    container_name: postgres
    restart: always
    env_file:
      - .env
    ports:
      - "${POSTGRES_PORT}:5432"
    volumes:
      - ./pgdata:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./postgresql.conf:/etc/postgresql/postgresql.conf
    command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]

  # Redis
  redis:
    image: redis:7
    container_name: redis
    restart: always
    volumes:
      - ./redis-data:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
    ports:
      - "${REDIS_PORT}:6379"

  # Kafka
  zookeeper:
    image: confluentinc/cp-zookeeper:7.6.1
    container_name: zookeeper
    environment:
      ZOOKEEPER_CLIENT_PORT: ${ZOOKEEPER_PORT}
    ports:
      - "${ZOOKEEPER_PORT}:2181"

  kafka:
    image: confluentinc/cp-kafka:7.6.1
    container_name: kafka
    depends_on:
      - zookeeper
    ports:
      - "${KAFKA_PORT}:9092"
    environment:
      KAFKA_BROKER_ID: ${KAFKA_BROKER_ID}
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:${ZOOKEEPER_PORT}
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://${KAFKA_ADVERTISED_HOST_NAME}:${KAFKA_PORT}
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    volumes:
      - ./kafka-data:/var/lib/kafka/data

  # Elasticsearch
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ELASTIC_VERSION}
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    ports:
      - "${ELASTIC_PORT}:9200"
    volumes:
      - ./es-data:/usr/share/elasticsearch/data
      - ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
    command: ["/usr/share/elasticsearch/bin/elasticsearch", "-Epath.conf=/usr/share/elasticsearch/config"]

  # Nginx
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "${NGINX_PORT}:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./html:/usr/share/nginx/html
    command: ["nginx", "-g", "daemon off;"]

启动命令

docker-compose up -d
  • PostgreSQL、Redis 使用 .env
  • Kafka、Elasticsearch 使用 command
  • Nginx 使用挂载配置文件 + command
  • 支持数据卷持久化
  • 修改本地配置文件后,重启容器即可生效

5. 总结

功能实现方式优点
简单初始化.env 环境变量快速,官方支持,初始化用户/数据库/密码
高级启动参数command自定义参数,覆盖默认启动
自定义配置文件挂载卷 + command可动态更新,保持灵活性
多服务一键启动docker-compose up -d集中管理,支持持久化,易迁移
可视化管理pgAdmin/RedisInsight/Kibana(可扩展)便于开发调试

最佳实践****

  1. .env 集中管理敏感信息
  2. 简单初始化用环境变量,复杂配置用 command 或挂载文件
  3. 所有服务挂载本地数据卷,防止丢失
  4. 修改本地配置文件后直接重启容器生效
  5. Docker Compose 便于团队协作与环境重建

这样就形成了 完整的开发环境指南,同时支持 .env、command、自定义配置文件和一键启动所有服务。