Apache ResilientDB Docker Compose 部署指南

使用 Docker Compose 部署 Apache ResilientDB:多阶段 Dockerfile 编译源码与生成证书、compose 单服务编排与端口映射、容器内客户端读写验证、等价 docker run 与常见问题,命令均实测

Apache ResilientDBApache ResilientDB2026/10/12

Apache ResilientDB Docker Compose 部署指南

目标:以 Docker Compose 一键部署 Apache ResilientDB KV 服务(4 副本 + 1 客户端代理):多阶段 Dockerfile 内完成源码编译与证书生成,docker-compose.yml 编排单服务并映射 10001-10005 端口,最后用官方客户端完成读写验证。全部命令与回显均在真实环境实测。

一、环境信息

  • 操作系统:Ubuntu 22.04(构建机与镜像基础镜像一致,x86_64)
  • Docker:29.8.1(Docker Compose v5.5.1,BuildKit 默认开启)
  • 部署目录:/root/rdb-compose
  • 镜像:resilientdb-kv:latest(自建,约 5.12GB)
  • 源码:master 分支 commit 4de5cb43686276ace4307f44839a1de920ab524a
  • 端口映射:宿主机 10001-10005 → 容器 10001-10005
  • 容器内运行用户:root

二、前置条件

  • Docker 与 Docker Compose 插件可用:
docker --version
docker compose version

回显:

Docker version 29.8.1, build 4a63305
Docker Compose version v5.5.1
  • 磁盘剩余空间 15GB 以上(镜像约 5.12GB,构建上下文与缓存另需数 GB)。
  • 已具备源码目录 /root/rdb-compose/incubator-resilientdb(git clone 获取)与 Bazel 6.0.0 二进制(与源码 .bazelversion 一致,官方发布页提供 sha256 校验文件)。

三、版本选型说明

组件版本说明
Apache ResilientDBmaster(commit 4de5cb4)源码编译;官方发行版另见 https://downloads.apache.org/incubator/resilientdb/
基础镜像ubuntu:22.04与裸机安装指南环境保持一致
Bazel6.0.0源码 .bazelversion 固定版本,多阶段构建中显式安装
Docker / Compose29.8.1 / v5.5.1BuildKit 多阶段构建

💡 Apache ResilientDB 官方 Docker/Dockerfile 基于 Ubuntu 20.04 且只预编译客户端工具;本文自建镜像基于 Ubuntu 22.04、预编译服务端与客户端并生成证书,容器启动即就绪。

四、部署步骤

4.1 目录准备

mkdir -p /root/rdb-compose && cd /root/rdb-compose
git clone https://github.com/apache/incubator-resilientdb incubator-resilientdb

回显:

Cloning into 'incubator-resilientdb'...
remote: Enumerating objects: 9241, done.

将 Bazel 6.0.0 二进制放入部署目录并命名 bazel-6.0.0-linux-x86_64(官方发布页下载,校验命令与发布页 sha256 比对):

sha256sum bazel-6.0.0-linux-x86_64

回显(与 bazel 官方发布页 6.0.0 sha256 一致):

f03d44ecaac3878e3d19489e37caa4ca1dc57427b686a78a85065ea3c27ebe68  bazel-6.0.0-linux-x86_64

4.2 编写 Dockerfile(多阶段构建)

创建 /root/rdb-compose/Dockerfile:

# Apache ResilientDB KV 服务自建镜像(多阶段构建)
# 阶段一:编译 ResilientDB 并生成证书
FROM ubuntu:22.04 AS builder
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
    build-essential ca-certificates clang-format curl default-jre-headless \
    protobuf-compiler python3-dev rapidjson-dev unzip zip

# 安装 Bazel 6.0.0(与源码 .bazelversion 一致)
COPY bazel-6.0.0-linux-x86_64 /usr/local/bin/bazel
RUN chmod 0755 /usr/local/bin/bazel && bazel --version

COPY incubator-resilientdb /root/incubator-resilientdb
WORKDIR /root/incubator-resilientdb

# 编译 KV 服务端与客户端工具
RUN bazel build //service/kv:kv_service //service/tools/kv/api_tools:kv_service_tools

# 生成证书与公私钥(node1-5 + admin)
RUN /bin/bash ./service/tools/kv/server_tools/generate_keys_and_certs.sh

# 阶段二:运行镜像
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y default-jre-headless psmisc net-tools \
    && rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/local/bin/bazel /usr/local/bin/bazel
COPY --from=builder /root/.cache/bazel /root/.cache/bazel
COPY --from=builder /root/incubator-resilientdb /root/incubator-resilientdb
WORKDIR /root/incubator-resilientdb
EXPOSE 10001 10002 10003 10004 10005
ENTRYPOINT ["./entrypoint.sh"]

⚠️ 两个易错点(均实测踩过):

  1. 证书生成脚本必须用 /bin/bash 调用——generate_keys_and_certs.sh 文件头没有 shebang 且使用 bash 数组语法,直接 RUN ./generate_keys_and_certs.sh 会以 dash 执行并报:
    ./service/tools/kv/server_tools/generate_keys_and_certs.sh: 20: Syntax error: "(" unexpected
    
  2. 运行阶段需要保留 bazel 二进制与 /root/.cache/bazel(预热的构建输出)——官方入口 entrypoint.sh 会执行 start_kv_service.sh,其中包含一次 bazel build //service/kv:kv_service 增量校验;运行阶段缺少 bazel 时虽不影响服务启动(二进制已预编译),但日志会报 bazel: command not found。

4.3 编写 docker-compose.yml

创建 /root/rdb-compose/docker-compose.yml:

services:
  kv-server:
    build: .
    image: resilientdb-kv:latest
    container_name: resilientdb-kv-server
    restart: unless-stopped
    mem_limit: 4g
    ports:
      - "10001:10001"
      - "10002:10002"
      - "10003:10003"
      - "10004:10004"
      - "10005:10005"

💡 单服务编排:4 个共识副本与 1 个客户端代理都在同一容器内由官方脚本管理(start_kv_service.sh),对外只需暴露 10001-10005。多容器多副本拓扑需为每个副本单独生成证书与配置,见「注意事项」。

4.4 构建镜像

cd /root/rdb-compose
docker build -t resilientdb-kv:latest .

首次构建为全量编译,约 30-60 分钟(duckdb、cryptopp、boost 等大文件为主);实测构建成功结尾回显:

#22 unpacking to docker.io/library/resilientdb-kv:latest
#22 unpacking to docker.io/library/resilientdb-kv:latest 38.3s done
#22 DONE 126.1s

查看镜像:

docker images resilientdb-kv

回显:

REPOSITORY      TAG       IMAGE ID       CREATED          SIZE
resilientdb-kv  latest    4d8123e1799e   6 minutes ago    5.12GB

💡 构建提速:Bazel 支持磁盘缓存,构建命令可改为 bazel build --disk_cache=/root/bazel-disk-cache ...,并把缓存目录随构建上下文 COPY 进构建阶段,二次构建实测仅需约 87 秒(INFO: Build completed successfully, 414 total actions,364 个动作直接命中磁盘缓存)。弱网环境可先把 WORKSPACE/repositories.bzl 中的依赖包按文件名预下载到目录,构建时加 --distdir=/root/rdb-dist(详见《Ubuntu 22.04 安装 Apache ResilientDB 指南》Q2)。

4.5 启动服务

cd /root/rdb-compose
docker compose up -d

回显:

 Container resilientdb-kv-server Created
 Container resilientdb-kv-server Starting
 Container resilientdb-kv-server Started

首次启动容器会执行官方入口 entrypoint.sh:先清理旧进程,再运行一次 Bazel 增量校验(约 60-90 秒),随后拉起 4 副本与客户端代理。启动日志(docker logs resilientdb-kv-server):

kv_service: no process found
Starting local Bazel server and connecting to it...
Loading:
Analyzing: target //service/kv:kv_service (117 packages loaded, 3561 targets configured)

服务就绪后日志滚动输出共识监控(stats.cpp:424] =========== monitor ========== 每周期一次)。

4.6 验证部署

查看容器状态与端口映射:

docker compose ps

回显:

NAME                    IMAGE                   COMMAND             SERVICE     CREATED         STATUS         PORTS
resilientdb-kv-server   resilientdb-kv:latest   "./entrypoint.sh"   kv-server   3 minutes ago   Up 3 minutes   0.0.0.0:10001-10005->10001-10005/tcp, [::]:10001-10005->10001-10005/tcp

容器内核对 5 个监听端口并执行读写:

docker compose exec kv-server bash -c 'netstat -tln | grep -c 1000'

回显:

5

写入数据:

docker compose exec kv-server ./bazel-bin/service/tools/kv/api_tools/kv_service_tools \
    --config service/tools/config/interface/service.config \
    --cmd set --key compose_test --value hello_resdb

回显(glog 配置解析提示行为正常输出):

E20261012 15:47:10.902683   375 resdb_config_utils.cpp:146] parse json id:1 ip:127.0.0.1 port:10005
set key = compose_test, value = hello_resdb done, ret = 0

读取数据:

docker compose exec kv-server ./bazel-bin/service/tools/kv/api_tools/kv_service_tools \
    --config service/tools/config/interface/service.config \
    --cmd get --key compose_test

回显:

E20261012 15:47:10.910007   377 resdb_config_utils.cpp:146] parse json id:1 ip:127.0.0.1 port:10005
get key = compose_test value = hello_resdb

4.7 等价 docker run 方式

单容器启动(与 compose 等价;同一镜像可复用):

docker run -d --name resilientdb-kv -p 10001-10005:10001-10005 resilientdb-kv:latest

实测容器内验证(与 compose 一致):

set key = run_test, value = docker_ok done, ret = 0
get key = run_test value = docker_ok

⚠️ compose 与 docker run 两种方式不要同时跑在同一批端口上,端口冲突会导致第二个实例副本监听失败。

五、配置说明

  • 端口:docker-compose.yml 中 10001-10004 为副本共识端口,10005 为客户端代理端口;宿主机侧如需错峰可改左侧端口(如 20001:10001),容器内端口保持不变(service.config 指向容器内 127.0.0.1:10005)。
  • 资源:mem_limit: 4g 满足默认内存存储形态(空载单进程 RSS 约 95MB,见实测);启用 LevelDB 后按 leveldb_info 缓存配置上调。
  • 重试策略:restart: unless-stopped 保证异常退出后自动拉起;服务重启后数据会因默认内存存储而清空(实测验证,见《Ubuntu 22.04 安装 Apache ResilientDB 指南》注意事项)。
  • 镜像内路径:源码与构建输出固定在 /root/incubator-resilientdb,证书在 service/tools/data/cert/,配置在 service/tools/config/。

六、注意事项

  • 默认内存存储:容器重启后 KV 数据清空,需持久化请在构建阶段使用 bazel build //service/kv:kv_service --define=enable_leveldb=True 并在 server.config 中配置 leveldb_info。
  • 容器内地址:server.config 与 service.config 默认全部指向 127.0.0.1,单容器部署保持默认即可;客户端应用如部署在容器外,需在容器外通过宿主机映射端口访问,或将客户端工具放入容器内执行(本文采用容器内执行)。
  • 多副本多容器拓扑:将 4 个副本拆分到 4 个容器时,需为每个副本生成独立证书并改写 server.config 为各容器 IP(自定义 compose 网络),同步调整 start_kv_service.sh 的启动方式;本文给出的是官方单容器多进程拓扑,生产验证最充分。
  • HTTP/GraphQL 接口:官方生态的 crow HTTP 服务(默认 18000 端口,ecosystem/graphql/service/http_server)在当前 master 源码下无法随主仓编译,实测报错:
    ERROR: Skipping '//ecosystem/graphql/service/http_server:crow_service_main': no such package 'ecosystem/graphql/service/http_server': Package is considered deleted due to --deleted_packages
    
    (ecosystem/graphql 为嵌套 WORKSPACE 被主仓排除,其 BUILD 还引用了旧路径 //service/kv_service:resdb_kv_client。)因此本指南的接口验证以官方客户端 kv_service_tools 为准;HTTP/GraphQL 需待上游修复后补充验证。
  • 构建网络:镜像内 Bazel 构建需要访问 GitHub、dl.google.com、archives.boost.io 等域名;内网或弱网环境用 distdir 预置依赖包(见 4.4 节提速说明)。

七、常见问题

7.1:docker compose up 后立即退出或端口不通

定位:首次启动含一次 Bazel 增量校验,约 60-90 秒后服务才就绪,过早验证会误判。 解决:等待约 80 秒后 docker compose ps 确认 Up,再执行 docker compose exec kv-server bash -c 'netstat -tln | grep -c 1000'(应为 5)。

7.2:构建报 Syntax error: "(" unexpected

定位:generate_keys_and_certs.sh 无 shebang,被 dash 执行到 bash 数组语法。 解决:Dockerfile 中改为 RUN /bin/bash ./service/tools/kv/server_tools/generate_keys_and_certs.sh(见 4.2 节 ⚠️)。

7.3:构建在 Analyzing 阶段长时间卡住

定位:外部依赖抓取超时(golang.org 版本查询、boostorg.jfrog.io 已停服、GitHub 抖动等),常见报错:

WARNING: Download from https://golang.org/dl/?mode=json&include=all failed: class java.io.IOException connect timed out

解决:按 4.4 节说明使用 --distdir 预置依赖包(boost_1_80_0.tar.gz 从 https://archives.boost.io/release/1.80.0/source/ 获取,go SDK 从 https://dl.google.com/go/ 获取),必要时对 Bazel 下载重试,已下载条目会持久保留。

7.4:容器日志出现 bazel: command not found

定位:运行镜像阶段未携带 bazel 二进制,start_kv_service.sh 的增量构建步骤失败;因二进制已预编译,服务仍会启动。 解决:按 4.2 节 Dockerfile 在运行阶段补 COPY --from=builder /usr/local/bin/bazel /usr/local/bin/bazel 重建。

7.5:宿主机端口 10001-10005 被占用

定位:宿主机已有裸机部署或另一套容器在监听同批端口。 解决:修改 docker-compose.yml 左侧映射端口(如 20001:10001),或先停止裸机 KV 服务(killall -9 kv_service)再启动。

八、参考链接