Apprise 2.0 API Docker Compose 部署指南
用 Docker Compose 在单台服务器部署 Apprise API v2.0.2 通知网关:镜像选型(tag 无 v 前缀)、compose 全文、三目录持久化、环境变量表、配置文件挂载、等价 docker run、运维命令与 FAQ(全量实测)。
Apprise 2.0 API Docker Compose 部署指南
目标:用 Docker Compose 在单台服务器上部署 Apprise API v2.0.2 通知网关(官方镜像 caronc/apprise:2.0.2),含数据持久化、环境变量配置、发送验证、常用运维与升级方法。本文所有命令与回显均已在 Ubuntu 22.04.5 LTS(x86_64)+ Docker 29.9.2 + Docker Compose v5.6.1 环境实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(jammy),x86_64
- 容器运行时:Docker Engine 29.9.2、Docker Compose 插件 v5.6.1
- 部署目标:Apprise API v2.0.2(镜像
caronc/apprise:2.0.2,基础系统 Debian 13 trixie,内置 Python 3.14.9、Apprise 库 2.1.0) - 部署目录:
/opt/apprise-compose(compose 文件与三个数据卷目录均在其下) - Compose 项目名:
apprise-2.0.2-stack;容器名:apprise-2.0.2-server - 对外端口:8000(HTTP API 与 Web 配置管理器同端口)
二、镜像选型说明
Apprise API 官方只维护一个 Docker Hub 仓库 caronc/apprise,镜像内已打包好「nginx + gunicorn + Django」完整栈,开箱即用,是官方首推的部署形态。镜像标签规则的实测结论(2026-10-25 查询 Docker Hub):
| 标签 | 说明 |
|---|---|
2.0.2 | 当前最新稳定版(2026-10-24 推送),注意无 v 前缀 |
2 / latest | 浮动标签,当前同样指向 2.0.2 |
v2.0.0 / v1.5.4 等 | 老版本标签带 v 前缀,新旧命名风格不一致 |
edge | 开发分支滚动构建,生产勿用 |
⚠️ 注意:写
caronc/apprise:v2.0.2会报manifest ... not found——2.0.x 系列标签不带v前缀,而 1.x/2.0.0 时代带前缀,升级老部署时最容易踩这个坑。生产环境建议像本文一样锁定具体版本号,不要用latest。
拉取后镜像体积实测:
docker images caronc/apprise
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
caronc/apprise:2.0.2 6ae97e24b344 527MB 119MB U
解压后占用 527MB 磁盘(内容 119MB),预留 1GB 磁盘足够。
三、前置条件
开始部署前确认以下条件满足:
- 已安装 Docker Engine(≥ 24)与 Compose v2 插件;
- 磁盘剩余空间 ≥ 1GB;
- 8000 端口未被占用(可用
ss -ltn | grep :8000预查,被占用时改端口映射,见常见问题 Q6); - 能访问 Docker Hub 拉取镜像(拉取超时见常见问题 Q1)。
确认 Docker 与 Compose 版本:
docker --version
docker compose version
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
四、部署步骤
4.1 创建部署目录与数据卷目录
sudo mkdir -p /opt/apprise-compose/config /opt/apprise-compose/attach /opt/apprise-compose/plugin
cd /opt/apprise-compose
三个目录分别对应容器内 /config(通知通道配置)、/attach(通知附件)、/plugin(自定义通知插件)。
4.2 编写 docker-compose.yml
在 /opt/apprise-compose/docker-compose.yml 写入(全文实测可用):
name: apprise-2.0.2-stack
services:
apprise:
image: caronc/apprise:2.0.2
container_name: apprise-2.0.2-server
ports:
- "8000:8000"
environment:
APPRISE_STATEFUL_MODE: simple
APPRISE_WORKER_COUNT: "1"
APPRISE_DEFAULT_FORMAT: text
TZ: Asia/Shanghai
volumes:
- /opt/apprise-compose/config:/config
- /opt/apprise-compose/attach:/attach
- /opt/apprise-compose/plugin:/plugin
restart: unless-stopped
逐项说明:
| 配置项 | 取值 | 说明 |
|---|---|---|
| name | apprise-2.0.2-stack | Compose 项目名,决定网络/卷等资源前缀 |
| image | caronc/apprise:2.0.2 | 锁定稳定版,不用浮动标签 |
| container_name | apprise-2.0.2-server | 固定容器名,便于运维命令定位 |
| ports | 8000:8000 | 宿主 8000 映射到容器 8000 |
| APPRISE_STATEFUL_MODE | simple | 配置键直接对应 /config/{key}.cfg 纯文本文件,可读可手工编辑 |
| APPRISE_WORKER_COUNT | "1" | gunicorn worker 数;默认 CPU×2+1,小规格机器显式调小 |
| APPRISE_DEFAULT_FORMAT | text | 通知正文默认按纯文本处理(可选 text/markdown/html) |
| TZ | Asia/Shanghai | 容器时区 |
| volumes | 三目录挂载 | 配置、附件、插件持久化到宿主 |
| restart | unless-stopped | 开机与异常退出自动拉起 |
💡 技术拓展:有状态存储策略
APPRISE_STATEFUL_MODE三档对比——
模式 配置键与文件的映射 适用 hash 键名经哈希映射到存储文件,目录不暴露键名(默认值) 键名可能含敏感信息时 simple 键名直接对应 {key}.cfg文件小团队,追求可读可手工编辑 disabled 关闭有状态,仅保留无状态 /notify纯转发场景,零存储 本文采用 simple 档:配置文件可读、可直接备份与手工修复。
4.3 启动并验证
cd /opt/apprise-compose
docker compose up -d
Network apprise-202-stack_default Creating
Network apprise-202-stack_default Created
Container apprise-2.0.2-server Creating
Container apprise-2.0.2-server Created
Container apprise-2.0.2-server Starting
Container apprise-2.0.2-server Started
⚠️ 注意:compose 项目名
apprise-2.0.2-stack中的点号会被 Compose 规范化剔除,实际创建的网络名是apprise-202-stack_default(docker compose config可见name: apprise-202-stack)。用docker network ls找不到带点的网络名是正常现象,不是部署失败。
确认容器状态与端口映射:
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
apprise-2.0.2-server caronc/apprise:2.0.2 "/opt/apprise/webapp…" apprise 28 minutes ago Up 28 minutes 0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp
健康检查(纯文本与 JSON 两种形式):
curl -s http://127.0.0.1:8000/status
curl -s -H "Accept: application/json" http://127.0.0.1:8000/status
OK
{"config_lock": false, "attach_lock": false, "stateful_enabled": true, "stateless_enabled": true, "degraded": false, "max_attachments": 6, "attach_size": 209715200, "status": {"persistent_storage": true, "can_write_config": true, "can_write_attach": true, "details": ["OK"]}, "privilege": "admin"}
stateful_enabled/stateless_enabled 均为 true、persistent_storage 为 true,说明双模通知与持久化卷都正常。浏览器访问 http://192.168.1.10:8000/ 打开 Web 配置管理器。
4.4 端到端发送验证
先保存一个有状态配置键 myalerts(指向一个 JSON Webhook 接收端),再通过它发通知。这里用本机 8433 端口的临时 HTTP 接收器充当通知目标(把下面脚本存为 /root/webhook_receiver.py,用 nohup python3 /root/webhook_receiver.py > /var/log/webhook-receiver.log 2>&1 & 后台运行):
from http.server import BaseHTTPRequestHandler, HTTPServer
class H(BaseHTTPRequestHandler):
def do_POST(self):
l = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(l)
print("RECEIVED path=%s body=%s" % (self.path, body.decode()), flush=True)
self.send_response(200)
self.end_headers()
self.wfile.write(b"{}")
def log_message(self, *a):
pass
HTTPServer(("0.0.0.0", 8433), H).serve_forever()
保存配置键(json:// 是通用 JSON Webhook 通道,把通知以 JSON POST 到目标地址;192.168.1.10 为接收器所在机器的示例地址,换成你的实际地址,注意该地址需从容器内可达——接收器在宿主机上时用宿主局域网 IP,不能用 127.0.0.1,那指向容器自身):
curl -s -X POST -H "Content-Type: application/json" \
-d '{"urls": "json://192.168.1.10:8433/hook"}' \
http://127.0.0.1:8000/add/myalerts
{"error": null}
通过该配置键发送一条 markdown 格式通知:
curl -s -X POST "http://127.0.0.1:8000/notify/myalerts?format=markdown" \
--data-urlencode "body=**B2 持久化验证**:容器重启后通知通道正常"
2026-10-25 03:12:06,618 - INFO - Notifying 1 service(s).
2026-10-25 03:12:06,626 - INFO - Sent JSON POST notification.
接收器日志确认投递内容:
tail -1 /var/log/webhook-receiver.log
RECEIVED path=/hook body={"version": "1.0", "title": "", "message": "**B2 持久化验证**:容器重启后通知通道正常", "attachments": [], "type": "info"}
至此部署完成:8000 端口对外提供 API 与 Web 管理器,通知可正常投递。
五、数据持久化说明
三个挂载目录的分工与实测落盘形态:
| 宿主目录 | 容器内 | 内容 |
|---|---|---|
| /opt/apprise-compose/config | /config | 有状态配置(每键一个 {key}.cfg + 标记文件 + store/ 状态存储区) |
| /opt/apprise-compose/attach | /attach | 通知附件上传 |
| /opt/apprise-compose/plugin | /plugin | 自定义通知插件(Python 文件) |
4.4 保存配置键后,宿主侧实际落盘:
ls -la /opt/apprise-compose/config/
cat /opt/apprise-compose/config/myalerts.cfg
total 16
drwxr-xr-x 3 1000 1000 4096 Oct 25 03:41 .
drwxr-xr-x 6 root root 4096 Oct 25 02:47 ..
-rw------- 1 1000 1000 0 Oct 25 02:47 .auth.guard
-rw------- 1 1000 1000 0 Oct 25 03:11 .myalerts.created
-rw------- 1 1000 1000 86 Oct 25 03:11 myalerts.cfg
drwxr-xr-x 3 1000 1000 4096 Oct 25 02:48 store
json://192.168.1.10:8433/hook?method=POST&overflow=upstream&retry=0&wait=0.5&optional=no
要点解读:
myalerts.cfg是纯文本 Apprise URL 列表(每行一条),可直接用编辑器修改,权限 600。- 文件属主显示为
1000:1000——容器内运行用户是apprise(uid 1000),宿主侧若无同名用户则显示数字。宿主上直接编辑后注意保持该属主,否则容器内可能读不到。 .myalerts.created是键创建标记、.auth.guard是认证保护标记、store/是发送状态存储区,均属正常运行产物,不要手工删除。
实测验证持久化:执行 docker compose down 再 docker compose up -d(命令回显见第十章),配置键 myalerts 完整保留、可直接继续发通知——配置安全取决于宿主目录而非容器生命周期。
六、环境变量表
Apprise API 服务端全部由环境变量配置,compose 的 environment: 段注入。本节列出部署最常用的变量(完整清单与全部默认值见本专栏《Apprise API 2.0 配置参数详解》):
| 环境变量 | 默认值 | 本文取值 | 说明 |
|---|---|---|---|
| APPRISE_STATEFUL_MODE | hash | simple | 有状态存储策略:hash/simple/disabled |
| APPRISE_STATELESS_MODE | enabled | (默认) | 无状态 /notify 开关 |
| APPRISE_WORKER_COUNT | CPU×2+1 | 1 | gunicorn worker 数 |
| APPRISE_WORKER_TIMEOUT | 300 | (默认) | worker 超时秒数 |
| APPRISE_DEFAULT_FORMAT | 空 | text | 通知正文默认格式:text/markdown/html |
| APPRISE_ATTACH_SIZE | 200 | (默认) | 附件总大小上限(MB) |
| APPRISE_MAX_ATTACHMENTS | 6 | (默认) | 单请求附件数上限 |
| APPRISE_CONFIG_DIR | 镜像内置 /config | (默认) | 配置目录(官方镜像已内置,无需显式声明) |
| APPRISE_ATTACH_DIR | 镜像内置 /attach | (默认) | 附件目录(同上) |
| APPRISE_PLUGIN_PATHS | 镜像内置 /plugin | (默认) | 插件扫描路径(同上) |
| APPRISE_AUTH_REQUIRED | no | (默认) | 是否启用全局 Basic Auth(yes/no) |
| APPRISE_USER / APPRISE_PASSWORD | 空 | (按需) | 全局管理员账号密码 |
| APPRISE_ADMIN | yes | (默认) | 是否启用 Web 配置管理器 |
| ALLOWED_HOSTS | * | (默认) | 允许的 Host 头,生产建议改为实际域名 |
| TZ | Etc/UTC | Asia/Shanghai | 时区 |
⚠️ 注意:
APPRISE_CONFIG_DIR等三个路径变量在官方镜像 Dockerfile 中已内置,容器内实测可见——即使 compose 不显式声明也生效:
docker exec apprise-2.0.2-server env | grep APPRISE | sort
APPRISE_ATTACH_DIR=/attach
APPRISE_CONFIG_DIR=/config
APPRISE_DEFAULT_FORMAT=text
APPRISE_PLUGIN_PATHS=/plugin
APPRISE_STATEFUL_MODE=simple
APPRISE_WORKER_COUNT=1
生产环境建议补开全局认证(演示账号 admin / q1w2e3r4):
environment:
APPRISE_AUTH_REQUIRED: "yes"
APPRISE_USER: admin
APPRISE_PASSWORD: q1w2e3r4
七、配置参数说明
本文 compose 用到的 4 个显式变量:
- APPRISE_STATEFUL_MODE=simple:选择 simple 后,配置键与
/config/{key}.cfg一一对应,便于备份(直接tar打包 config 目录)与灾难恢复(把文件放回即可)。 - APPRISE_WORKER_COUNT=1:单容器单核小规格部署时,默认值 CPU×2+1 会拉起过多 gevent worker、白白占内存;1~2 个 worker 足够支撑告警类低频流量。大流量再按 CPU 核数上调。
- APPRISE_DEFAULT_FORMAT=text:未显式声明格式的通知按纯文本处理,避免调用方漏传
format时行为不一致。 - TZ=Asia/Shanghai:影响通知模板时间戳与日志时间。
修改任何环境变量后,需要 docker compose up -d 重建容器才生效(restart 不重读 compose 文件),完整参数语义与调优见《Apprise API 2.0 配置参数详解》。
八、配置文件挂载
simple 模式下配置目录是纯文本文件,因此支持「绕开 API、直接挂配置」的用法:把预先写好的 {key}.cfg 放进 ./config 目录即可被服务读取。例如手工创建:
echo 'json://192.168.1.10:8433/hook' | sudo tee /opt/apprise-compose/config/direct.cfg
sudo chown 1000:1000 /opt/apprise-compose/config/direct.cfg
sudo chmod 600 /opt/apprise-compose/config/direct.cfg
通过 API 读回验证(无需重启,请求时实时读盘):
curl -s http://127.0.0.1:8000/json/urls/direct
{"tags": [], "urls": [{"id": "0b765814", "service_name": "JSON", "enabled": true, "url": "json://192.168.1.10:8433/hook?method=POST&overflow=upstream&retry=0&wait=0.5&optional=no", "retry": 0, "optional": false, "tags": [], "tag_details": [], "template": {}}]}
⚠️ 注意:手工写入的文件属主必须是容器内 apprise 用户的 uid 1000(
chown 1000:1000),权限建议 600;属主不对时 API 读取会报权限错误或读不到配置。批量迁移配置时此方式比逐条调 API 高效。
九、等价 docker run
不用 Compose 时,与本文 compose 文件完全等价的单命令形态:
docker run -d --name apprise-2.0.2-server \
-p 8000:8000 \
-e APPRISE_STATEFUL_MODE=simple \
-e APPRISE_WORKER_COUNT=1 \
-e APPRISE_DEFAULT_FORMAT=text \
-e TZ=Asia/Shanghai \
-v /opt/apprise-compose/config:/config \
-v /opt/apprise-compose/attach:/attach \
-v /opt/apprise-compose/plugin:/plugin \
--restart unless-stopped \
caronc/apprise:2.0.2
二者选其一即可。Compose 的优势在于配置即代码(环境变量、卷、重启策略都在 yml 里可评审、可版本化),升级与重建只需 up -d;docker run 适合一次性临时验证。
十、常用运维命令
以下命令均在 /opt/apprise-compose 目录下执行,回显为实测结果。
实时跟踪日志:
docker compose logs -f
apprise-2.0.2-server | 2026-10-25 11:12:06,618 [INFO] apprise: Notifying 1 service(s).
apprise-2.0.2-server | 2026-10-25 11:12:06,626 [INFO] apprise: Sent JSON POST notification.
apprise-2.0.2-server | 2026-10-25 11:12:06,627 [INFO] django: NOTIFY - - Delivered Notification(s) - KEY: myalerts
重启服务(不重读 compose 文件):
docker compose restart
Container apprise-2.0.2-server Restarting
Container apprise-2.0.2-server Started
停止并清理(数据卷目录保留在宿主,配置不丢):
docker compose down
Container apprise-2.0.2-server Stopping
Container apprise-2.0.2-server Stopped
Container apprise-2.0.2-server Removing
Container apprise-2.0.2-server Removed
Network apprise-202-stack_default Removing
Network apprise-202-stack_default Removed
重新拉起:
docker compose up -d
Network apprise-202-stack_default Creating
Network apprise-202-stack_default Created
Container apprise-2.0.2-server Creating
Container apprise-2.0.2-server Created
Container apprise-2.0.2-server Starting
Container apprise-2.0.2-server Started
进容器排查(镜像基于 Debian 13,自带 curl/python3,无 wget):
docker exec -it apprise-2.0.2-server /bin/bash
升级版本:修改 yml 中 image 标签后拉取并重建(当前已是最新时的实测回显):
docker compose pull
docker compose up -d
Image caronc/apprise:2.0.2 Pulling
Image caronc/apprise:2.0.2 Pulled
备份配置(纯文本目录直接打包即可):
sudo tar czf /root/apprise-config-$(date +%F).tar.gz -C /opt/apprise-compose config
十一、常见问题
Q1:docker compose pull 拉取镜像超时或失败?
A:国内服务器直连 Docker Hub 不稳定。方案一配置镜像加速器(/etc/docker/daemon.json 加 registry-mirrors 后 systemctl restart docker);方案二给 Docker 守护进程配 HTTP 代理(/etc/docker/systemd/ 下 drop-in 注入 HTTP_PROXY/HTTPS_PROXY 环境变量)。改完重试 docker compose pull。
Q2:拉取报 manifest for caronc/apprise:v2.0.2 not found?
A:2.0.x 系列标签不带 v 前缀,正确写法是 caronc/apprise:2.0.2。注意老版本(v2.0.0、v1.5.4)反而带前缀,命名风格不一致,以 Docker Hub 标签页为准。
Q3:docker network ls 里找不到 apprise-2.0.2-stack_default?
A:Compose 会规范化项目名(剔除点号等特殊字符),本文项目实际网络名是 apprise-202-stack_default。可用 docker compose config 查看规范化后的项目名,属正常行为。
Q4:通知 URL 里的目标主机名报 Unparseable URL 类错误?
A:实测发现 Apprise URL 解析器对某些含多段点号的非标主机名(如内部测试机名)解析失败。把主机名换成 IP 地址或标准 FQDN(如 hooks.example.com)即可正常解析投递;生产环境目标地址建议一律用标准域名或 IP。
Q5:改了 compose 文件里的环境变量,重启后不生效?
A:docker compose restart 只重启进程、不重读 yml。必须 docker compose up -d,Compose 检测到配置变化后自动重建容器。
Q6:8000 端口被占用?
A:改 ports 映射左侧端口,如 "18000:8000",然后 docker compose up -d;调用方相应改访问端口。
十二、参考链接
- Apprise API 源码仓库:https://github.com/caronc/apprise-api
- Docker Hub 镜像页:https://hub.docker.com/r/caronc/apprise
- 官方安装文档:https://appriseit.com/getting-started/
- 支持的通知服务目录:https://appriseit.com/services/
- 本专栏相关文档:《Apprise 介绍与选型指南》、《Ubuntu 22.04 安装 Apprise API 2.0 指南》、《Apprise API 2.0 配置参数详解》、《Apprise API 2.0 API 使用详解》