GlobaLeaks 5.0.99 Docker Compose 部署指南

用 Docker Compose 部署 GlobaLeaks 5.0.99:官方镜像锁定、compose 项目名与端口/网络/数据卷配置、环境变量、首次初始化、测试举报验收、等价 docker run、运维命令与排障(2026-10-26 实测)。

GlobaLeaksGlobaLeaks匿名举报TorDebian 122026/10/26

GlobaLeaks 5.0.99 Docker Compose 部署指南

目标:用 Docker Compose 部署 GlobaLeaks 5.0.99,完成端口映射、数据持久化、首次初始化、管理员登录与测试举报验收,并给出等价 docker run、运维命令与排障方法。以下命令与回显均来自 Docker 29.9.2 + Compose 5.6.1 实测(2026-10-26),镜像为 Docker Hub 官方 globaleaks/globaleaks:v5.0.99。

一、环境信息

  • 宿主机:Linux x86_64
  • Docker Engine:29.9.2
  • Docker Compose:5.6.1
  • 镜像:globaleaks/globaleaks:v5.0.99
    • 镜像 ID:sha256:1a4b6dddcf16ea8d99dda9d6ba7fa58af6e95dc81678cc0ed16e2a1a2269c789
    • 大小:742,095,288 字节(约 708 MiB)
    • 构建时间:2026-07-26T09:57:12Z(与 GitHub v5.0.99 发布同日)
    • 基础系统:Debian trixie;Python 3.13.5;Twisted 24.11.0
    • 默认用户:UID/GID 1000:1000(globaleaks)
    • 暴露端口:8080/tcp(HTTP)、8443/tcp(HTTPS)
  • Compose 项目名:globaleaks-5.0.99-stack
  • 自定义网络:globaleaks-5.0.99-net,子网 10.89.74.0/24,容器地址 10.89.74.10
  • 宿主端口:8142 → 8080、8143 → 8443
  • 数据卷:宿主目录挂载到容器内 /var/globaleaks

💡 说明:官方镜像与 Debian 包是同一套代码,globaleaks/globaleaks:v5.0.99 在 Docker Hub 上与 latest 指向同一 digest(查询日 2026-10-26),生产环境务必锁定 v5.0.99 而不是 latest。

二、镜像选型说明

Docker Hub 上 globaleaks/globaleaks 仓库共 84 个标签(含历史版本),当前版本线为 5.0.x:

标签更新时间用途
v5.0.992026-07-26本文采用的稳定版本
latest2026-07-26与 v5.0.99 同 digest,仅适合试用
v5.0.982026-07-16上一补丁版,用于回滚对照
v5.0.962026-06-28更早补丁版

选型要点:

  • 生产锁定 v5.0.99:latest 会随上游发布漂移,重建容器时可能被动升级,而 GlobaLeaks 升级会触发数据库迁移,需先备份。
  • 只从官方仓库拉取:第三方重打包版本无法保证签名与构建可复现性;拉取后用 docker image inspect 核对 RepoDigests。
  • 镜像体积约 708 MiB:包含 Tor、Twisted、Python 运行时与前端资源,属于自包含设计,不需要额外的数据库容器。

三、前置条件

3.1 宿主资源与端口

  • 最低配置与官方要求一致:双核 2.0GHz、1GB 内存、20GB 磁盘;镜像与数据卷建议预留 5GB 以上。
  • 宿主 8142、8143 未被占用(本文使用 8142/8143,避免与宿主既有 80/443 服务冲突):
ss -lntp | grep -E ':(8142|8143)\s'
(无输出表示两个端口均空闲)

3.2 拉取镜像

docker pull globaleaks/globaleaks:v5.0.99

docker image inspect globaleaks/globaleaks:v5.0.99 \
  --format '{{json .RepoDigests}}'
["globaleaks/globaleaks@sha256:1a4b6dddcf16ea8d99dda9d6ba7fa58af6e95dc81678cc0ed16e2a1a2269c789"]

说明:RepoDigests 中的 digest 与本文第一章的镜像 ID 一致,说明拉取的是官方仓库对应版本。若拉取被镜像加速器拦截(报错含 this image is not in the allowlist),改用可直连 Docker Hub 的网络或更换加速器后重试。

3.3 准备数据目录

容器内进程以 UID 1000 运行,宿主目录必须可写,否则启动时报权限错误:

mkdir -p /srv/globaleaks/data
chown 1000:1000 /srv/globaleaks/data
chmod 700 /srv/globaleaks/data
stat -c '%a %u:%g %n' /srv/globaleaks/data
700 1000:1000 /srv/globaleaks/data

⚠️ 注意:目录权限必须是 700 且属主为 1000。GlobaLeaks 会在其中保存数据库、Tor 密钥与附件,权限放宽会削弱匿名性。

四、部署步骤

4.1 编写 compose 文件

在 /srv/globaleaks/ 下创建 docker-compose.yml:

name: globaleaks-5.0.99-stack

services:
  globaleaks:
    image: globaleaks/globaleaks:v5.0.99
    container_name: globaleaks-5.0.99-b2
    restart: unless-stopped
    command: ["/usr/lib/globaleaks/globaleaks-exec"]
    ports:
      - "8142:8080"
      - "8143:8443"
    volumes:
      - /srv/globaleaks/data:/var/globaleaks
    environment:
      TZ: Asia/Shanghai
      APPARMOR_SANDBOXING: "0"
      LISTENING_IP: "::"
      WORKING_DIR: /var/globaleaks/
    networks:
      globaleaks-net:
        ipv4_address: 10.89.74.10

networks:
  globaleaks-net:
    name: globaleaks-5.0.99-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.74.0/24

逐项说明:

  • name:Compose 顶层项目名,固定为 globaleaks-5.0.99-stack,决定容器、网络、卷的命名前缀与后续 docker compose -p 的默认值。
  • command:覆盖镜像默认 CMD,改用官方启动包装脚本 globaleaks-exec,它读取 LISTENING_IP、WORKING_DIR、APPARMOR_SANDBOXING 三个环境变量。
  • ports:左侧为宿主端口、右侧为容器端口;8080 只做 HTTPS 跳转,对外真正使用的是 8443。
  • volumes:宿主 /srv/globaleaks/data 挂到容器 /var/globaleaks,所有状态都落在这里。
  • restart: unless-stopped:宿主重启后自动拉起,人工 stop 后不自动恢复。
  • networks:显式命名并固定子网,便于后续接入反向代理或监控容器。

4.2 启动栈

docker compose -f /srv/globaleaks/docker-compose.yml up -d
 Container globaleaks-5.0.99-b2 Creating
 Container globaleaks-5.0.99-b2 Created
 Container globaleaks-5.0.99-b2 Starting
 Container globaleaks-5.0.99-b2 Started

查看状态:

docker compose -f /srv/globaleaks/docker-compose.yml ps
NAME                   IMAGE                           COMMAND                  SERVICE      CREATED          STATUS          PORTS
globaleaks-5.0.99-b2   globaleaks/globaleaks:v5.0.99   "/usr/lib/globaleaks…"   globaleaks   12 seconds ago   Up 12 seconds   0.0.0.0:8142->8080/tcp, [::]:8142->8080/tcp, 0.0.0.0:8143->8443/tcp, [::]:8143->8443/tcp

状态为 Up 且两个端口映射齐全即表示容器已运行;COMMAND 列显示的是包装脚本而非 Python 直接启动,说明 4.1 的 command 覆盖生效。

4.3 启动日志确认

docker compose -f /srv/globaleaks/docker-compose.yml logs --tail=12
2026-10-26T09:29:39+0800 [twisted.scripts._twistd_unix.UnixAppLogger#info] twistd 24.11.0 (/usr/bin/python3 3.13.5) starting up.
2026-10-26T09:29:39+0800 [twisted.scripts._twistd_unix.UnixAppLogger#info] reactor class: twisted.internet.epollreactor.EPollReactor.
2026-10-26T09:29:39+0800 [builtins.Site#info] Starting factory <Site object at 0x734f945e4050>
2026-10-26T09:29:39+0800 [stdout#info] [E] Failed to initialize Tor connection; error: Tor control port not open on /var/globaleaks/tmp/tor_control; waiting for Tor to become available
2026-10-26T09:29:39+0800 [stdout#info] GlobaLeaks is now running and accessible at the following urls:
2026-10-26T09:29:39+0800 [stdout#info] - [HTTPS]: https://0.0.0.0
2026-10-26T09:29:39+0800 [stdout#info] - [Tor]:  http://gpg6dcwamlv3pdz3i65dqiiwjz5orcvm6yc62ojkgffyxywszjdu3nid.onion

日志里同时给出 HTTPS 入口与 onion 地址。Tor control port not open 是首次启动的过渡告警,Tor 引导完成后会自行消失,不影响 HTTPS 通道。

4.4 端口连通性验证

curl -s -o /dev/null -w "http=%{http_code}\n" http://127.0.0.1:8142/
curl -k -s -o /dev/null -w "https=%{http_code}\n" https://127.0.0.1:8143/
http=301
https=200
  • 301:HTTP 入口按设计跳转到 HTTPS;
  • 200:HTTPS 入口可正常返回页面;
  • 容器网络地址为 10.89.74.10,与 4.1 中固定地址一致。

4.5 首次初始化向导

浏览器访问 https://<宿主机IP>:8143,按六步向导完成:选择语言 → 站点名称 → 管理员账号(admin / q1w2e3r4)→ 首个受理人账号(recipient / q1w2e3r4)→ 接受许可证 → 完成。

向导提交后接口返回 201(实测):

wizard: 201 {}

初始化完成后,公开接口会从「无可用渠道」变为 1 个渠道、1 个受理人:

public: 200 contexts: 1 receivers: 1

4.6 管理员登录与验收

登录管理员账号并读取节点信息:

docker compose -f /srv/globaleaks/docker-compose.yml exec -u root globaleaks \
  python3 /root/admin_check.py
login -> OK role: admin id: 9ecb677616e356e7c753f30b506d972a3a27c0896487c498a2868faada765b6d
GET /api/admin/node -> 200 version: 5.0.99 name: GlobaLeaks Demo

提交一条测试举报后,管理员收件箱应出现对应记录:

tips -> 200 [{"id": "6d247b56-6a02-4ec5-a88d-05b3f2d144ac", "progressive": 1, "creation_date": "2026-10-26T01:30:14.623585Z", "last_update": "2026-10-26T01:30:14.623588Z", "expiration_date": "2027-01-24T23:59:59Z", "context_id": "7e0b7878-c900-4c19-a017-d92570b89a3f", "status": "new", "substatus": null, "tor": false, "comments": 0, "files": 0, "receiver_count": 1, "last_access": "2026-10-26T01:30:14.623590Z"}]

验收判据:status=new 表示新举报入队;expiration_date 为 2027-01-24,对应默认 90 天保留期;receiver_count=1 表示已绑定向导创建的受理人。提交动作本身返回:

2) POST /api/whistleblower/submission -> 201
    {}

💡 说明:admin_check.py 是验收辅助脚本,仅调用平台 REST API,不属于 GlobaLeaks 自带命令;日常运维可直接使用 Web 管理后台,无需该脚本。

五、数据持久化说明

所有状态位于容器内 /var/globaleaks,本文通过宿主目录绑定挂载持久化。验证方式:重启容器后检查举报记录是否仍在。

docker compose -f /srv/globaleaks/docker-compose.yml restart
 Container globaleaks-5.0.99-b2 Restarting
 Container globaleaks-5.0.99-b2 Started
tips -> 200 [{"id": "6d247b56-6a02-4ec5-a88d-05b3f2d144ac", "creation_date": "2026-10-26T01:30:14.623585Z", "status": "new", ...}]

重启后 tip ID、创建时间、状态完全一致,说明数据库已落在宿主目录而非容器可写层。

目录内容说明:

路径(容器内)内容是否必须持久化
/var/globaleaks/globaleaks.dbSQLite 数据库:站点配置、用户、举报、审计日志必须
/var/globaleaks/tmp/Tor 控制/SOCKS 套接字与临时文件建议(重启自动重建)
/var/globaleaks/ 其余子目录附件、onion 密钥、备份必须

⚠️ 注意:不要用匿名卷或 docker compose down -v 清理数据。删除数据卷等同于销毁全部举报与加密密钥,且无法恢复。

六、环境变量表

镜像默认只带 PATH 与 DEBIAN_FRONTEND 两个变量,业务行为由 4.1 的 environment 注入:

变量本文取值作用默认
TZAsia/Shanghai容器时区,影响日志时间与通知时间戳UTC
APPARMOR_SANDBOXING0是否启用 AppArmor 强制沙箱;1 会在 aa-status --enabled 失败时以退出码 78 退出1
LISTENING_IP::监听地址,:: 表示双栈::
WORKING_DIR/var/globaleaks/数据目录,必须与挂载点一致/var/globaleaks/

逐项说明与取舍:

  • APPARMOR_SANDBOXING=0 是容器部署的必要妥协:容器内通常没有加载宿主 AppArmor 策略,包装脚本检测到 aa-status 不可用会直接退出(日志 GlobaLeaks Apparmor Sandboxing Failure: requires apparmor)。若宿主机已加载 /etc/apparmor.d/usr.bin.globaleaks,可改为 1 并追加 security_opt: ["apparmor=usr.bin.globaleaks"] 恢复沙箱。
  • WORKING_DIR 必须与 volume 目标一致:改成其他路径而未挂载会导致数据写入容器可写层,重启即丢失。
  • TZ 只影响展示:数据库内时间统一为 UTC,修改时区不会改变已存储记录。
  • 端口不可通过环境变量修改:端口由镜像 EXPOSE 8080/8443 与应用程序固定监听决定,只能改宿主侧映射。

七、配置参数说明

Compose 层的关键参数(与业务配置无关,业务配置在管理后台):

参数本文取值说明
imageglobaleaks/globaleaks:v5.0.99锁定版本,避免漂移
container_nameglobaleaks-5.0.99-b2固定容器名,便于日志与 exec 定位
restartunless-stopped异常退出与宿主重启自动恢复
ports8142:8080、8143:8443宿主端口可按需替换,容器端口不可改
volumes/srv/globaleaks/data:/var/globaleaks唯一状态目录
networks.ipv4_address10.89.74.10固定地址,便于反向代理指向
command/usr/lib/globaleaks/globaleaks-exec启用环境变量解析与可选 AppArmor

业务配置(站点名、语言、通知、保留策略、Tor、证书等)存储在 /var/globaleaks/globaleaks.db,通过管理后台修改,不存在可挂载的 globaleaks.conf。这一点在配置篇会逐项展开。

八、配置文件挂载

容器部署下只有两类文件值得挂载:

  1. 数据目录:/var/globaleaks(本文已挂载),承载数据库、密钥与附件。
  2. 自定义 TLS 证书:若使用企业 CA 证书,可把证书与私钥放入数据目录外的只读目录,再通过管理后台粘贴证书内容(平台把证书保存在数据库中,不读取固定路径文件)。

示例:只读挂载证书目录,便于在后台粘贴时取用:

    volumes:
      - /srv/globaleaks/data:/var/globaleaks
      - /srv/globaleaks/certs:/srv/certs:ro

⚠️ 注意:不要挂载空的宿主目录覆盖 /var/globaleaks(例如误挂 /srv/globaleaks/empty),容器内权限会变为 root 所有,UID 1000 无法写库,表现为启动即退出。

九、等价 docker run

不使用 Compose 时,等价命令如下(网络需提前创建):

docker network create --subnet 10.89.74.0/24 globaleaks-5.0.99-net

docker run -d \
  --name globaleaks-5.0.99-b2 \
  --restart unless-stopped \
  --network globaleaks-5.0.99-net --ip 10.89.74.10 \
  -p 8142:8080 -p 8143:8443 \
  -v /srv/globaleaks/data:/var/globaleaks \
  -e TZ=Asia/Shanghai \
  -e APPARMOR_SANDBOXING=0 \
  -e LISTENING_IP=:: \
  -e WORKING_DIR=/var/globaleaks/ \
  globaleaks/globaleaks:v5.0.99 \
  /usr/lib/globaleaks/globaleaks-exec

两者差异:Compose 负责项目命名、依赖顺序与一键重建;docker run 需手工管理网络与容器名。验证方式一致:

docker ps --filter name=globaleaks-5.0.99-b2 --format '{{.Names}} {{.Status}} {{.Ports}}'
globaleaks-5.0.99-b2 Up 12 seconds 0.0.0.0:8142->8080/tcp, [::]:8142->8080/tcp, 0.0.0.0:8143->8443/tcp, [::]:8143->8443/tcp

十、常用运维命令

10.1 服务生命周期

# 查看状态
docker compose -f /srv/globaleaks/docker-compose.yml ps

# 跟踪日志
docker compose -f /srv/globaleaks/docker-compose.yml logs -f --tail=50

# 重启
docker compose -f /srv/globaleaks/docker-compose.yml restart

# 停止并移除容器(保留数据目录)
docker compose -f /srv/globaleaks/docker-compose.yml down
NAME                   IMAGE                           COMMAND                  SERVICE      CREATED          STATUS          PORTS
globaleaks-5.0.99-b2   globaleaks/globaleaks:v5.0.99   "/usr/lib/globaleaks…"   globaleaks   12 seconds ago   Up 12 seconds   0.0.0.0:8142->8080/tcp, [::]:8142->8080/tcp, 0.0.0.0:8143->8443/tcp, [::]:8143->8443/tcp

10.2 容器内命令

# 版本确认
docker compose -f /srv/globaleaks/docker-compose.yml exec globaleaks /usr/bin/globaleaks --version
GlobaLeaks version: 5.0.99
Database version: 68

输出节选(实测尾部):命令前还会打印两条平台推荐与升级提示,属正常警告。

# 读取数据库中的配置项(CLI 工具 gl-admin)
docker compose -f /srv/globaleaks/docker-compose.yml exec -u 1000 globaleaks \
  /usr/bin/gl-admin getvar -w /var/globaleaks version
5.0.99

💡 说明:gl-admin 以 UID 1000 运行才能读写数据库;以 root 运行会因文件属主不匹配而失败。CLI 的完整子命令与参数见《GlobaLeaks 5.0.99 常用 CLI 命令与工具详解》。

10.3 备份与恢复

# 停机备份(保证数据库一致)
docker compose -f /srv/globaleaks/docker-compose.yml stop
tar -zcf /srv/globaleaks/backup-$(date +%F).tar.gz -C /srv/globaleaks/data .
docker compose -f /srv/globaleaks/docker-compose.yml start
ls -lh /srv/globaleaks/backup-$(date +%F).tar.gz
tar: ./tmp/tor_control: socket ignored
tar: ./tmp/tor_socks: socket ignored
-rw-r--r-- 1 root root 140K Oct 26 09:32 /srv/globaleaks/backup-2026-10-26.tar.gz

说明:socket ignored 是 tar 对运行中 Tor 套接字的正常提示,这两个套接字重启后会自动重建,不影响备份可用性。

恢复时先 stop,清空 /srv/globaleaks/data 后解包,再 start。备份包包含数据库与密钥,离开宿主前应加密存放。

十一、常见问题

11.1 容器启动即退出,日志报 AppArmor 失败

GlobaLeaks Apparmor Sandboxing Failure: requires apparmor

原因:APPARMOR_SANDBOXING 为 1,但容器内 aa-status --enabled 判定 AppArmor 未启用。处理:在 compose 中设 APPARMOR_SANDBOXING: "0";若安全要求必须启用,则宿主先加载 AppArmor 策略并配置 security_opt。

11.2 权限错误,数据库无法创建

现象:日志出现 Permission denied,容器反复重启。原因:宿主数据目录属主不是 1000。处理:

chown -R 1000:1000 /srv/globaleaks/data
chmod 700 /srv/globaleaks/data

11.3 compose 提示网络已存在但非 compose 创建

level=warning msg="a network with name globaleaks-5.0.99-net exists but was not created by compose."

原因:该网络由之前的 docker network create 或其他项目创建。处理:确认无其他容器使用后 docker network rm globaleaks-5.0.99-net 再 up,或在 compose 中把网络标记为 external: true 并自行维护。

11.4 拉取镜像报 allowlist 拒绝

error from registry: 这镜像不在白名单. this image is not in the allowlist.

原因:宿主配置了带白名单的镜像加速器。处理:改用可直连 Docker Hub 的出口、换用放行该仓库的加速器,或从官方发布渠道获取离线包后 docker load。

11.5 访问 8143 证书告警

首次启动使用自签证书,浏览器提示不受信任属正常。生产环境在管理后台配置受信任证书或启用 ACME 自动签发;反向代理终止 TLS 时,需确保代理日志关闭,避免记录举报人 IP。

11.6 onion 地址与上次不同

若删除了数据目录或挂载点变更,Tor 密钥会重新生成,onion 地址随之改变。保持 /var/globaleaks 持久化即可稳定地址;更换地址意味着旧地址失效,需要重新分发。

十二、参考链接