Fider v0.38.2 Docker Compose 部署指南

Fider v0.38.2 用户反馈板 Docker Compose 双服务(app+PostgreSQL 17)从零部署实测:镜像选型与版本钉定、站点初始化与邮件验证闭环、数据持久化、环境变量表、等价 docker run 与 5 类启动/网络排障实录。

FiderFider用户反馈自托管GoDockerPostgreSQL2026/11/01

Fider v0.38.2 Docker Compose 部署指南

目标:在一台干净的 Linux 服务器上,用 Docker Compose 以「应用 + PostgreSQL」双服务形态从零部署 Fider v0.38.2 用户反馈板,完成站点初始化(创建站点、管理员邮箱验证登录、发布第一条反馈),并验证数据持久化与常见故障处理。本文全部命令与回显均在实验环境实测照抄(部署日期 2026-11-01)。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(x86_64)
  • Docker Engine:29.x;Docker Compose:v5.6.1(docker compose version 实测回显 Docker Compose version v5.6.1)
  • Fider:官方镜像 getfider/fider:v0.38.2(GitHub Releases 实查最新稳定版,发布于 2026-10-05;镜像内版本横幅实查为 v0.38.2-e492af4a30db30c104df3dfb9e0f04e55757ba9e)
  • PostgreSQL:官方镜像 postgres:17(实测拉取版本 PostgreSQL 17.11,满足官方「PG 12+」要求)
  • 测试邮件组件:mailhog/mailhog(官方文档推荐的试用 SMTP,Web UI 端口 8025)
  • 端口规划:Fider Web 对外 8140(容器内固定监听 3000)、MailHog UI 对外 8142
  • 部署目录:/opt/fider(compose 文件、数据目录统一收敛于此)
  • 示例管理员:站点名 quzuo,邮箱 root@quzuo.net;数据库口令 q1w2e3r4

二、镜像选型说明

Fider 官方文档明确「不发行 Linux/Windows 二进制,自托管需要 Docker」,官方镜像发布在 Docker Hub:

镜像说明选型结论
getfider/fider:stable官方文档示例默认标签,滚动指向最新稳定构建可用,但内容随时间漂移
getfider/fider:v0.38.2与 GitHub Release 一一对应的固定标签本文采用,生产可复现
ghcr.io/getfider/fider:*GitHub Container Registry 路径实测 denied(该仓库未公开发布),勿用

⚠️ 实测记录:stable 与 v0.38.2 两个标签的镜像摘要不同(stable 为 sha256:eb95d0b4bf5d...,v0.38.2 为 sha256:25d17db73c3d...),即 stable 并不恰好等于 v0.38.2。生产部署请像本文一样钉住版本标签,升级时显式改标签。

⚠️ 网络说明:本次实验宿主 Docker 守护进程配置了国内镜像加速(docker.m.daocloud.io 等)。getfider/fider 经镜像加速实测可直接 docker pull 成功;ghcr.io 路径在本环境返回 error from registry: denied。若你的服务器直连 Docker Hub 受阻,优先换国内加速器,而不是 ghcr。

三、前置条件

  1. Docker 与 Compose 插件已安装并可拉取镜像(docker info 正常返回);
  2. 目标端口空闲:
ss -ltn | grep -E ':8140|:8142' || echo "8140/8142 free"

实测回显(部署前):

8140/8142 free
  1. 准备一个足够强的 JWT 会话密钥(32 字节随机十六进制即可):
openssl rand -hex 32

实测回显:

f823a9215047a93f21242be82cce6578f9cc882c2b63b2b7f7e51522482ddc6c

💡 说明:JWT_SECRET 用于签发登录会话,改动会使所有人被登出。上面回显只是某一次生成的示例值;本文后续 compose 与 docker run 中使用的密钥是同一方式另生成的另一个 64 位十六进制串(即实验环境实际在用的那把),两者不必相同,各自随机即可。

  1. 邮件通道:Fider 的注册/登录完全依赖邮件验证链接(v0.38.2 实测 users 表无 password 列,即没有本地密码体系,登录走魔法链接或 OAuth)。生产环境配置真实 SMTP/Mailgun/Amazon SES 三选一;本文试用环境用官方文档推荐的 MailHog 假 SMTP。

四、部署步骤

4.1 创建部署目录与 compose 文件

mkdir -p /opt/fider/pg_data
cd /opt/fider

写入 docker-compose.yml(双服务:db + app;name: 显式钉项目名,避免多套栈互扰):

name: fider-v0.38.2-stack

services:
  db:
    restart: always
    image: postgres:17
    container_name: fider-v0.38.2-db
    hostname: db
    volumes:
      - /opt/fider/pg_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: fider
      POSTGRES_PASSWORD: q1w2e3r4
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U fider -d fider"]
      interval: 5s
      timeout: 3s
      retries: 12

  app:
    restart: always
    image: getfider/fider:v0.38.2
    container_name: fider-v0.38.2-server
    hostname: app
    ports:
      - "8140:3000"
    environment:
      BASE_URL: "http://192.168.1.172:8140"
      DATABASE_URL: "postgres://fider:***@db:5432/fider?sslmode=disable"
      JWT_SECRET: "3f9c2a7e5b1d8c4a6f0e9b2c5d8a1f4e7b0c3d6a9f2e5b8c1d4a7e0f3b6c9d2"
      EMAIL_NOREPLY: "noreply@quzuo.net"
      EMAIL_SMTP_HOST: "mailhog"
      EMAIL_SMTP_PORT: "1025"
      LOG_LEVEL: "INFO"
    depends_on:
      db:
        condition: service_healthy

networks:
  default:
    name: fider-v0382-stack_fider-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.60.0/24

关键项说明:

  • BASE_URL 必须等于用户实际访问的完整地址(含协议与端口),Fider 用它拼装所有邮件内链接;
  • DATABASE_URL 指向服务名 db,库名默认与用户同名 fider(postgres 镜像以 POSTGRES_USER 建同名库);
  • depends_on + healthcheck:官方文档的裸 compose 允许 app 先于数据库启动并靠 restart: always 重试自愈;本文用健康检查门控,首轮即一次成功(见 4.3 日志);
  • 自定义网段 10.89.60.0/24 为实验内网规划,按你的服务器网段替换即可。

4.2 拉取并启动

cd /opt/fider
docker compose pull
docker compose up -d

docker compose up -d 实测回显(节选):

 Container fider-v0.38.2-db Creating 
 Container fider-v0.38.2-db Created 
 Container fider-v0.38.2-server Creating 
 Container fider-v0.38.2-server Created 
 Container fider-v0.38.2-db Starting 
 Container fider-v0.38.2-db Started 
 Container fider-v0.38.2-db Waiting 
 Container fider-v0.38.2-db Healthy 
 Container fider-v0.38.2-server Starting 
 Container fider-v0.38.2-server Started 

4.3 启动日志验证

docker compose logs app 2>&1 | head -8

实测回显(首轮全新库,自动迁移):

INFO [2026-11-01T12:19:40Z] [MIGRATE] Running migrations...
INFO [2026-11-01T12:19:40Z] [MIGRATE] Found total of 95 migration files.
INFO [2026-11-01T12:19:40Z] [MIGRATE] Current version is 0
INFO [2026-11-01T12:19:40Z] [MIGRATE] Running Version: 201701261850 (201701261850_create_tenants.up.sql)
INFO [2026-11-01T12:19:40Z] [MIGRATE] Running Version: 201701281131 (201701281131_rename_domain.up.sql)
...(95 个迁移文件逐个执行,输出节选)
INFO [2026-11-01T12:19:40Z] [WEB] Environment: production
INFO [2026-11-01T12:19:40Z] [WEB] http server started on :3000
INFO [2026-11-01T12:19:40Z] [BGW] Starting worker 0.

看到 http server started on :3000 与 6 个后台 worker(Starting worker 0..5)即启动成功——这与官方文档「http server started on :3000 means everything is ok」的判据一致。

docker compose ps

实测回显:

NAME                   IMAGE                    COMMAND                  SERVICE   CREATED          STATUS                    PORTS
fider-v0.38.2-db       postgres:17              "docker-entrypoint.s…"   db        12 minutes ago   Up 12 minutes (healthy)   5432/tcp
fider-v0.38.2-server   getfider/fider:v0.38.2   "/bin/sh -c './fider…"   app       15 seconds ago   Up 4 seconds              0.0.0.0:8140->3000/tcp, [::]:8140->3000/tcp

4.4 挂载测试 SMTP(MailHog)

试用环境没有真实 SMTP 时,按官方文档挂一个 MailHog 接进本栈网络(注意:compose 项目名含小数点会被规范化,网络实名是 fider-v0382-stack_fider-net,见「常见问题」11.5):

docker run -d --name fider-v0.38.2-mailhog --hostname mailhog \
  --network fider-v0382-stack_fider-net -p 8142:8025 mailhog/mailhog

--hostname mailhog 必须与 app 服务的 EMAIL_SMTP_HOST: "mailhog" 一致,容器内 DNS 按主机名解析。

4.5 服务可达性验证

curl -s -o /dev/null -w "%{redirect_url}\n" http://192.168.1.172:8140/

实测回显:

http://192.168.1.172:8140/signup

全新实例访问根路径自动 307 跳转 /signup(创建第一个站点)。浏览器打开 http://192.168.1.172:8140/signup 即见官方注册页(页标题实测为 Sign up · Fider)。

五、站点初始化(首次运行)

5.1 创建站点与管理员

在 /signup 页面依次填写站点名 quzuo、你的名字 root、邮箱 root@quzuo.net 提交。该表单背后是 POST /_api/tenants,命令行等价操作实测如下:

curl -s -X POST http://192.168.1.172:8140/_api/tenants \
  -H 'Content-Type: application/json' \
  -d '{"tenantName":"quzuo","name":"root","email":"root@quzuo.net"}'

实测回显:

{}
HTTP 200

⚠️ 排障实录:字段名有讲究——只传 {"name":...} 返回 {"errors":[{"field":"tenantName","message":"Name is required."}]}(HTTP 400),只传 {"tenantName":...} 返回 {"errors":[{"field":"name","message":"Name is required."}]}(HTTP 400);tenantName(站点名)、name(用户姓名)、email 三者缺一不可。

5.2 邮箱验证完成注册

提交后 Fider 发出标题为 Your new Fider site 的验证邮件。MailHog 环境可直接取其 HTTP API 读信:

curl -s http://192.168.1.172:8142/api/v2/messages | python3 -c "
import json,sys,re
d=json.load(sys.stdin)
for it in d.get('items',[]):
    for m in set(re.findall(r'http://[^\"<> ]{10,160}', it['Content']['Body'])):
        if 'k=' in m: print(m)
"

实测回显(验证链接):

http://192.168.1.172:8140/signup/verify?k=ESlSfs4RM66LJOd8tcEOI9cvcpyfpjg2jLoJ9l6h0Irfy5XMgSSvnYYJWnfjHpU0

浏览器打开该链接即完成注册并自动登录(实测返回 307 跳回站点首页)。此后每次登录都在 /signin 输入邮箱收一次性验证链接——Fider v0.38.2 没有本地密码(实测 users 表无 password 列),这是它安全模型的一部分:

curl -s -X POST http://192.168.1.172:8140/_api/signin -H 'Content-Type: application/json' -d '{"email":"root@quzuo.net"}'

实测回显:

{"userExists":true}

5.3 发布第一条反馈验证业务闭环

登录后创建帖子(内部 API 实测):

curl -s -b cookies.txt -X POST http://192.168.1.172:8140/api/v1/posts \
  -H 'Content-Type: application/json' \
  -d '{"title":"支持中文全文检索","description":"希望反馈板支持中文分词与全文检索","tags":[]}'

实测回显:

{"id":1,"isApproved":true,"number":1,"slug":"zhi-chi-zhong-wen-quan-wen-jian-suo","title":"支持中文全文检索"}

浏览器首页实测标题为 <title>quzuo</title>,帖子列表可见该条反馈。

六、数据持久化说明

数据位置持久化方式
全部业务数据(站点/用户/帖子/评论/投票/上传附件/SQL 日志)PostgreSQL 单一 fider 库bind mount /opt/fider/pg_data
应用配置compose environment:compose 文件本身
上传文件默认 BLOB_STORAGE=sql 存库内 blobs 表随数据库一起持久化

💡 技术拓展:Fider 文件存储有三种——sql(默认,附件进 PostgreSQL,备份一锅端)、fs(落盘目录,需 BLOB_STORAGE_FS_PATH + 挂载卷)、s3(S3 兼容对象存储)。本文用默认 sql,小站附件量不大时最省心;大站建议 s3。切换 BLOB_STORAGE 不会迁移存量文件,选型要趁早(官方文档明示)。

持久化实测:重启应用服务后数据无损——

docker compose restart app
docker exec fider-v0.38.2-db psql -U fider -d fider -tc "select id, title, status from posts;"

实测回显:

  1 | 支持中文全文检索 |      0

数据库迁移版本同样落库可查(实测 migrations_history 共 95 行,最高版本 202606121200)。

七、环境变量表

本 compose 实际使用的变量(完整参数面见官方 Configuration Reference:https://docs.fider.io/hosting-instance#configuration-reference ):

变量本文取值必填说明
BASE_URLhttp://192.168.1.172:8140✅站点公网访问地址,邮件链接基址
DATABASE_URLpostgres://fider:***@db:5432/fider?sslmode=disable✅PG 连接串
JWT_SECRET64 位十六进制随机串✅会话签名密钥,改动即全员登出
EMAIL_NOREPLYnoreply@quzuo.net✅发件人地址
EMAIL_SMTP_HOSTmailhog✅(SMTP 方式时)缺它启动 panic(见 11.2)
EMAIL_SMTP_PORT1025✅(SMTP 方式时)MailHog 默认收件端口
LOG_LEVELINFO❌默认即 INFO

八、配置文件挂载

Fider 全量配置走环境变量,无独立配置文件;仅一类文件需要挂载进 /app/etc(官方文档 Mounting the etc folder):

  • SSL_CERT / SSL_CERT_KEY 指向的证书与私钥文件;
  • privacy.md、terms.md 法律页。
  app:
    volumes:
      - /opt/fider/etc:/app/etc

⚠️ 注意:/app 内其余目录(dist、static、views、migrations、locale 共 22 种语言包)都是镜像内置资源,不要挂载覆盖;升级镜像即升级它们。

九、等价 docker run

双服务 compose 中 app 服务的等价单命令形态(数据库先行单独起,或指向外部 PG):

docker run -d --name fider-v0.38.2-server \
  -p 8140:3000 \
  -e BASE_URL="http://192.168.1.172:8140" \
  -e DATABASE_URL="postgres://fider:***@db:5432/fider?sslmode=disable" \
  -e JWT_SECRET="3f9c2a7e5b1d8c4a6f0e9b2c5d8a1f4e7b0c3d6a9f2e5b8c1d4a7e0f3b6c9d2" \
  -e EMAIL_NOREPLY="noreply@quzuo.net" \
  -e EMAIL_SMTP_HOST="mailhog" \
  -e EMAIL_SMTP_PORT="1025" \
  --network fider-v0382-stack_fider-net \
  --restart always \
  getfider/fider:v0.38.2

镜像默认启动命令为 ./fider migrate && ./fider(实测 docker inspect 的 Cmd 字段),即先自动迁移再启动服务,与 compose 形态行为一致。

十、常用运维命令

cd /opt/fider

# 查看栈内服务状态
docker compose ps

# 跟踪应用日志(官方口径:docker compose logs app)
docker compose logs -f app

# 改环境变量后重建生效(Fider 只在启动时读取配置)
docker compose up -d

# 只重启应用
docker compose restart app

# 升级到新版本:改 compose 中镜像标签后
docker compose pull && docker compose up -d

# 停止整栈(保留数据目录)
docker compose down

# 健康检查(容器内二进制自带 ping 子命令,退出码 0/1)
docker exec fider-v0.38.2-server /app/fider ping; echo $?

ping 实测回显:退出码 0(内部 GET /_health 返回 200)。

十一、常见问题

11.1 拉取 ghcr.io/getfider/fider 报 denied

实测 docker pull ghcr.io/getfider/fider:stable 返回 error from registry: denied。官方镜像实际发布在 Docker Hub getfider/fider,改用 docker pull getfider/fider:stable 或固定版本标签即可(本文实测 v0.38.2 拉取成功)。

11.2 缺必填环境变量导致启动 panic

实测逐层暴露的校验链(docker run --entrypoint /app/fider getfider/fider:v0.38.2 --help 在缺失对应变量时依次报):

panic: Error Trace: 
- failed to parse environment variables (app/pkg/env/env.go:170)
- the environment variable "JWT_SECRET" is missing

补齐 JWT_SECRET 后报 EMAIL_NOREPLY is missing,再补报 DATABASE_URL……最后报:

panic: could not find environment variable named 'EMAIL_SMTP_HOST'

结论:BASE_URL/DATABASE_URL/JWT_SECRET/EMAIL_NOREPLY 四个必填之外,采用 SMTP 邮件方案时 EMAIL_SMTP_HOST/EMAIL_SMTP_PORT 也必须显式设置,否则进程在解析配置阶段直接退出(连 --help 都跑不出来,因为校验发生在 flag 解析之前)。

11.3 [MIGRATE] pq: password authentication failed for user "fider" (28P01)

实测排障实录:DATABASE_URL 连接串口令与 POSTGRES_PASSWORD 不一致时,应用进入重启循环,日志反复刷:

INFO [2026-11-01T12:18:16Z] [MIGRATE] Running migrations...
ERROR [2026-11-01T12:18:16Z] [MIGRATE] Error Trace: 
- failed to get last migration record (app/pkg/dbx/migrate.go:57)
- pq: password authentication failed for user "fider" (28P01)

定位方法:docker inspect 对比 app 的 DATABASE_URL 与 db 的 POSTGRES_PASSWORD;或在数据库侧用同串口令验证 psql -h 127.0.0.1 -U fider。修正 compose 后 docker compose up -d 重建即恢复。注意:若 pg_data 已用旧口令初始化过,改 POSTGRES_PASSWORD 环境变量不会改库内口令,需进库执行 ALTER USER fider WITH PASSWORD 'q1w2e3r4';(与 compose 中 POSTGRES_PASSWORD 保持一致)。

11.4 首轮启动报 dial tcp :5432 connection refused

官方文档明示这是预期现象(裸 compose 下 app 先于数据库就绪):靠 restart: always 自动重试到数据库可用。本文用 healthcheck + depends_on: condition: service_healthy 从根上消除该窗口,首轮即一次成功。

11.5 往 compose 网络里挂外部容器报 network not found

实测:compose 项目名 fider-v0.38.2-stack 中的小数点被规范化剥离,实际网络名是 fider-v0382-stack_fider-net(docker network ls | grep fider 可见)。给 MailHog 等旁路组件 --network 时必须用规范化后的实名。

十二、参考链接

Fider v0.38.2 Docker Compose 部署指南 - Quzuo