Zipline 4.8.2 Docker Compose 部署指南

Ubuntu 24.04 上用 Docker Compose 从零部署 Zipline 4.8.2(PostgreSQL 16 + nginx 反代):AVX 前置检查、.env 与 compose 全文、持久化与升级两态对照实测、docker run 等价部署与七条排障实录。

ZiplineZipline2026/11/01

Zipline 4.8.2 Docker Compose 部署指南

目标:在一台 Ubuntu 24.04 LTS 服务器上,用 Docker Compose 从零把 Zipline 4.8.2(文件分享 + 短链 + 文本粘贴三合一服务)跑起来,配好 nginx 反向代理,完成首次初始化,并沉淀升级、持久化验证与真实踩坑记录。本文全部命令与回显均为 2026-11-01 实机执行原文。

一、环境信息

项目值
操作系统Ubuntu 24.04.5 LTS(x86_64)
Docker29.9.2, build a82e528
Docker Composev5.6.1(docker compose version 实测)
Zipline4.8.2(ghcr.io/diced/zipline:4.8.2,2026-11-01 实查官方最新稳定版)
数据库PostgreSQL 16(postgres:16)
反向代理nginx:alpine(独立部署,端口 8143)
端口规划直连 8142→3000,反代 8143→80;部署前用 ss -ltn 确认空闲
网段自定义网络 zipline-v482-net,子网 10.89.62.0/24
部署目录/opt/zipline
演示账号root / q1w2e3r4(初始化时创建)

选型背景与功能边界见 《Zipline 介绍与选型指南》;部署后想调参数看 《Zipline 4.8.2 配置参数详解》;接口实操看 《Zipline 4.8.2 常用操作与 API 详解》。

二、镜像选型说明

  • 应用镜像:官方镜像仓库 ghcr.io/diced/zipline,tag 跟随版本号。生产环境钉死版本号(本文用 4.8.2),不要用 latest——官方约 2~6 周发一版,minor 版本会带行为变化。
  • 数据库镜像:官方 compose 模板即 postgres:16,Zipline 4.x 的 schema 按 PG16 验证。
  • 运行时要求:镜像内是 Node.js 24(实测环境变量 NODE_VERSION=24.22.1),视频缩略图依赖 ffmpeg(官方镜像已内置)。
  • ⚠️ 网络说明:ghcr.io 在国内直连拉取可能很慢或失败。实测环境的降级渠道是给 Docker 配置代理 192.168.1.62:7897(/etc/docker/daemon.json 的 proxies 段),或改从 docker.m.daocloud.io 加速域名拉取;两者任一可用即可继续,下文默认已配好拉取通道。

三、前置条件

3.1 CPU 必须支持 AVX 指令集(硬性门槛)

Zipline v4 的依赖要求 CPU 支持 AVX,否则进程起不来。部署前先查:

grep -c avx /proc/cpuinfo

实测回显:

6

(每个逻辑核的 flags 里都含 avx,计数 >0 即可用。)老至强、部分嵌套虚拟化环境此值为 0,那就换不了 Zipline v4,选型阶段就要排除。

3.2 端口与网段

ss -ltn | grep -E ':8142|:8143'

实测部署前无输出(端口空闲),部署后:

LISTEN 0  4096  0.0.0.0:8143  0.0.0.0:*
LISTEN 0  4096  0.0.0.0:8142  0.0.0.0:*

Docker 环境就绪:

docker --version && docker compose version

实测回显:

Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1

四、部署步骤

4.1 建立部署目录与 .env

mkdir -p /opt/zipline/{uploads,public,themes}
cd /opt/zipline
openssl rand -base64 32   # 生成数据库密码,取前 32 位
openssl rand -base64 32   # 生成 CORE_SECRET

写入 .env(示例值即本次实测值):

POSTGRESQL_PASSWORD=PlG0QklJ17CAoqFYk5u4nGBqOMAkGlQh
CORE_SECRET=bNI6krbWOmOeGEsXl7fD5wioCDT9TNub
CORE_RETURN_HTTPS_URLS=false
FILES_ROUTE=/f
FILES_LENGTH=12
FILES_DEFAULT_FORMAT=date
FILES_MAX_FILE_SIZE=5mb
URLS_ROUTE=/s
URLS_LENGTH=8
FEATURES_THUMBNAILS_ENABLED=true
FEATURES_THUMBNAILS_INSTANTANEOUS=true
CORE_TRUST_PROXY=true
CORE_TRUSTED_PROXIES=10.89.62.0/24
DEBUG=zipline

⚠️ 实测教训:CORE_SECRET 有长度校验。用 openssl rand -base64 32 后再做字符删减可能把长度削到 32 以下,服务会直接拒绝启动并报:

[2026-11-01T09:00:17 ERROR  config.validate] There was an error while validating the environment.
[2026-11-01T09:00:17 ERROR  config.validate] CORE_SECRET: Secret must contain at least 32 characters

保持 32 字符以上原样使用即可。

4.2 编写 docker-compose.yml

官方模板结构 + 本次实测的完整文件(/opt/zipline/docker-compose.yml):

name: zipline-v4.8.2-stack

services:
  postgresql:
    image: postgres:16
    restart: unless-stopped
    env_file:
      - .env
    environment:
      POSTGRES_USER: ${POSTGRESQL_USER:-zipline}
      POSTGRES_PASSWORD: ${POSTGRESQL_PASSWORD:?POSTGRESQL_PASSWORD is required}
      POSTGRES_DB: ${POSTGRESQL_DB:-zipline}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD', 'pg_isready', '-U', 'zipline']
      interval: 10s
      timeout: 5s
      retries: 5

  zipline:
    image: ghcr.io/diced/zipline:4.8.2
    restart: unless-stopped
    ports:
      - '8142:3000'
    env_file:
      - .env
    environment:
      - CORE_PORT=3000
      - CORE_HOSTNAME=0.0.0.0
      - DATABASE_URL=postgres://${POSTGRESQL_USER:-zipline}:${POSTGRESQL_PASSWORD}@postgresql:5432/${POSTGRESQL_DB:-zipline}
    depends_on:
      postgresql:
        condition: service_healthy
    volumes:
      - './uploads:/zipline/uploads'
      - './public:/zipline/public'
      - './themes:/zipline/themes'
    healthcheck:
      test: ['CMD', 'wget', '-q', '--spider', 'http://0.0.0.0:3000/api/healthcheck']
      interval: 15s
      timeout: 2s
      retries: 2

volumes:
  pgdata:

networks:
  default:
    name: zipline-v482-net
    ipam:
      config:
        - subnet: 10.89.62.0/24

结构要点:POSTGRESQL_PASSWORD is required 用 Compose 的 :? 语法强制必填;depends_on 配 service_healthy 保证数据库就绪后再起应用;CORE_HOSTNAME=0.0.0.0 是反代/端口映射能进来的前提。

4.3 启动

docker compose up -d

实测回显:

 Container zipline-v482-stack-postgresql-1 Creating 
 Container zipline-v482-stack-postgresql-1 Created 
 Container zipline-v482-stack-zipline-1 Creating 
 Container zipline-v482-stack-zipline-1 Created 
 Container zipline-v482-stack-postgresql-1 Starting 
 Container zipline-v482-stack-postgresql-1 Started 
 Container zipline-v482-stack-postgresql-1 Waiting 
 Container zipline-v482-stack-postgresql-1 Healthy 
 Container zipline-v482-stack-zipline-1 Starting 
 Container zipline-v482-stack-zipline-1 Started 

状态确认:

docker compose ps

实测回显:

NAME                              IMAGE                         COMMAND                  SERVICE      CREATED          STATUS                    PORTS
zipline-v482-stack-postgresql-1   postgres:16                   "docker-entrypoint.s…"   postgresql   35 seconds ago   Up 35 seconds (healthy)   5432/tcp
zipline-v482-stack-zipline-1      ghcr.io/diced/zipline:4.8.2   "/zipline/entrypoint"    zipline      35 seconds ago   Up 25 seconds (healthy)   0.0.0.0:8142->3000/tcp, [::]:8142->3000/tcp

4.4 健康检查与初始化状态

curl -s http://127.0.0.1:8142/api/healthcheck

实测回显:

{"pass":true}

全新实例的初始化入口判断接口:

curl -s http://127.0.0.1:8145/api/setup

实测回显(对照实验用的干净实例):

{"firstSetup":true}

已初始化过的实例同一请求返回 403:

{"error":"E9001: Setup already completed","code":9001,"statusCode":403}

4.5 创建超级管理员

浏览器打开 http://<服务器IP>:8142/auth/setup,表单里设置用户名/密码——本次实测创建 root / q1w2e3r4。该入口只在 firstSetup:true 时可用,建完即关(见上节 403)。登录后建议立刻在后台 Features 里关闭开放注册(邀请制策略见配置详解篇)。

五、反向代理配置

Zipline 4.4.1 起移除内置 TLS,HTTPS 一律交给反代。nginx 站点配置实测可用原文:

server {
  listen 80;
  server_name _;

  client_max_body_size 100M;

  location / {
    proxy_pass http://zipline:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

两个配套点:

  1. 反代必须与应用同网络(本例 zipline-v482-net),proxy_pass 才能用服务名 zipline 解析;
  2. 应用侧要声明信任它——.env 里 CORE_TRUST_PROXY=true、CORE_TRUSTED_PROXIES=10.89.62.0/24(反代所在网段),否则限流与访客 IP 统计全部失真。

经反代验证:

curl -s http://127.0.0.1:8143/api/healthcheck

实测回显:

{"pass":true}

上 HTTPS 后记得把 CORE_RETURN_HTTPS_URLS=true 打开,生成的直链才会是 https:// 且 Cookie 带 Secure。

六、数据持久化说明

三类持久化位置,备份三处都要带走:

数据位置类型
元数据(用户/文件索引/短链/统计)named volume zipline-v482-stack_pgdata卷
上传文件本体/opt/zipline/uploads(默认 local datasource)bind mount
自定义主题/图标、PWA 素材/opt/zipline/themes、/opt/zipline/publicbind mount

持久化实测:docker compose down(不带 -v,卷保留)再 up -d 后,用户数据原样:

docker compose exec zipline ziplinectl list-users

实测回显(重建后与重建前一致):

[{"id":"x48cfnti1ir8atu0qbnha9oa","username":"root","createdAt":"2026-11-01T07:43:15.834Z","role":"SUPERADMIN"},{"id":"nqcbgnte8j43i2a92nuzosu1","username":"demo","createdAt":"2026-11-01T07:56:37.978Z","role":"USER"}]

此前上传的文件直链在重建后仍返回 200。恢复侧对应:pg_dump 元数据库 + 打包 uploads 目录即可完整还原。

⚠️ 实测注意:docker compose down 时若网络还被其他东西挂着(比如本例独立部署的 nginx-proxy 也接在 zipline-v482-net 上),会输出 Network zipline-v482-net Resource is still in use——服务已正常停止删除,仅网络保留,不影响下次 up;想彻底清网络要先断开占用它的其他服务。

七、环境变量表

.env 各变量含义(完整参数体系、默认值与生效方式见 《Zipline 4.8.2 配置参数详解》,此处只列本部署用到的):

变量本例取值必填说明
POSTGRESQL_PASSWORD随机 32 位✅数据库密码,compose 用 :? 强制
CORE_SECRET随机 ≥32 位✅Cookie 签名 + Token 加密密钥
CORE_RETURN_HTTPS_URLSfalse建议上 HTTPS 后改 true
CORE_TRUST_PROXY / CORE_TRUSTED_PROXIEStrue / 反代网段反代场景✅不配则限流/IP 全按反代算
FILES_ROUTE / FILES_LENGTH / FILES_DEFAULT_FORMAT/f / 12 / date否文件直链前缀/随机名长度/命名格式
FILES_MAX_FILE_SIZE5mb否单文件大小上限(默认 100mb)
URLS_ROUTE / URLS_LENGTH/s / 8否短链前缀/短码长度
FEATURES_THUMBNAILS_ENABLED / ..._INSTANTANEOUStrue / true否视频缩略图开关/即时生成
DEBUGzipline否打开 debug 级日志,排障利器

八、配置文件挂载

env_file: .env 之外,三个目录 bind mount 进服务固定路径:./uploads→/zipline/uploads、./public→/zipline/public、./themes→/zipline/themes。自定义主题(.css)放 themes/、PWA 图标放 public/ 即可被后台识别,无需重建;random-words 命名的词表也放 public/(animals.txt/adjectives.txt,一行一词,改完不用重启)。

九、等价 docker run 部署(对照实测)

不用 Compose 时等价三步(实测于端口 8145、网段 10.89.63.0/24,验证后已拆除):

docker network create --subnet 10.89.63.0/24 zipline-v482-run-net
docker run -d --name zipline-v482-run-pg --network zipline-v482-run-net \
  -e POSTGRES_USER=zipline -e POSTGRES_PASSWORD=Runpw123456 -e POSTGRES_DB=zipline \
  postgres:16
docker run -d --name zipline-v482-run-app --network zipline-v482-run-net \
  -p 8145:3000 \
  -e CORE_SECRET=<32位以上随机串> \
  -e DATABASE_URL=postgres://zipline:Runpw123456@zipline-v482-run-pg:5432/zipline \
  -e CORE_HOSTNAME=0.0.0.0 \
  -v $PWD/runuploads:/zipline/uploads \
  ghcr.io/diced/zipline:4.8.2

实测验证回显:

{"pass":true}
{"firstSetup":true}

启动日志尾部:

[2026-11-01T09:01:15 INFO   server] server started hostname="0.0.0.0" port=3000

差异提醒:run 形态没有 healthcheck 编排与 depends_on 顺序保证,应用先于数据库就绪启动时会报 EAI_AGAIN 然后靠 --restart 兜底,生产仍推荐 Compose。

十、常用运维命令

docker compose logs -f zipline          # 跟日志(DEBUG=zipline 时含配置加载明细)
docker compose restart zipline          # 只重启进程:不重读 .env、不重建
docker compose up -d                    # 配置无变化时输出 "Running",不动服务
docker compose up -d                    # .env/compose 有变化时输出 "Recreate",滚动重建
docker compose down                     # 停并删容器与网络,保留 pgdata 卷
docker compose down -v                  # 连卷删(数据库数据会没,慎用)

两态对照实测:前一步把 .env 里 FILES_MAX_FILE_SIZE 从 1mb 改成 5mb 后执行 docker compose up -d(当时数据库容器恰好缺失,输出里同时包含它的补建过程)——检测到配置变化,重建应用:

 Container zipline-v482-stack-postgresql-1 Creating 
 Container zipline-v482-stack-postgresql-1 Created 
 Container zipline-v482-stack-zipline-1 Recreate 
 Container zipline-v482-stack-zipline-1 Recreated 
 Container zipline-v482-stack-postgresql-1 Starting 
 Container zipline-v482-stack-postgresql-1 Started 
 Container zipline-v482-stack-postgresql-1 Waiting 
 Container zipline-v482-stack-postgresql-1 Healthy 
 Container zipline-v482-stack-zipline-1 Starting 
 Container zipline-v482-stack-zipline-1 Started 

紧接着第二次 docker compose up -d——配置无变化,原样不动:

 Container zipline-v482-stack-zipline-1 Running 
 Container zipline-v482-stack-postgresql-1 Running 
 Container zipline-v482-stack-postgresql-1 Waiting 
 Container zipline-v482-stack-postgresql-1 Healthy 

改 .env 必须走 up -d 触发重建才生效(restart 不重读环境变量);验证生效用 docker compose exec zipline ziplinectl read-config。

升级:改 compose 里镜像 tag(如 4.8.2→新版本号)→ docker compose pull zipline → docker compose up -d(自动 Recreate)。回滚即改回旧 tag 再 up -d。版本自检:登录态下 GET /api/version 实测返回 "isLatest":true 与 latest.tag。

十一、常见问题(排障实录)

  1. 应用反复重启,日志报 Error: getaddrinfo EAI_AGAIN postgresql(实录:数据库服务未运行时,应用 crash-loop,docker ps 显示 Restarting (1))——应用解析不到服务名 postgresql。定位:docker compose ps -a 看数据库状态;若数据库容器是 Exited/残留的 Created 状态,docker rm -f 清掉残留后 docker compose up -d 重建,应用侧 depends_on: service_healthy 会重新把关。本次实机即按此恢复,两服务最终同显 (healthy)。
  2. 上传大文件报 E1062: No files in multipart/form-data request——不是没带文件,是超 FILES_MAX_FILE_SIZE 被 multipart 解析器静默丢弃(实测 6MB/上限 5mb 触发)。调大上限走 up -d 重建,或改分块上传接口。
  3. 换 CORE_SECRET 后所有人掉线、Token 全 401——设计行为:Cookie 与 Token 均由它加密。换密钥前先公告,换后重新登录取 Token。
  4. docker compose down 报 Network ... Resource is still in use——网络被栈外服务占用(本例 nginx-proxy)。容器已正常清理,网络保留无害;确要删除先断开占用方。
  5. 容器起来但 CORE_SECRET 校验失败直接退出——日志 CORE_SECRET: Secret must contain at least 32 characters(实录见 §4.1 警告框),给足 32 字符即可。
  6. 拉取 ghcr.io 超时——按 §二 网络说明走代理或加速域名,配完 systemctl restart docker 再 docker compose pull。
  7. CPU 无 AVX——进程根本起不来且报错指向原生依赖加载;换机或留在 v3(已停维),选型阶段用 grep -c avx /proc/cpuinfo 预判。

十二、参考链接