Atsumeru Docker Compose 部署指南
Atsumeru 官方 Docker 镜像(atsumerudev/atsumeru:latest,实测为 v1.1)的 Compose 全流程部署实录:镜像选型与版本落差、五卷挂载与 31337 端口、JAVA_OPT_XMX 堆限与 ps 验证、首次启动随机 Admin 口令提取与改密、CBZ 测试库导入全回显,含 401/404 排障实录(2026-11-01 实测)。
Atsumeru Docker Compose 部署指南
目标:用 Docker Compose 把 Atsumeru 官方镜像从零拉起——镜像选型(含官方镜像落后 GitHub 稳定版的版本落差说明)、五个数据卷与 31337 端口规划、JVM 堆限注入与生效验证、首次启动随机 Admin 口令提取与改密、注册导入目录并实测导入一个 CBZ 测试漫画,全部命令与回显为 2026-11-01 实测。产品定位与选型背景见 《Atsumeru 介绍与选型指南》。
一、环境信息
- 宿主机:Ubuntu 26.04.1 LTS,x86_64
- Docker:29.9.2;Docker Compose:v5.6.1
- 软件版本:Atsumeru v1.1(官方 GitHub 最新稳定版为 2.2,官方镜像未跟进,选型说明见二;版本线溯源见 《Atsumeru 介绍与选型指南》 第二章)
- 镜像:
atsumerudev/atsumeru:latest(镜像 ID16ee7196726a,本地大小 485MB,内置 Temurin OpenJDK 17.0.13+11 JRE) - 项目名:
atsumeru-11-stack(compose 显式name:,防多项目互删) - 网络:自定义 bridge
atsumeru-11-stack_atsumeru-net,子网10.89.57.0/24,服务固定地址10.89.57.10 - 端口:宿主
8138→ 服务31337(Atsumeru 默认 API 端口) - 数据目录(宿主侧,均 bind 挂载):
/opt/data/quzuo/tmp/atsumeru/{library,config,database,cache,logs} - JVM 堆限:
JAVA_OPT_XMX=-Xms256m -Xmx512m(注入位置与验证见 4.4) - 演示账号:
Admin / q1w2e3r4(随机初始口令经 4.3 改密而来;普通用户root / q1w2e3r4)
二、镜像选型说明
2.1 官方镜像与 tag 策略
Docker Hub 仓库 atsumerudev/atsumeru 实测仅有 4 个 tag(/v2/tags API,2026-11-01 查询):
| tag | 最后推送时间 | 对应程序版本 |
|---|---|---|
latest | 2025-01-15 | 1.1 |
1.1 | 2025-01-15 | 1.1 |
1.0.3 | 2023-12-21 | 1.0.3 |
1.0.2 | 2023-08-23 | 1.0.2 |
关键事实:官方镜像线停在 1.1。GitHub Releases 的 1.2/1.3/2.0/2.1/2.2(最新稳定 2.2,2026-07-08)目前只提供 Atsumeru-2.2.jar 构件,没有对应镜像。因此:
- 走 Compose/镜像 路线 = 得到 1.x 形态:无 Web 管理界面、无 Swagger-UI,管理靠 REST API + 桌面端 Atsumeru Manager;
- 走 jar 路线 = 可部署 2.2,获得 WebUI(2.0 起)与 OpenAPI 文档(1.2 起),但需要自备 Java 17+ 运行时并自行做 systemd 托管。
⚠️ 注意:生产建议用
1.1版本号 tag 替代latest锁定版本,避免未来官方突然推新latest造成不可控升级。本文实测即latest(当前等于 1.1)。
2.2 架构支持
官方 docker.html 明示镜像支持 linux/amd64、linux/arm64、linux/arm/v7(树莓派可跑),但 ARM 模式下仅支持读取 ZIP/CBZ 压缩包,PDF/DJVU 导入不可用。本文环境为 amd64,不受该限制。
三、前置条件
- 宿主机已装 Docker 20+ 与 Compose v2 插件(本机 29.9.2 / v5.6.1);
- 宿主端口未占用:
31337或计划映射端口(本机取 8138)空闲——ss -ltn | grep 8138部署前无输出; - 已规划数据目录并预建五个子目录(library/config/database/cache/logs),目录属主对容器内 root 可写;
- 若走自定义 bridge 网络,确认目标子网(本机 10.89.57.0/24)未被占用:
docker network ls无同网段冲突。
四、部署步骤
4.1 编写 compose 文件
# /opt/data/quzuo/tmp/atsumeru/compose/docker-compose.yml(实测全文)
name: atsumeru-11-stack
services:
atsumeru:
image: atsumerudev/atsumeru:latest
container_name: atsumeru-11-web
ports:
- '8138:31337'
environment:
- JAVA_OPT_XMX=-Xms256m -Xmx512m
volumes:
- '/opt/data/quzuo/tmp/atsumeru/library:/library'
- '/opt/data/quzuo/tmp/atsumeru/config:/app/config'
- '/opt/data/quzuo/tmp/atsumeru/database:/app/database'
- '/opt/data/quzuo/tmp/atsumeru/cache:/app/cache'
- '/opt/data/quzuo/tmp/atsumeru/logs:/app/logs'
networks:
atsumeru-net:
ipv4_address: 10.89.57.10
restart: unless-stopped
networks:
atsumeru-net:
driver: bridge
ipam:
config:
- subnet: 10.89.57.0/24
逐项说明:name: 显式项目名是批次硬规(防 down 误删他组件栈);ports 把默认 API 端口 31337 映射到宿主 8138;五个卷对应官方 docker.html 的挂载清单(library 书库、/app/config 配置、/app/database 双 SQLite 库、/app/cache 封面缓存、/app/logs 日志);JAVA_OPT_XMX 是镜像入口脚本识别的堆参数变量(见 4.4);restart: unless-stopped 与官方示例一致。
4.2 启动并验证服务状态
docker compose -p atsumeru-11-stack -f /opt/data/quzuo/tmp/atsumeru/compose/docker-compose.yml up -d
启动后状态实测:
$ docker compose -p atsumeru-11-stack ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
atsumeru-11-web atsumerudev/atsumeru:latest "sh -c 'java -Dserve…" atsumeru 26 minutes ago Up 26 minutes (healthy) 0.0.0.0:8138->31337/tcp, [::]:8138->31337/tcp
镜像自带健康检查,STATUS 显示 (healthy) 即为就绪。
4.3 首次启动:提取随机 Admin 口令
启动日志(节选,实测首尾):
_ _
/ \ | |_ ___ _ _ _ __ ___ ___ _ __ _ _
/ _ \| __/ __| | | | '_ ` _ \ / _ \ '__| | | |
/ ___ \ |_\__ \ |_| | | | | | | __/ | | |_| |
/_/ \_\__|___/\__,_|_| |_| |_|\___|_| \__,_|
Version: (v1.1)
2026-11-01T10:56:27.081Z INFO 7 --- [Atsumeru] [ main] xyz.atsumeru.web.AtsumeruApplication : Starting AtsumeruApplication v1.1 using Java 17.0.13 with PID 7 (/app/Atsumeru.jar started by root in /app)
2026-11-01T10:56:27.083Z INFO 7 --- [Atsumeru] [ main] xyz.atsumeru.web.AtsumeruApplication : The following 1 profile is active: "production"
2026-11-01T10:56:27.772Z INFO 7 --- [Atsumeru] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 31337 (http)
...
2026-11-01T10:56:28.022Z INFO 7 --- [Atsumeru] [ main] BooksDaoManager : Connected to books database!
2026-11-01T10:56:28.026Z WARN 7 --- [Atsumeru] [ main] ImportFolders : Unable to load folders.properties... Maybe there is no folders yet?
2026-11-01T10:56:28.027Z WARN 7 --- [Atsumeru] [ main] Settings : Unable to load atsumeru.properties. A new one will be created...
...
2026-11-01T10:56:28.379Z INFO 7 --- [Atsumeru] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 31337 (http) with context path '/'
2026-11-01T10:56:28.389Z INFO 7 --- [Atsumeru] [ main] xyz.atsumeru.web.AtsumeruApplication : Started AtsumeruApplication in 1.553 seconds (process running for 1.825)
2026-11-01T10:56:28.390Z WARN 7 --- [Atsumeru] [ main] UsersRepository : [Admin] user not found. Creating one...
2026-11-01T10:56:28.446Z INFO 7 --- [Atsumeru] [ main] UsersRepository : [Admin] user created with password = (63,_BlEAp42
两条 WARN 是首次启动的正常现象(尚无配置/导入目录)。管理员口令只打印一次,随时可回查:
docker logs atsumeru-11-web 2>&1 | grep -i password
2026-11-01T10:56:28.446Z INFO 7 --- [Atsumeru] [ main] UsersRepository : [Admin] user created with password = (63,_BlEAp42
⚠️ 排障实录(登录端点 401):Atsumeru 2.x 客户端习惯先调
POST /auth/login换 token,但 1.1 没有该端点。实测:$ curl -i -X POST http://localhost:8138/auth/login -H 'Content-Type: application/json' -d '{"login":"Admin","password":"(63,_BlEAp42"}' HTTP/1.1 401 WWW-Authenticate: Basic realm="Realm" Content-Length: 0定位:读 1.1 源码
WebSecurityConfiguration.java(jsDelivr 镜像取证),确认 1.1 仅启用httpBasic(),无 login/logout/refresh 控制器。结论:1.1 直接用 HTTP Basic 认证,curl 加-u '用户名:密码'即可,无需登录步骤。
4.4 JVM 堆限注入与生效验证
镜像入口命令实测为:
sh -c "java -Dserver.port=31337 ${JAVA_OPT_XMX} -jar Atsumeru.jar"
即堆参数经环境变量 JAVA_OPT_XMX 注入(compose 的 environment: 处修改,见 4.1);jar 直跑形态则写在 java -Xms256m -Xmx512m -jar ... 命令行。批次规范堆限 256–512MB,本文取 -Xms256m -Xmx512m。
验证一(首选 jps -v,官方镜像为 JRE 无此命令,实录如下):
$ docker exec atsumeru-11-web jps -v
OCI runtime exec failed: exec failed: unable to start container process: exec: "jps": executable file not found in $PATH
⚠️ 排障实录:
atsumerudev/atsumeru镜像基于 Temurin JRE(/opt/java/openjdk/bin下无 jps/jcmd 等 JDK 工具),jps -v在镜像内不可用。改用进程命令行验证。
验证二(实测生效值):
docker exec atsumeru-11-web ps -ef | grep '[j]ava'
root 7 1 0 10:56 ? 00:00:07 java -Dserver.port=31337 -Xms256m -Xmx512m -jar Atsumeru.jar
-Xms256m -Xmx512m 已按预期进入 JVM 命令行;docker inspect 亦可见 Env 中 JAVA_OPT_XMX=-Xms256m -Xmx512m。jar 形态在真机上可直接 jps -v(JDK 自带)看到同样的 -Xms256m -Xmx512m。
4.5 首次配置:改密与连通性验证
Atsumeru 1.x 无 Web 管理界面(浏览器打开 http://<宿主>:8138/ 只会得到 401),首次配置走 API。先验证 Basic 连通:
curl -s -u 'Admin:(63,_BlEAp42' -o /dev/null -w 'HTTP %{http_code}\n' http://localhost:8138/api/server/ping
HTTP 200
⚠️ 排障实录(端点 404):最初按直觉请求
http://localhost:8138/server/info,返回:{"type":"problemDetail.type.org.springframework.web.servlet.resource.NoResourceFoundException","title":"problemDetail.title.org.springframework.web.servlet.resource.NoResourceFoundException","status":404,"detail":"problemDetail.org.springframework.web.servlet.resource.NoResourceFoundException","instance":"/server/info"}定位:1.1 全部 REST 控制器挂载在
/api前缀下(源码ServerApiController.ROOT_ENDPOINT = "/api/server",ImporterApiController等为/api/v1/...)。结论:正确路径是/api/server/info。
把随机口令改成演示口令 q1w2e3r4(用户名保持默认 Admin):
curl -s -X PATCH -u 'Admin:(63,_BlEAp42' -H 'Content-Type: application/json' \
-d '{"id":1,"user_name":"Admin","password":"q1w2e3r4","roles":["ADMIN"],"authorities":["ROLE_ADMIN"]}' \
http://localhost:8138/api/v1/users/update
{"code":201,"message":"User successfully created"}
curl -s -u 'Admin:q1w2e3r4' -o /dev/null -w 'new-pass ping: HTTP %{http_code}\n' http://localhost:8138/api/server/ping
curl -s -u 'Admin:(63,_BlEAp42' -o /dev/null -w 'old-pass ping: HTTP %{http_code}\n' http://localhost:8138/api/server/ping
new-pass ping: HTTP 200
old-pass ping: HTTP 401
新口令生效、旧口令失效。服务端信息确认版本线:
curl -s -u 'Admin:q1w2e3r4' http://localhost:8138/api/server/info
{"name":"Atsumeru","version":"1.1","version_name":"Bohrium","has_password":true,"debug_mode":false,"stats":{"total_series":0,"total_archives":0,"total_chapters":0,"total_categories":0}}
4.6 准备测试书库并注册导入目录
在挂载的 library 卷里造一个最小 CBZ(zip 内含 3 页 PNG + ComicInfo.xml 边车元数据):
mkdir -p /opt/data/quzuo/tmp/atsumeru/library/manga/AtsumeruTestSeries
cd /opt/data/quzuo/tmp/atsumeru/library/manga/AtsumeruTestSeries
python3 - <<'EOF'
import zlib, struct, zipfile
def png(w,h,rgb):
raw=b''.join(b'\x00'+bytes(rgb)*w for _ in range(h))
def chunk(t,d):
c=t+d
return struct.pack('>I',len(d))+c+struct.pack('>I',zlib.crc32(c)&0xffffffff)
ihdr=struct.pack('>IIBBBBB',w,h,8,2,0,0,0)
return b'\x89PNG\r\n\x1a\n'+chunk(b'IHDR',ihdr)+chunk(b'IDAT',zlib.compress(raw))+chunk(b'IEND',b'')
comicinfo='''<?xml version="1.0" encoding="utf-8"?>
<ComicInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ComicInfo.xsd">
<Series>AtsumeruTestSeries</Series>
<Number>1</Number>
<Title>Volume 1</Title>
<Writer>quzuo</Writer>
<Genre>Action</Genre>
<PageCount>3</PageCount>
</ComicInfo>'''
with zipfile.ZipFile('AtsumeruTestSeries v001.cbz','w') as z:
for i,c in enumerate([(240,60,60),(60,240,60),(60,60,240)],1):
z.writestr(f'{i:03d}.png', png(64,96,c))
z.writestr('ComicInfo.xml', comicinfo)
EOF
ls -la
-rw-r--r-- 1 root root 1384 Nov 1 19:17 'AtsumeruTestSeries v001.cbz'
注册导入目录(路径是服务视角路径,即容器内挂载点 /library/manga,不是宿主路径):
curl -s -X POST -u 'Admin:q1w2e3r4' -H 'Content-Type: application/json' \
-d '{"path":"/library/manga","singles":false}' \
http://localhost:8138/api/v1/importer/add
{"code":200,"message":"Folder added"}
curl -s -u 'Admin:q1w2e3r4' http://localhost:8138/api/v1/importer/list
[{"hash":"63fe8498b2a1b0edec7c2efdc8fd3296","path":"/library/manga","singles":false,"singles_in_root":false,"singles_if_in_root_with_folders":false,"ignore_volume_numbers_detection":false,"series_count":0,"singles_count":0,"archives_count":0,"chapters_count":0}]
4.7 触发扫描并验证入库
curl -s -u 'Admin:q1w2e3r4' http://localhost:8138/api/v1/importer/scan
{"code":200,"message":"Scan started"}
curl -s -u 'Admin:q1w2e3r4' http://localhost:8138/api/v1/importer/status
{"import_active":false,"last_start_time":1793531877754,"running_ms":0,"imported":0,"total":0,"percent":0.0}
(status 的 imported=0 是因为注册目录时文件监听器已完成首轮导入,scan 无增量可导。)验证书库:
curl -s -u 'Admin:q1w2e3r4' http://localhost:8138/api/v1/books
[{"id":"atsumeru-serieb71204461360651e64a359ad591269ac","title":"Volume 1","is_single":false,"folder":"/library/manga/AtsumeruTestSeries","cover":"atsumeru36fae69422e431620cadd1b555d248c9?t=1793531877744","authors":["quzuo"],"genres":["Action"],"content_type":"UNKNOWN","is_mature":false,"is_adult":false,"pagesCount":3,"status":"ONGOING","translation_status":"UNKNOWN","plot_type":"UNKNOWN","censorship":"UNKNOWN","color":"UNKNOWN","rating":0,"created_at":1793531877744,"updated_at":1793531877744}]
ComicInfo.xml 的边车元数据(作者 quzuo、流派 Action、页数 3)已被自动解析入库。服务器统计同步更新:
curl -s -u 'Admin:q1w2e3r4' http://localhost:8138/api/server/info
{"name":"Atsumeru","version":"1.1","version_name":"Bohrium","has_password":true,"debug_mode":false,"stats":{"total_series":1,"total_archives":1,"total_chapters":0,"total_categories":1}}
取第一页图像验证阅读链路(返回 64×96 PNG):
curl -s -u 'Admin:q1w2e3r4' \
http://localhost:8138/api/v1/books/atsumeru36fae69422e431620cadd1b555d248c9/page/1 -o page1.png -w 'HTTP %{http_code} %{content_type} %{size_download}B\n'
file page1.png
HTTP 200 image/png 222B
page1.png: PNG image data, 64 x 96, 8-bit/color RGB, non-interlaced
部署至此端到端可用。
五、数据持久化说明
五个 bind 目录与容器内路径的对应关系(导入后实测宿主侧内容):
| 宿主目录 | 容器路径 | 内容(实测) |
|---|---|---|
tmp/atsumeru/library | /library | 书库原文件(本例 manga/AtsumeruTestSeries/*.cbz) |
tmp/atsumeru/config | /app/config | atsumeru.properties(服务设置)、folders.properties(导入目录注册表) |
tmp/atsumeru/database | /app/database | library.db(+-shm/-wal) 书库库、users.db 用户库(SQLite) |
tmp/atsumeru/cache | /app/cache | 封面缓存(清空后由 clear_cover_cache 重建) |
tmp/atsumeru/logs | /app/logs | import.log、requests.log(含 .lck) |
备份要点:停服后整目录打包 config/database/logs 即完成元数据备份(SQLite 的 -wal 文件必须一起拷);library 是原始内容、cache 可再生,按需取舍。
六、环境变量表
| 变量 | 实测值 | 作用 | 依据 |
|---|---|---|---|
JAVA_OPT_XMX | -Xms256m -Xmx512m | 拼入入口脚本 java ... ${JAVA_OPT_XMX} -jar Atsumeru.jar 的堆参数 | docker inspect Entrypoint + ps -ef 验证(4.4) |
JAVA_HOME | /opt/java/openjdk | 镜像内置 Temurin JRE 路径(镜像自带,勿改) | docker inspect Env |
JAVA_VERSION | jdk-17.0.13+11 | 内置运行时版本(信息性) | 同上 |
服务端口无环境变量可改:入口脚本硬编码 -Dserver.port=31337,换端口靠 compose 的 ports 宿主侧映射(本例 8138)。
七、配置文件挂载与说明
首次改设置/注册目录后,/app/config 落盘两个文件(宿主侧 cat 实测):
# config/atsumeru.properties
#Auto save properties: Sun Nov 01 11:18:52 UTC 2026
#Sun Nov 01 11:18:52 UTC 2026
allow_loading_list_with_volumes=true
allow_loading_list_with_chapters=false
disable_chapters=true
disable_file_watcher=false
disable_watch_for_modified_files=false
disable_request_logging_into_console=true
# config/folders.properties
[{"hash":"63fe8498b2a1b0edec7c2efdc8fd3296","path":"/library/manga","singles":false,"singles_in_root":false,"singles_if_in_root_with_folders":false,"ignore_volume_numbers_detection":false,"series_count":0,"singles_count":0,"archives_count":0,"chapters_count":0}]
atsumeru.properties 六个键的含义与取值建议逐项见本专栏配置详解篇;folders.properties 是导入目录注册表(JSON 数组),不建议手改,由 /api/v1/importer/add|remove 维护,手改后需重启服务生效。
八、等价 docker run
官方 docker.html 给出的等价单命令(路径与端口按本文环境替换,其余与 compose 版等价):
docker run -d \
--name=atsumeru \
-p 8138:31337 \
-e 'JAVA_OPT_XMX=-Xms256m -Xmx512m' \
-v /opt/data/quzuo/tmp/atsumeru/library:/library \
-v /opt/data/quzuo/tmp/atsumeru/config:/app/config \
-v /opt/data/quzuo/tmp/atsumeru/database:/app/database \
-v /opt/data/quzuo/tmp/atsumeru/cache:/app/cache \
-v /opt/data/quzuo/tmp/atsumeru/logs:/app/logs \
--restart unless-stopped \
atsumerudev/atsumeru:latest
差异说明:compose 版额外固定了项目名、自定义网络与容器 IP(便于多栈隔离与复查);官方原版端口写 31337:31337,本环境按端口规划取 8138。
九、常用运维命令
# 查看服务状态与健康
docker compose -p atsumeru-11-stack ps
# 跟踪日志(导入/请求排障)
docker logs -f atsumeru-11-web
# 重启服务(改手编配置后)
docker compose -p atsumeru-11-stack restart
# 升级路线 A:官方若发布新镜像,改 image tag 后重拉
docker pull atsumerudev/atsumeru:latest && docker compose -p atsumeru-11-stack up -d
# 升级路线 B:当前官方最新稳定 2.2 无镜像,需 jar 形态(Java 17+ 主机上
# java -Xms256m -Xmx512m -jar Atsumeru-2.2.jar,数据目录同构可直接迁移)
# 停栈清理(只影响本项目)
docker compose -p atsumeru-11-stack down
十、常见问题
Q1:浏览器打开管理页 401/空白? 1.1 无 WebUI,根路径全部要求 Basic 认证。管理走 API(本专栏 API 篇)或桌面端 Atsumeru Manager;要 WebUI 需 jar 部署 2.x(见二)。
Q2:Admin 密码忘了? 官方 jar.html 给出的恢复法:停服,删除 database/users.db,重启——服务端重建随机口令 Admin(打印在日志),代价是全部用户与权限丢失,多用户环境慎用;改密用 PATCH /api/v1/users/update(见 4.5)。
Q3:jps -v 报 executable file not found? 官方镜像是 JRE 不含 JDK 工具,用 docker exec <name> ps -ef | grep '[j]ava' 验证堆参数(见 4.4 排障实录)。
Q4:导入后 status 显示 imported=0? 文件监听器在目录注册时已首轮导入,scan 只处理增量,属正常(见 4.7)。
Q5:树莓派上 PDF 漫画不入库? ARM 镜像仅支持 ZIP/CBZ 读取(官方 docker.html 明示),PDF/DJVU 需 amd64 环境。
十一、参考链接
- 官方 Docker 指南:https://atsumeru.xyz/installation/docker.html (查询日期 2026-11-01)
- 官方 jar 指南:https://atsumeru.xyz/installation/jar.html (查询日期 2026-11-01)
- GitHub Releases(版本线):https://github.com/Atsumeru-xyz/Atsumeru/releases (查询日期 2026-11-01)
- Docker Hub tags:https://hub.docker.com/r/atsumerudev/atsumeru/tags (查询日期 2026-11-01)
- 同站相关:《Atsumeru 介绍与选型指南》、《Kavita 0.9.1.4 Docker Compose 部署指南》