OpenSearch 2.x Docker Compose 部署指南

使用 Docker Compose 一键部署 OpenSearch 2.x 单节点(官方镜像 `opensearchproject/opensearch:2.19.0`),涵盖数据持久化、配置文件挂载、健康检查、日志限制,并给出等价的 `docker run` 方式。部署文件位于 `/opt/data/ops/opensearch`,本文档全部命令均在...

OpenSearchOpenSearch容器化2026/09/27

OpenSearch 2.x Docker Compose 部署指南

目标:使用 Docker Compose 一键部署 OpenSearch 2.x 单节点(官方镜像 opensearchproject/opensearch:2.19.0),涵盖数据持久化、配置文件挂载、健康检查、日志限制,并给出等价的 docker run 方式。部署文件位于 /opt/data/ops/opensearch,本文档全部命令均在宿主机实测通过。

环境信息

  • Docker 版本:Docker 29.4.1(Compose v2)
  • 镜像版本:opensearchproject/opensearch:2.19.0(实测 OpenSearch 2.19.0,捆绑 JDK 21.0.6)
  • 容器名称:opensearch-2-x
  • 端口映射:宿主机 19201 → 容器 9200
  • 数据目录:宿主机 /opt/data/ops/opensearch/data
  • 配置目录:宿主机 /opt/data/ops/opensearch/conf(opensearch.yml 只读挂载)
  • 部署文件:/opt/data/ops/opensearch/docker-compose.yaml
  • 镜像拉取:docker.io 官方库直拉成功(本机配置了多个 registry-mirror 加速器)

端口规范说明

本环境宿主机端口遵循 「1 + 默认端口末 4 位」 规范:

服务容器内默认端口规范映射端口本环境实际端口原因
OpenSearch HTTP9200192001920119200 已被宿主机 Elasticsearch 容器(es-8-x)占用
Valkey63791637916380冲突调整(同规范)
MySQL33061330613306无冲突

💡 说明:若 19200 空闲,按规范应映射 19200:9200;本环境实测 19200 被 ES 占用,故使用 19201:9200。

前置条件

  • Docker Engine + Compose 插件(实测 Docker 29.4.1)
  • 已规划数据目录与配置目录(/opt/data/ops/opensearch/{data,conf})
  • 宿主机内存建议 ≥ 2G(本系列受限环境 512m 堆实测正常)
  • 镜像可拉取(docker.io 或 m.daocloud.io 等加速源)

部署步骤

步骤 1. 创建目录与配置文件

执行命令:

mkdir -p /opt/data/ops/opensearch/{data,conf}
cd /opt/data/ops/opensearch

创建 /opt/data/ops/opensearch/conf/opensearch.yml:

# =============================================================================
# OpenSearch 2.x 单节点配置(Docker Compose 挂载,实测 opensearchproject/opensearch:2.19.0)
# 安全插件已禁用(演示/测试简化),生产环境务必启用安全插件!
# =============================================================================
cluster.name: opensearch-cluster
node.name: opensearch-node-1
network.host: 0.0.0.0
http.port: 9200
discovery.type: single-node
plugins.security.disabled: true

💡 命令解释:mkdir -p 创建数据与配置目录;opensearch.yml 挂载覆盖镜像默认配置(默认只有 cluster.name 与 network.host,见配置详解文档)。

💡 说明:plugins.security.disabled: true 与镜像环境变量 DISABLE_SECURITY_PLUGIN=true 等效(实测 entrypoint 脚本第 34 行:DISABLE_SECURITY_PLUGIN=true 时写入该配置项)。

步骤 2. 编写 docker-compose.yaml

执行命令(文件内容):

# =============================================================================
# OpenSearch 2.x Docker Compose 部署文件(单节点,实测镜像 opensearchproject/opensearch:2.19.0)
# 使用方式:cd /opt/data/ops/opensearch && docker compose up -d
# 端口规范:宿主机端口 = '1' + 默认端口末4位(9200 -> 19200);
#           因宿主机 19200 已被 Elasticsearch 占用,本环境调整为 19201 -> 9200
# =============================================================================

services:
  opensearch:
    # 官方镜像(docker.io/opensearchproject/opensearch,实测版本 2.19.0)
    image: opensearchproject/opensearch:2.19.0

    # 容器名称,方便 docker ps / docker logs 定位
    container_name: opensearch-2-x

    # 重启策略:容器异常退出时自动重启(除非手动 stop)
    restart: unless-stopped

    # ---- 环境变量配置 ----
    environment:
      # 跳过安装演示配置(不自动生成 demo 证书/密码)
      - DISABLE_INSTALL_DEMO_CONFIG=true
      # 禁用安全插件(测试/演示简化;生产环境务必移除并启用安全插件!)
      - DISABLE_SECURITY_PLUGIN=true
      # JVM 堆内存:内存受限环境固定 512m(生产建议 4g-32g,不超过物理内存一半)
      - OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m
      # 单节点模式(与挂载配置中的 discovery.type 保持一致)
      - discovery.type=single-node

    # ---- 端口映射:宿主机19201 -> 容器9200 ----
    ports:
      - "19201:9200"

    # ---- 数据持久化(重要)----
    volumes:
      - ./data:/usr/share/opensearch/data
      # ---- 配置持久化:./conf/opensearch.yml 挂载覆盖默认配置 ----
      - ./conf/opensearch.yml:/usr/share/opensearch/config/opensearch.yml:ro

    # ---- 健康检查:容器内 curl 探测 HTTP 端口 ----
    healthcheck:
      test: ["CMD", "curl", "-fs", "http://localhost:9200/_cluster/health"]
      interval: 15s      # 每 15 秒检查一次
      timeout: 5s        # 单次检查超时
      retries: 10        # 连续 10 次失败视为不健康
      start_period: 30s  # 启动后 30 秒才开始检查(OpenSearch 启动较慢)

    # 容器日志大小限制,防止磁盘被日志占满
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "3"

💡 命令解释:DISABLE_INSTALL_DEMO_CONFIG=true 跳过 demo 配置安装脚本;DISABLE_SECURITY_PLUGIN=true 关闭安全插件(官方 entrypoint 实测支持,等效 plugins.security.disabled: true);OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m 覆盖默认 1g 堆(实测 _nodes/jvm 显示 512m);healthcheck 用镜像内置 curl 探测 / _cluster/health(实测镜像内 /usr/bin/curl 存在)。

💡 说明:-e discovery.type=single-node 与挂载的 opensearch.yml 中 discovery.type: single-node 同时存在(幂等,实测无冲突);配置改 ./conf/opensearch.yml 后 docker compose restart opensearch 生效。

步骤 3. 校验并启动

执行命令:

cd /opt/data/ops/opensearch
docker compose config --quiet && echo "compose 语法OK"
docker compose up -d
docker compose ps

执行结果:

compose 语法OK
 Network opensearch_default Creating
 Network opensearch_default Created
 Container opensearch-2-x Creating
 Container opensearch-2-x Created
 Container opensearch-2-x Starting
 Container opensearch-2-x Started

💡 命令解释:docker compose config --quiet 只校验语法不输出;up -d 后台创建并启动(默认项目名取目录名 opensearch,网络 opensearch_default)。

⚠️ 实测踩坑:首次启动约 1 分钟后容器仍 (health: starting) 且 curl 无响应,日志报 AccessDeniedException[/usr/share/opensearch/data/nodes]——宿主机新建的 ./data 目录属主为 root,容器内 opensearch 用户(uid 1000)无写权限。

修复命令(容器内 root 授权数据目录):

docker exec -u root opensearch-2-x chown -R opensearch:opensearch /usr/share/opensearch/data
docker compose restart

💡 命令解释:-u root 以容器内 root 执行 chown(bind mount 的写权限由宿主机内核裁决,容器 root 等同宿主机 root 权限);之后 restart 重新加载。

修复后结果:

 Container opensearch-2-x Restarting
 Container opensearch-2-x Started

步骤 4. 验证部署

执行命令:

docker compose ps --format '{{.Name}} {{.Status}}'
curl -s http://localhost:19201/ | grep -E '"(name|cluster_name|number)"'
curl -s 'http://localhost:19201/_cluster/health?pretty' | grep -E '"status"|"number_of_nodes"'

执行结果(实测):

opensearch-2-x Up About a minute (healthy)
  "name" : "opensearch-node-1",
  "cluster_name" : "opensearch-cluster",
  "number" : "2.19.0",
  "status" : "green",
  "number_of_nodes" : 1,

💡 说明:(healthy) 表示健康检查通过;节点名/集群名来自挂载的 ./conf/opensearch.yml(opensearch-node-1 / opensearch-cluster),证明配置挂载生效;版本 2.19.0、集群 green。

步骤 5. 数据持久化验证(重启不丢数据)

执行命令:

curl -s -X PUT 'http://localhost:19201/compose_test/_doc/1' -H 'Content-Type: application/json' -d '{"note":"compose deploy ok"}'
docker compose restart
sleep 40
curl -s 'http://localhost:19201/compose_test/_doc/1'

执行结果(实测):

# 写入
{"_index":"compose_test","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},...}
# 重启后读取
{"_index":"compose_test","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"note":"compose deploy ok"}}

💡 说明:./data bind mount 到 /usr/share/opensearch/data,重启后文档仍可读到(found: true),索引分片落盘在宿主机 ./data/nodes/0/indices/(实测目录存在)。单节点下 _shards.successful: 1(默认 1 副本无法分配,索引 yellow,数据可用)。

等价的 docker run

执行命令:

docker run -d --name opensearch-2-x \
  -p 19201:9200 \
  -e "discovery.type=single-node" \
  -e "DISABLE_INSTALL_DEMO_CONFIG=true" \
  -e "DISABLE_SECURITY_PLUGIN=true" \
  -e "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" \
  -v /opt/data/ops/opensearch/data:/usr/share/opensearch/data \
  -v /opt/data/ops/opensearch/conf/opensearch.yml:/usr/share/opensearch/config/opensearch.yml:ro \
  --restart unless-stopped \
  opensearchproject/opensearch:2.19.0

💡 命令解释:-p 19201:9200 端口映射;-e 环境变量与 compose 一一对应;-v 挂载数据与配置;--restart unless-stopped 重启策略。

💡 说明:若用 docker run 且数据目录首次使用,同样需要先 docker exec -u root <容器> chown -R opensearch:opensearch /usr/share/opensearch/data(或宿主机 chown 1000:1000)。本系列首个测试容器即以该命令启动,实测正常运行(集群名 docker-cluster)。

环境变量说明

环境变量作用实测状态
DISABLE_INSTALL_DEMO_CONFIG=true跳过 demo 证书/密码生成✅ 生效(entrypoint 第 40 行)
DISABLE_SECURITY_PLUGIN=true关闭安全插件(等效 plugins.security.disabled: true)✅ 生效(entrypoint 第 34 行)
OPENSEARCH_JAVA_OPTSJVM 参数追加,覆盖默认堆 1g✅ 生效(实测 heap 512m)
discovery.type以环境变量方式注入 yml 配置✅ 生效

注意事项

  • 数据目录属主:首次使用 ./data 必须授权容器用户(chown -R 1000:1000 或容器内 chown -R opensearch:opensearch),否则 AccessDeniedException。
  • 安全插件:DISABLE_SECURITY_PLUGIN=true 仅限测试/演示;生产必须移除并配置安全插件(密码/证书/HTTPS),勿将 19201 暴露公网。
  • 端口规范:1 + 默认端口末4位;若 19200 空闲应映射 19200:9200,冲突时顺延(本环境用 19201)。
  • 堆内存:512m 仅适合受限演示;生产堆不超过物理内存一半(如 8G 机器给 4G)。
  • 健康检查:start_period: 30s 需大于 OpenSearch 实际启动时间(本环境实测 30~60s 才 healthy),检查失败不误杀容器。
  • 镜像拉取失败时可用加速源:m.daocloud.io/docker.io/opensearchproject/opensearch:2.19.0。

常见问题

问题 1:容器反复重启 / AccessDeniedException: /usr/share/opensearch/data/nodes

原因: 宿主机 ./data 目录属主为 root,容器内 opensearch 用户(uid 1000)无法创建 nodes 目录(实测日志原文)。

解决:

docker exec -u root opensearch-2-x chown -R opensearch:opensearch /usr/share/opensearch/data
docker compose restart

问题 2:健康检查长时间 starting / unhealthy

原因: start_period 过短(OpenSearch 启动 + 插件初始化需 30~60s,实测);或安全插件未关导致探测被拒。

解决: 将 start_period 设为 30~60s;确认 DISABLE_SECURITY_PLUGIN=true 生效(docker logs opensearch-2-x | grep -i security)。

问题 3:宿主机 19200 被占用(端口冲突)

原因: 同规范端口已被其他服务(本环境 Elasticsearch 容器 es-8-x 占用 19200)使用,docker run -p 19200:9200 报 port is already allocated。

解决: 顺延一个端口:

docker run -d --name opensearch-2-x -p 19201:9200 ...   # 或改 compose ports 为 "19201:9200"

问题 4:堆内存不足 / 写入 429

原因: 512m 堆写入大 bulk 时线程池排队,报 429 Too Many Requests 或 OOM。

解决: 增大 OPENSEARCH_JAVA_OPTS(如 -Xms1g -Xmx1g)并重启;或拆分 bulk 批次、调大 thread_pool.write.queue_size。

卸载方式

cd /opt/data/ops/opensearch
docker compose down          # 停止并移除容器与默认网络(数据卷 ./data 保留)
docker rm -f opensearch-2-x  # 若用 docker run 启动
rm -rf /opt/data/ops/opensearch/data /opt/data/ops/opensearch/conf   # 清理数据与配置(确认已备份)

💡 说明:docker compose down 不删除 bind mount 数据目录,清理数据需手动 rm -rf ./data(先备份)。

参考链接


本文档由 www.quzuo.net 平台开发