Docker Compose 模块化多环境配置规范指南

服务的版本、端口、密码,以及项目的环境,网络这些要怎么放置?

标准的规范做法是双层配置隔离

  • 根目录公共 .env:仅保留全局通用变量(ENVCOMPOSE_PROJECT_NAMENETWORK_NAME 等)。

  • 服务私有 .env:与服务的 docker-compose.yml 同级放置,仅维护该服务独有的参数(如版本、密码、端口、JVM 配置等)。


示例:elasticsearch_V9.4.2


目录结构规范

以下为标准的工程目录结构。不同环境(如 dev / test / prod)通过顶层文件夹进行物理隔离,.env 按照双层变量隔离的方式:

dev/
├── .env                               # 全局公共环境配置文件(仅定义共享基础设施变量)
└── elasticsearch_V9.4.2/              # 独立服务单元
    ├── .env                           # 服务私有环境配置文件(仅定义服务专属变量)
    ├── docker-compose.yml             # Docker Compose 编排文件
    └── volumes/                       # 持久化数据与日志挂载目录

配置文件详解与完整注释


1. 全局公共环境配置:dev/.env

位于环境根目录下,仅保留跨服务共享的基础网络项目标识参数。

# =========================================================
# Docker Compose 全局公共环境配置文件
# 作用:管理跨服务的全局基础设施配置(如网络、环境标识等)
# =========================================================

############################################################
# 环境基础配置
############################################################

# 当前运行环境标识
# 可选值:dev(开发)、test(测试)、prod(生产)
ENV=dev

# Docker Compose 全局项目名称(影响容器默认命名前缀)
COMPOSE_PROJECT_NAME=dev

############################################################
# Docker 公共网络配置
############################################################

# 跨服务通信的 Docker 共享网络名称
NETWORK_NAME=network-${ENV}

# 自定义 Docker bridge 网络子网掩码(确保网段不与宿主机冲突)
NETWORK_SUBNET=10.10.0.0/24

2. 服务私有环境配置:dev/elasticsearch_V9.4.2/.env

位于服务目录下,包含与 Elasticsearch 强绑定的个性化参数。

# =========================================================
# Elasticsearch 服务专属环境配置文件
# 作用:管理 Elasticsearch 独享的版本、账号密码、端口及性能参数
# 位置:与服务自身的 docker-compose.yml 同级
# =========================================================

############################################################
# Elasticsearch 配置
############################################################

# 镜像版本(例如:9.4.2 / 8.17.0)
ES_VERSION=9.4.2

# 内置 elastic 用户密码
ES_PASSWORD=Pass@8520

# 暴露端口配置
ES_PORT_HTTP=9200
ES_PORT_TRANSPORT=9300

# JVM 堆内存设置(根据宿主机资源弹性调整)
ES_JAVA_OPTS=-Xms2g -Xmx2g

3. 服务编排配置:dev/elasticsearch_V9.4.2/docker-compose.yml
# =========================================================
# Elasticsearch Docker Compose 配置
#
# 目录结构:
#   dev/
#   ├── .env
#   └── elasticsearch_V${ES_VERSION}(例如:elasticsearch_V9.4.2)/
#       ├── .env
#       ├── docker-compose.yml
#       └── volumes/
#           ├── data/        # Elasticsearch 持久化数据
#           ├── logs/        # Elasticsearch 运行日志
#           └── plugins/     # Elasticsearch 第三方插件
#
# 说明:
#
#   1. 环境配置
#      全局基础参数(ENV、NETWORK等)由根目录公共 .env 管理;
#      Elasticsearch 专属参数(版本、密码、端口等)由服务同级 .env 管理。
#
#   2. 持久化目录
#      Elasticsearch 的数据、日志和第三方插件统一存放于
#      elasticsearch_V${ES_VERSION}/volumes/ 目录下。
#
#   3. 路径规则
#      所有宿主机挂载目录均采用相对路径,
#      相对路径以当前 docker-compose.yml 所在目录为基准。
#      例如 ./volumes/data 对应:
#      <当前环境>/elasticsearch_V${ES_VERSION}/volumes/data。
#
#   4. 环境隔离
#      挂载路径不使用 ${ENV} 拼接。
#      不同环境通过上层目录进行隔离,例如:
#      dev/elasticsearch_V${ES_VERSION}、test/elasticsearch_V${ES_VERSION}。
#
#   5. 数据迁移
#      elasticsearch_V${ES_VERSION}/ 目录包含 Compose 配置及 Elasticsearch
#      持久化数据,可作为当前环境的整体备份和迁移单元。
#
#   6. 镜像配置
#      Elasticsearch 的默认配置文件由 Docker 镜像提供,
#      不直接挂载整个 /usr/share/elasticsearch/config 目录,
#      避免覆盖镜像内部的默认配置文件。
#
# =========================================================


############################################################
# 网络配置
############################################################

networks:

  # Compose 内部网络名称。
  env_network:

    # 使用 Docker Bridge 网络。
    driver: bridge

    # Docker 实际网络名称,由上层公共 .env 管理。
    name: ${NETWORK_NAME}

    # 自定义网络地址范围。
    ipam:
      config:
        - subnet: ${NETWORK_SUBNET}


############################################################
# 服务配置
############################################################

services:

  ##########################################################
  # Elasticsearch
  ##########################################################

  elasticsearch:

    # Elasticsearch 镜像及版本。
    # 版本由私有 .env 中的 ES_VERSION 管理。
    image: elasticsearch:${ES_VERSION}

    # 容器名称(自动拼接版本与环境)。
    # 例如:elasticsearch_dev_V9.4.2
    container_name: elasticsearch_${ENV}_V${ES_VERSION}

    # 加入当前环境的 Docker 网络。
    networks:
      - env_network

    # 端口映射。
    #
    # HTTP:
    #   宿主机 ${ES_PORT_HTTP} -> 容器 9200
    #
    # Transport:
    #   宿主机 ${ES_PORT_TRANSPORT} -> 容器 9300
    ports:
      - "${ES_PORT_HTTP}:9200"
      - "${ES_PORT_TRANSPORT}:9300"

    # Elasticsearch 运行参数。
    environment:

      # 单节点模式。
      discovery.type: single-node

      # elastic 内置用户密码。
      ELASTIC_PASSWORD: ${ES_PASSWORD}

      # 开启 Elasticsearch 安全认证。
      xpack.security.enabled: "true"

      # JVM 堆内存参数。
      ES_JAVA_OPTS: ${ES_JAVA_OPTS}

      # 磁盘水位配置。
      # 避免磁盘空间不足时过早触发数据分配保护。
      cluster.routing.allocation.disk.watermark.low: "90%"
      cluster.routing.allocation.disk.watermark.high: "95%"
      cluster.routing.allocation.disk.watermark.flood_stage: "97%"


    ########################################################
    # 持久化目录
    ########################################################
    #
    # 所有宿主机挂载目录均采用相对路径。
    #
    # 相对路径以当前 docker-compose.yml 所在目录为基准。
    #
    # 当前 Compose 文件路径示例:
    #
    #   <当前环境>/elasticsearch_V${ES_VERSION}/docker-compose.yml
    #
    # 因此:
    #
    #   ./volumes/data
    #   ./volumes/logs
    #   ./volumes/plugins
    #
    # 分别对应:
    #
    #   <当前环境>/elasticsearch_V${ES_VERSION}/volumes/data
    #   <当前环境>/elasticsearch_V${ES_VERSION}/volumes/logs
    #   <当前环境>/elasticsearch_V${ES_VERSION}/volumes/plugins
    #
    # 不使用 ${ENV} 拼接挂载路径,
    # 环境隔离由上层目录完成。
    #
    ########################################################

    volumes:

      # Elasticsearch 核心持久化数据。
      #
      # 宿主机:
      #   ./volumes/data
      #
      # 容器:
      #   /usr/share/elasticsearch/data
      #
      # 保存索引、Shard、Lucene 数据及集群持久化状态。
      - ./volumes/data:/usr/share/elasticsearch/data

      # Elasticsearch 运行日志。
      #
      # 宿主机:
      #   ./volumes/logs
      #
      # 容器:
      #   /usr/share/elasticsearch/logs
      - ./volumes/logs:/usr/share/elasticsearch/logs

      # Elasticsearch 第三方插件。
      #
      # 宿主机:
      #   ./volumes/plugins
      #
      # 容器:
      #   /usr/share/elasticsearch/plugins
      #
      # 插件必须与 ES_VERSION 保持兼容。
      - ./volumes/plugins:/usr/share/elasticsearch/plugins


    ########################################################
    # 健康检查
    ########################################################

    healthcheck:

      # 使用 elastic 用户访问 Elasticsearch HTTP API。
      test:
        [
          "CMD-SHELL",
          "curl -sf -u elastic:${ES_PASSWORD} http://localhost:9200 >/dev/null || exit 1"
        ]

      # 每 10 秒检查一次。
      interval: 10s

      # 单次健康检查最大执行时间。
      timeout: 5s

      # 连续失败 30 次后标记为 unhealthy。
      retries: 30

      # 启动阶段给予 300 秒宽限时间。
      start_period: 300s


    # 容器异常退出后自动重启。
    restart: unless-stopped


    ########################################################
    # 容器标签
    ########################################################

    labels:

      # 当前环境。
      env: ${ENV}

      # Elasticsearch 版本。
      version: ${ES_VERSION}

      # 服务名称(自动拼接环境与版本号)。
      service: elasticsearch_${ENV:-dev}_V${ES_VERSION}

4. 服务启动

elasticsearch_V9.4.2/ 目录下执行命令时,显式同时加载父级和当前目录的 .env 文件

docker compose --env-file ../.env --env-file .env up -d

注意:必须同时写上 --env-file ../.env--env-file .env,这样 Compose 才能在语法解析阶段同时获取到父级的 ENVNETWORK_NAME 以及子级的 ES_VERSION
在这里插入图片描述


5. 浏览器访问
http://localhost:9200/

在这里插入图片描述


6. IK 分词器安装

GitHub 官网https://release.infinilabs.com/analysis-ik/stable/

下载对应 Elasticsearch 版本的分词器

在这里插入图片描述


6.1 解压到宿主机挂载目录安装(最优雅,推荐)

不挂载 config,直接把 IK 插件解压在宿主机的 volumes/plugins/analysis-ik 目录下。

在这里插入图片描述
IK 分词器在手动解压安装时,自带一个 config/ 文件夹(包含 IKAnalyzer.cfg.xml.dic 词典文件)。只要放在 plugins/analysis-ik/config/ 下,ES 会自动识别,既保留了配置文件,又不需要改动 Compose 的挂载项

宿主机结构:

volumes/plugins/analysis-ik/
├── config/               <-- IK 自带的配置文件及词典
│   ├── IKAnalyzer.cfg.xml
│   └── main.dic
├── elasticsearch-analysis-ik-9.4.2.jar
└── plugin-descriptor.properties

6.2 elasticsearch-plugin 工具 执行安装(不建议)

不建议使用 elasticsearch-plugin 工具 执行安装 IK分词器,运行 elasticsearch-plugin install 时,ES 会将压缩包中的配置文件自动抽取并强制移动到全局配置目录 /usr/share/elasticsearch/config/analysis-ik/ 下,而插件主目录 /usr/share/elasticsearch/plugins/analysis-ik/ 仅保留 .jar 包与 plugin-descriptor.properties。不建议挂载整个 config 目录,必须使用具体文件或具体子文件夹的挂载,这样每增加一个插件就要多加一个挂载配置,太傻了。

elasticsearch-plugin install --batch https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-9.4.2.zip

在这里插入图片描述
查看挂载目录
在这里插入图片描述
绝对不建议挂载整个 config 目录(即 - ./volumes/config:/usr/share/elasticsearch/config),这会导致 Elasticsearch 无法启动

为什么不能直接挂载整个 config 目录?

  • 覆盖镜像内置核心文件:Elasticsearch 官方 Docker 镜像的 /usr/share/elasticsearch/config/ 内部自带了非常重要的系统默认文件(如 elasticsearch.ymljvm.optionslog4j2.propertiesroles.yml 以及系统证书等)。

  • 挂载机制冲突:当你把宿主机的一个空目录(或非完整的目录)挂载到容器的 /usr/share/elasticsearch/config 时,Docker 的挂载机制会直接用宿主机目录隐藏掉容器镜像内部的原有文件。导致 ES 启动时找不到基础配置文件或 keytool 证书而直接 Crash 崩溃。


6.3 重启 Elasticsearch 容器

注意安装 IK 分词器后必须重启 Elasticsearch 容器,才能让 Elasticsearch 加载这个插件。

docker restart elasticsearch_dev_V9.4.2

7. IK 分词器测试
curl -u elastic:Pass@8520 -X POST "http://localhost:9200/_analyze" -H "Content-Type: application/json" -d "{\"analyzer\":\"ik_smart\",\"text\":\"中华人民共和国国歌\"}"

在这里插入图片描述

更多推荐