Apache Amoro 0.8.1-incubating Docker Compose 部署指南

Apache Amoro 0.8.1-incubating Docker Compose 部署指南:自建 amoro:0.8.1 镜像(eclipse-temurin:8-jdk 基础)并用 Compose 编排 AMS,挂载 config.yaml/jvm.properties 与 derby 数据目录,端口 1630/1260/1261 映射,JVM 堆 256-512MB,重启数据持久化,全程命令与回显实测

Apache AmoroAmoro2026/10/13

Apache Amoro 0.8.1-incubating Docker Compose 部署指南

目标:使用 Docker Compose 编排 Apache Amoro 0.8.1-incubating 的 AMS 服务,通过自建镜像注入发行包、挂载 config.yaml / jvm.properties 与 derby 数据目录,实现「一条 docker compose 命令拉起湖仓管理服务」。端口 1630/1260/1261 映射到宿主机,JVM 堆限定 256-512MB,全程命令与回显均为实际执行结果。

一、环境信息

  • Docker:24.x(本指南实测环境)
  • Docker Compose:v2(docker compose 子命令)
  • Amoro 镜像:自建 amoro:0.8.1(基于 eclipse-temurin:8-jdk,内含 Amoro 0.8.1-incubating bin-hadoop3 发行包)
  • 服务:amoro(AMS 单服务,Web 控制台 + REST + Thrift 同进程)
  • 映射端口:1630(HTTP)、1260(表服务 Thrift)、1261(优化服务 Thrift)
  • 配置挂载:./conf/config.yaml、./conf/jvm.properties → 镜像内对应文件;./data → /opt/amoro/data(derby 元数据落盘)
  • 管理账号:admin / q1w2e3r4

说明:Docker Hub 上有官方镜像 apache/amoro:0.8.1-incubating 可直接使用;若内网无法拉取官方镜像,可按本指南用官方发行包自建镜像(本文采用),原理与配置完全一致。

二、镜像选型说明

镜像基础说明
apache/amoro:0.8.1-incubating官方构建官方发布镜像,直接 pull 即用,需外部挂载配置
amoro:0.8.1(自建)eclipse-temurin:8-jdk本指南采用,把官方 tar.gz 发行包打进镜像,版本与二进制部署完全一致,便于离线交付与留档

关键差异:两者运行时行为相同(AMS 都是同一发行包)。自建镜像的价值在于:基础镜像与制品版本可固定、可离线分发、可按需叠加 Hadoop/Hive 客户端配置。本文以自建镜像为主线。

三、前置条件

  • 装有 Docker 与 Docker Compose v2 的服务器,root 权限。
  • 已从官方下载站取得 apache-amoro-0.8.1-incubating-bin-hadoop3.tar.gz(约 310MB,下载与 sha512 校验方式见《Apache Amoro 0.8.1-incubating 安装指南》4.2 节,本文不再重复校验输出)。
  • 宿主机 1630、1260、1261 端口空闲(ss -tlnp | grep -E '1630|1260|1261' 应无输出)。

四、部署步骤

4.1 创建目录结构

mkdir -p amoro-compose/conf amoro-compose/data
cd amoro-compose
cp /opt/apache-amoro-0.8.1-incubating-bin-hadoop3.tar.gz .
ls -l
-rw-r--r-- 1 root root 324970517 10月 13 11:29 apache-amoro-0.8.1-incubating-bin-hadoop3.tar.gz
drwxr-xr-x 2 root root      4096 10月 13 11:29 conf
drwxr-xr-x 2 root root      4096 10月 13 11:33 data

4.2 编写自建镜像的 Dockerfile

cat > Dockerfile <<'EOF'
FROM eclipse-temurin:8-jdk

# Amoro 0.8.1-incubating(bin-hadoop3 发行包,与 Dockerfile 同目录提前下载好)
COPY apache-amoro-0.8.1-incubating-bin-hadoop3.tar.gz /tmp/

RUN cd /tmp \
    && tar -xzf apache-amoro-0.8.1-incubating-bin-hadoop3.tar.gz \
    && mv amoro-0.8.1-incubating /opt/amoro \
    && rm -f apache-amoro-0.8.1-incubating-bin-hadoop3.tar.gz

ENV AMORO_HOME=/opt/amoro
EXPOSE 1630 1260 1261
CMD ["/opt/amoro/bin/ams.sh", "start-foreground"]
EOF
指令说明
FROM eclipse-temurin:8-jdkAmoro 支持 JDK 8/11;选 8-jdk 基础镜像,镜像内 JAVA_HOME 为 /opt/java/openjdk
COPY ... /tmp/把已下载好的发行包带进构建(比构建期 wget 更稳,离线也可构建)
CMD ams.sh start-foreground前台运行,日志输出交给 docker,容器退出即服务退出
EXPOSE1630 HTTP、1260/1261 Thrift,声明性端口

构建镜像:

docker build -t amoro:0.8.1 .
#8 naming to docker.io/library/amoro:0.8.1 done
#8 unpacking to docker.io/library/amoro:0.8.1 3.8s done
#8 DONE 16.4s
docker images | grep amoro
amoro:0.8.1                                                         de4368919c40       1.79GB          770MB   U

解读:本机 docker 输出列中 DISK USAGE 1.79GB 为镜像占用磁盘(含 temurin JDK 解压层),CONTENT SIZE 770MB 为镜像内容大小;镜像 ID 每次构建不同,以本机输出为准。

4.3 准备挂载用的配置文件

从镜像里取出出厂配置作为底稿:

docker run --rm amoro:0.8.1 cat /opt/amoro/conf/config.yaml > conf/config.yaml
docker run --rm amoro:0.8.1 bash -c "grep -vE '^ *#|^ *$' /opt/amoro/conf/jvm.properties" > conf/jvm.properties
wc -l conf/config.yaml conf/jvm.properties
  214 conf/config.yaml
    4 conf/jvm.properties

对 conf/config.yaml 做三处修改(管理密码、derby 路径、镜像内 JAVA_HOME):

sed -i 's/admin-password: admin/admin-password: q1w2e3r4/' conf/config.yaml
sed -i 's|url: jdbc:derby:/tmp/amoro/derby;create=true|url: jdbc:derby:/opt/amoro/data/derby;create=true|' conf/config.yaml
sed -i 's|export.JAVA_HOME: "/opt/java"|export.JAVA_HOME: "/opt/java/openjdk"|' conf/config.yaml
grep -nE "admin-password|url: jdbc:derby|export.JAVA_HOME" conf/config.yaml
20:  admin-password: q1w2e3r4
111:    url: jdbc:derby:/opt/amoro/data/derby;create=true
167:      export.JAVA_HOME: "/opt/java/openjdk"   # JDK environment

修改 conf/jvm.properties,把出厂 8GB 堆限制到 256-512MB:

sed -i 's/^xms=.*/xms=256/; s/^xmx=.*/xmx=512/' conf/jvm.properties
cat conf/jvm.properties
xms=256
xmx=512
jmx.remote.port=
extra.options="-XX:NewRatio=1 -XX:SurvivorRatio=3 -XX:+ExitOnOutOfMemoryError"

⚠️ derby 路径特意写成 /opt/amoro/data/derby(父目录 /opt/amoro/data 将被挂载),而不是直接挂载 derby 目录本身——derby ;create=true 要求目标目录不存在(详见「九、常见问题」9.1)。

4.4 编写 docker-compose.yml

cat > docker-compose.yml <<'EOF'
services:
  amoro:
    image: amoro:0.8.1
    container_name: amoro-ams
    hostname: amoro-ams
    ports:
      - "1630:1630"
      - "1260:1260"
      - "1261:1261"
    volumes:
      - ./conf/config.yaml:/opt/amoro/conf/config.yaml
      - ./conf/jvm.properties:/opt/amoro/conf/jvm.properties
      - ./data:/opt/amoro/data
    restart: unless-stopped
EOF
配置项说明
hostname: amoro-ams必须显式设置:AMS 启动时要解析自身主机名,不设会报 UnknownHostException(见 9.2)
portsWeb/REST 1630,Thrift 1260/1261,三端口一并映射
volumes两个配置文件单文件挂载,derby 数据经父目录 ./data 落盘宿主机
restart: unless-stopped宿主机重启后自动拉起(docker 服务在运行时)

4.5 启动与状态确认

docker compose up -d
[+] Running 2/2
 ✔ Network amoro-compose_default    Created
 ✔ Container amoro-ams              Started
docker compose ps
NAME        IMAGE         COMMAND                   SERVICE   CREATED          STATUS                  PORTS
amoro-ams   amoro:0.8.1   "/__cacert_entrypoin…"   amoro     19 minutes ago   Up Less than a second   0.0.0.0:1260-1261->1260-1261/tcp, [::]:1260-1261->1260-1261/tcp, 0.0.0.0:1630->1630/tcp, [::]:1630->1630/tcp

解读:COMMAND 显示 "/__cacert_entrypoin…" 是 temurin 基础镜像的入口脚本,它再 exec 我们的 ams.sh start-foreground;PORTS 中 1260-1261 为 docker 对连续端口的合并展示。

derby 首次初始化会在 stdout 打印建表 SQL(输出节选,实测首部):

docker logs amoro-ams 2>&1 | grep -E 'CREATE TABLE' | head -5
CREATE TABLE catalog_metadata (
CREATE TABLE database_metadata (
CREATE TABLE optimizer (
CREATE TABLE resource (
CREATE TABLE resource_group (

服务就绪标志(Thrift 两个线程与 HTTP 端口)在容器内主日志中确认:

docker exec amoro-ams grep -E 'thrift-.*started|Http server start' /opt/amoro/logs/ams-info.log | tail -3
thrift-table-management-server-thread has been started
thrift-optimizing-server-thread has been started
Http server start at 1630.

4.6 服务验证

Web 控制台:浏览器访问 http://<宿主机IP>:1630/,用 admin / q1w2e3r4 登录。命令行验证首页与免登录版本接口:

curl -s -o /dev/null -w "index:%{http_code}\n" http://127.0.0.1:1630/
curl -s http://127.0.0.1:1630/api/ams/v1/versionInfo
index:200
{"message":"success","code":200,"result":{"version":"0.8.1-incubating(bc906c0)","commitTime":"2025-08-28T08:55:33+0800"}}

登录接口与会话访问(与 Web 控制台同款):

curl -s -c /tmp/amoro-cookie.txt -X POST http://127.0.0.1:1630/api/ams/v1/login \
  -H "Content-Type: application/json" -H "X-Request-Source: Web" \
  -d '{"user":"admin","password":"q1w2e3r4"}'
{"message":"success","code":200,"result":"success"}
curl -s -b /tmp/amoro-cookie.txt -H "X-Request-Source: Web" \
  http://127.0.0.1:1630/api/ams/v1/overview/summary
{"message":"success","code":200,"result":{"catalogCnt":0,"tableCnt":0,"tableTotalSize":0,"totalCpu":0,"totalMemory":0}}

确认容器内 JVM 堆实际生效值(验证 4.3 的 jvm.properties 挂载已生效):

docker exec amoro-ams ps -ef | grep [j]ava | grep -oE '\-Xms[0-9]+m -Xmx[0-9]+m'
-Xms256m -Xmx512m

五、数据持久化说明

数据落盘位置说明
derby 元数据宿主机 ./data/derby/AMS 全部目录/表/优化任务元数据,重启不丢
运行日志容器内 /opt/amoro/logs/未挂载,随容器删除而丢;需留存见下方提示
配置宿主机 ./conf/config.yaml 与 jvm.properties 均为宿主机文件

验证持久化:重启后登录接口依旧可用(元数据库复用):

docker compose restart
sleep 30
docker compose ps
curl -s -c /tmp/amoro-cookie.txt -X POST http://127.0.0.1:1630/api/ams/v1/login \
  -H "Content-Type: application/json" -H "X-Request-Source: Web" \
  -d '{"user":"admin","password":"q1w2e3r4"}'
 Container amoro-ams  Restarting
 Container amoro-ams  Started
NAME        IMAGE         COMMAND                   SERVICE   CREATED          STATUS          PORTS
amoro-ams   amoro:0.8.1   "/__cacert_entrypoin…"   amoro     22 minutes ago   Up 30 seconds   0.0.0.0:1260-1261->1260-1261/tcp, [::]:1260-1261->1260-1261/tcp, 0.0.0.0:1630->1630/tcp, [::]:1630->1630/tcp
{"message":"success","code":200,"result":"success"}
ls data/derby/
README_DO_NOT_TOUCH_FILES.txt  db.lck  dbex.lck  log  seg0  service.properties

💡 说明:AMS 日志默认写容器内 /opt/amoro/logs/。若需在宿主机留存日志,在 volumes: 中追加 - ./logs:/opt/amoro/logs 即可(目录会自动创建)。

六、环境变量表

Amoro 镜像没有业务语义的环境变量,行为全部由挂载的配置文件驱动。与运行相关的环境层面项如下:

环境变量/等价配置默认值说明
AMORO_HOME(镜像内 ENV)/opt/amoro安装根目录,ams.sh 据此定位 conf/lib
AMORO_LOG_DIR(可选注入)$AMORO_HOME/logs日志目录,可用 environment: 覆盖到挂载目录
AMORO_CONF_DIR(可选注入)$AMORO_HOME/conf配置目录
JVM 堆出厂 xms=8196/xmx=8196本文经挂载 jvm.properties 覆盖为 256/512

💡 说明:AMS 的 JVM 参数不走 JAVA_OPTS/JAVA_TOOL_OPTIONS 约定,而是读 conf/jvm.properties 的 xms/xmx,所以 Compose 场景下用挂载文件的方式改堆最可靠;也可用 environment: [AMORO_CONF_DIR=/opt/amoro/conf-custom] 指向另一份配置目录。

七、配置参数说明

挂载的 config.yaml 关键段(出厂值与本文取值):

配置项出厂值本文取值说明
ams.admin-usernameadminadmin控制台与 REST Basic 认证账号
ams.admin-passwordadminq1w2e3r4首次启动初始化管理员,务必改掉出厂弱口令
ams.http-server.bind-port16301630Web 控制台 + REST 端口
ams.http-server.rest-auth-typetokentokenAPI 鉴权方式,可选 basic
ams.thrift-server.table-service.bind-port12601260表服务 Thrift 端口
ams.thrift-server.optimizing-service.bind-port12611261优化服务 Thrift 端口
ams.database.typederbyderby元数据库类型,可换 mysql/postgresql
ams.database.urljdbc:derby:/tmp/amoro/derby;create=truejdbc:derby:/opt/amoro/data/derby;create=true挂载持久化路径
containers[0].properties.export.JAVA_HOME/opt/java/opt/java/openjdk本地 optimizer 进程用的 JAVA_HOME,需与镜像实际值一致

各配置项的完整含义、连接池与自优化等高级参数,见《Apache Amoro 0.8.1-incubating 配置参数详解》。

八、配置文件挂载

本方案采用「单文件挂载」而非整个 conf 目录挂载,理由与要点:

  • config.yaml 与 jvm.properties 是仅有的两处需要定制的文件;单文件挂载能保留镜像内其余出厂配置(log4j2.xml、mysql/postgres 初始化 SQL 等)。
  • 挂载路径必须与镜像内路径一字不差:/opt/amoro/conf/config.yaml、/opt/amoro/conf/jvm.properties。
  • 修改宿主机文件后需 docker compose restart 生效;确认生效用 docker exec amoro-ams cat /opt/amoro/conf/config.yaml | grep bind-port。
docker exec amoro-ams cat /opt/amoro/conf/config.yaml | grep "bind-port: 1630"
    bind-port: 1630

九、常见问题

9.1 启动即退出:Failed to create database ... Directory already exists

现象:docker compose up -d 后容器反复重启(docker compose ps 显示 Restarting),docker logs amoro-ams 几乎无输出;在容器内跑一次前台命令可见完整报错:

java.sql.SQLException: Cannot create PoolableConnectionFactory (Failed to create database '/opt/amoro/derby', see the next exception for details.)
Caused by: org.apache.derby.iapi.error.StandardException: Directory /opt/amoro/derby already exists.

定位:derby 带 ;create=true 建库时目标目录必须不存在。把宿主机空目录(尤其是 docker 为 bind mount 自动创建的目录)直接挂到 derby 路径上必踩此坑。

解决:挂载 derby 的父目录,derby 路径指向父目录下尚不存在的子目录(本文 4.3 的 /opt/amoro/data/derby 即为此设计);若已误生成空目录,先 rmdir data/derby 再重启:

rmdir data/derby
docker compose up -d
docker compose ps
NAME        IMAGE        SERVICE    CREATED         STATUS
amoro-ams   amoro:0.8.1  amoro      5 minutes ago   Up 35 seconds

9.2 启动即退出:UnknownHostException(解析自身主机名失败)

现象:容器反复重启且 stdout 无输出,容器内日志 /opt/amoro/logs/ams-error.log 出现:

Caused by: java.net.UnknownHostException: 174f09cdb3d3: Temporary failure in name resolution
        at java.net.InetAddress.getLocalHost(InetAddress.java:1427)

定位:部分基础镜像(如 eclipse-temurin 系列)内 JDK 无法解析 docker 默认生成的随机主机名,AMS 启动时取本机地址即失败。

解决:compose 中显式声明 hostname: amoro-ams(本文 4.4 已包含),重新 docker compose up -d。

9.3 端口冲突:Bind for 0.0.0.0:1630 failed

现象:docker compose up -d 报:

Error response from daemon: failed to set up container networking: ... Bind for 0.0.0.0:1630 failed: port is already allocated

定位:宿主机 1630 已被其他进程(例如另一套按《安装指南》部署的 AMS)占用。

解决:停掉占用进程,或将 compose ports 中宿主侧端口改为其他值(如 "2630:1630"),客户端访问相应换端口。

9.4 构建期网络下载失败

现象:Dockerfile 中 RUN wget ... 报 exit code: 4(网络失败),构建中断。

定位:构建环境无法直连下载站(代理或防火墙限制)。

解决:按本文 4.2 的 COPY 方式,先在可联网机器下载好 tar.gz 放到构建目录,再 docker build(构建过程完全离线)。

9.5 内存不足或被 OOM Kill

现象:容器启动后不久退出,docker inspect amoro-ams --format '{{.State.OOMKilled}}' 为 true。

解决:确认 conf/jvm.properties 已按 4.3 限制为 xms=256/xmx=512;如宿主机内存仍紧张,可将 xmx 降到 256(-Xms256m -Xmx256m),实测空载 AMS 在 512MB 堆下稳态占用约 300MB。

十、参考链接