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 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-jdk | Amoro 支持 JDK 8/11;选 8-jdk 基础镜像,镜像内 JAVA_HOME 为 /opt/java/openjdk |
COPY ... /tmp/ | 把已下载好的发行包带进构建(比构建期 wget 更稳,离线也可构建) |
CMD ams.sh start-foreground | 前台运行,日志输出交给 docker,容器退出即服务退出 |
EXPOSE | 1630 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) |
ports | Web/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-username | admin | admin | 控制台与 REST Basic 认证账号 |
ams.admin-password | admin | q1w2e3r4 | 首次启动初始化管理员,务必改掉出厂弱口令 |
ams.http-server.bind-port | 1630 | 1630 | Web 控制台 + REST 端口 |
ams.http-server.rest-auth-type | token | token | API 鉴权方式,可选 basic |
ams.thrift-server.table-service.bind-port | 1260 | 1260 | 表服务 Thrift 端口 |
ams.thrift-server.optimizing-service.bind-port | 1261 | 1261 | 优化服务 Thrift 端口 |
ams.database.type | derby | derby | 元数据库类型,可换 mysql/postgresql |
ams.database.url | jdbc:derby:/tmp/amoro/derby;create=true | jdbc: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。