Docker Compose 部署 Elasticsearch(单节点)
前言
Elasticsearch 用来做全文检索、日志检索、以及聚合分析时非常方便。
为了让本地开发、测试环境一键可复现,最省心的方式通常是用 docker compose 管起来。
本文以单节点为目标,给出一份可直接运行的 docker-compose.yml,并补齐持久化与常见报错的处理方式。
如果你只需要一个能用的 ES 来跑 demo 或联调接口,照着做就能很快跑起来。
准备
你需要先确认本机已经安装 Docker Desktop,并且 docker compose 可用。
下面命令用于确认 Docker 与 Compose 插件可正常工作。
1 | docker version |
如果你在 Windows 上使用 Docker Desktop,推荐使用 WSL2 后端。
后面涉及的内核参数调整,在 WSL2 与 Linux 主机上写法不同,我会分别给出。
实现
创建目录
先准备一个独立目录,用于存放 docker-compose.yml 与持久化数据目录。
下面给出一个示例目录结构,你也可以按自己习惯调整。
1 | mkdir -p es-compose |
编写 docker-compose.yml
下面这份 Compose 会拉起一个单节点 Elasticsearch,并把数据目录持久化到宿主机。
你只需要把 STACK_VERSION 改成你要的 ES 版本即可,建议用同一个大版本在团队内统一。
如果你希望开启安全认证,并且让 elastic 用户的默认密码来自 .env,可以使用 ELASTIC_PASSWORD。
需要注意的是,这个密码通常只在数据目录为空的首次初始化时生效。
如果你已经挂载了 ./data 并启动过,再修改 ELASTIC_PASSWORD 一般不会自动修改已有密码,这时需要清空数据重新初始化或执行重置密码命令。
1 | services: |
上面配置里我开启了安全认证,并关闭了 HTTPS,方便开发环境直接访问。
默认用户名是 elastic,密码就是 ELASTIC_PASSWORD 的值。
如果你要用于公网或准生产环境,建议开启 HTTPS,并配合反向代理与访问控制。
这里也补充一下端口的作用,方便你按需暴露端口与做防火墙策略。9200 是 Elasticsearch 的 HTTP 接口端口,curl 调用、Kibana 访问、以及业务服务的 REST 客户端通常都连这个端口。9300 是 Elasticsearch 节点之间的传输端口,集群内部通信、节点加入集群等会用到它,单节点模式下通常不需要对外网暴露。5601 是 Kibana 的 Web UI 端口,用浏览器访问 Kibana 控制台时会用到它,如果你不部署 Kibana 就不需要暴露。
如果你希望把数据目录挂载到宿主机目录(例如 ./data:/usr/share/elasticsearch/data),需要确保宿主机目录对容器内的 elasticsearch 用户可写。
在官方镜像里通常是以 uid 1000 运行,所以你可以在启动前执行下面命令修正权限。
1 | mkdir -p ./data |
编写 .env(推荐)
为了避免在 compose 文件里写死版本,你可以用 .env 来管理变量。
下面给一个示例,版本号与默认密码按你项目实际需要调整。
开启安全认证后,默认用户名是 elastic,密码就是 ELASTIC_PASSWORD。
Kibana 连接 Elasticsearch 建议使用内置用户 kibana_system,并在 .env 中配置 KIBANA_PASSWORD。
1 | STACK_VERSION=8.13.4 |
如果你开启了安全认证,并且想在已初始化后修改密码,可以进入容器执行交互式重置。
下面命令把 kibana_system 用户的密码重置为你输入的新值,然后把同样的值写到 .env 的 KIBANA_PASSWORD 中即可。
1 | docker exec -it es /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -i |
注意
启动后要执行第二条命令设置
kibana_system的密码,否则kibana无法登录
调整内核参数 vm.max_map_count
Elasticsearch 在 Linux 内核上通常要求 vm.max_map_count 至少为 262144。
下面给出在 Linux 主机上一次性生效与持久化生效两种写法。
1 | sudo sysctl -w vm.max_map_count=262144 |
如果你在 Windows 的 WSL2 里跑 Docker 后端,可以先在 WSL 发行版里执行同样命令。
如果你发现重启后失效,可以考虑在 WSL 的启动脚本或 wsl.conf 方案里做持久化,这部分不同发行版可能略有差异。
启动
下面命令会在后台启动 Elasticsearch 与 Kibana。
首次启动会拉取镜像,速度取决于网络情况。
1 | docker compose up -d |
验证
查看日志
1 | docker logs -f es |
你可以先用 curl 验证 ES 是否能返回基本信息。
下面命令会请求 ES 根路径与集群健康状态。
1 | curl -u elastic:${ELASTIC_PASSWORD} -s http://localhost:9200 |
如果你也启动了 Kibana,可以用浏览器访问 http://localhost:5601。
如果 Kibana 一直转圈或报错,优先看它自己的日志。
1 | docker logs -f kibana |
如果 Elasticsearch 开启了安全认证,而 Kibana 没有配置连接 Elasticsearch 的用户名密码,Kibana 通常无法正常启动或会持续重试。
你可以先用下面命令确认 Kibana 端口是否在监听,以及容器是否处于运行状态。
1 | docker compose ps |
常见问题
vm.max_map_count 太小
如果日志里出现 vm.max_map_count [xxx] is too low,说明你的宿主机内核参数没调到位。
你可以按本文前面 vm.max_map_count 的步骤调整,然后重启容器。
1 | docker compose restart elasticsearch |
文件描述符 nofile 太小
如果日志里出现 max file descriptors [xxxx] for elasticsearch process is too low,说明 nofile 不够。
本文的 compose 已经通过 ulimits.nofile 做了常见修正,但某些环境可能仍需要在宿主机层面提高限制。
你可以先确认容器内当前限制值,再决定是否需要改宿主机配置。
1 | docker exec -it es /bin/bash -lc "ulimit -n && ulimit -l" |
内存不足或启动很慢
如果你机器内存比较小,ES_JAVA_OPTS 的 -Xms/-Xmx 建议下调。
例如改成 -Xms512m -Xmx512m,更适合轻量 demo。
扩展
只启动 Elasticsearch
如果你只需要 ES,不需要 Kibana,可以把 kibana 服务从 compose 里删掉。
或者启动时只拉起指定服务。
1 | docker compose up -d elasticsearch |
清理与重置数据
如果你需要完全重置数据,先停服务,再删除本地 data 目录。
这会导致索引与数据全部丢失,请确认是你想要的效果。
1 | docker compose down |
总结
用 Docker Compose 部署 Elasticsearch 的最小落地流程可以概括为三步。
- 写好
docker-compose.yml,用volumes做持久化。 - 调整
vm.max_map_count与nofile,解决 ES 启动最常见的系统限制问题。 - 用
curl与健康检查验证服务状态,必要时查看docker logs定位问题。