本文介绍如何在一台 Linux 服务器上,以 Docker Compose 部署寻味。生产环境由 Web、API、Worker、AI Worker、PostgreSQL/PostGIS 和 Redis 组成;本仓库不包含域名、证书和反向代理的实际配置文件。
- 已安装 Docker Engine 与 Docker Compose 插件。
- 已为网站和 API 准备 HTTPS 域名,例如
gowith.example.com与api.gowith.example.com。 - 已准备 S3 兼容对象存储(生产文件存储和备份存储建议使用不同的私有桶或不同账号)。
- 已准备所需的 AI、地图、邮件和微信等第三方服务凭据。
应用容器只监听服务器的 127.0.0.1。请使用 Nginx、Caddy 或同类反向代理在主机上终止 HTTPS,并将公网流量转发到本机端口:
| 公网域名 | 本机上游地址 | 用途 |
|---|---|---|
gowith.example.com |
http://127.0.0.1:23000 |
用户网站 |
api.gowith.example.com |
http://127.0.0.1:24000 |
API 与实时事件 |
反向代理应转发 Host、X-Forwarded-For 和 X-Forwarded-Proto 请求头;API 的实时事件连接应关闭代理缓冲。API 只信任 TRUSTED_PROXY_CIDRS 中的直接上游(默认是本机回环),不要将其设为 0.0.0.0/0 或 ::/0,否则客户端可伪造来源 IP 绕过登录限速。证书、域名和防火墙属于服务器运维范围,不应写入仓库。
git clone <你的仓库地址> GoWith
cd GoWith
pnpm install --frozen-lockfile
cp .env.production.example .env.production
chmod 600 .env.production编辑 .env.production,至少完成以下配置。
PUBLIC_WEB_ORIGIN=https://gowith.example.com
WEB_ORIGIN=https://gowith.example.com
NEXT_PUBLIC_SITE_URL=https://gowith.example.com
NEXT_PUBLIC_API_BASE_URL=https://api.gowith.example.com
EXPO_PUBLIC_API_BASE_URL=https://api.gowith.example.com保留容器内部地址,不要把它们改成公网域名:
API_BASE_URL=http://api:24000
AI_WORKER_URL=http://ai-worker:28000
DATABASE_URL=postgres://gowith:<数据库密码>@postgres:25432/gowith
REDIS_URL=redis://:<Redis密码>@redis:26379
TRUSTED_PROXY_CIDRS=127.0.0.1/8,::1/128所有应用容器都不再继承完整 .env.production:Compose 只向 API、Worker、AI Worker、Web 分别传入运行所需的变量。AI Worker 默认直连官方 Groq;只有自行运营并明确知情时,才配置 GROQ_BASE_URL 指向兼容中转。
为每个密钥生成不同的随机值,不要使用示例文件中的占位符。
openssl rand -base64 48 # AUTH_SECRET
openssl rand -base64 32 # COOKIE_ENCRYPTION_KEY
openssl rand -base64 32 # AI_WORKER_SHARED_SECRET填写 AUTH_SECRET、COOKIE_ENCRYPTION_KEY、AI_WORKER_SHARED_SECRET、POSTGRES_PASSWORD、REDIS_PASSWORD、ADMIN_USERNAME 和一次性 ADMIN_INITIAL_PASSWORD。生产环境会拒绝使用公开占位符或过短的关键密钥。
生产环境使用 S3 兼容对象存储。配置 OBJECT_STORAGE_* 为用户上传和公开媒体存储;配置 PROJECT_BACKUP_S3_* 为独立、不可公开访问的备份目标。
FILE_STORAGE_DRIVER=s3
PROJECT_BACKUP_ENABLED=true
PROJECT_BACKUP_ENCRYPTION_KEY=<随机生成的 32 字节 Base64 密钥>
PROJECT_BACKUP_RELEASE_ID=<本次部署的 Git 提交号或版本号>备份密钥不可丢失,否则无法恢复备份。启用后,Worker 每天在北京时间 01:00 创建加密项目备份。首次部署完成后建议手动运行一次备份命令,确认对象存储权限和加密配置可用。
完整源音频会由 Worker 流式写入临时磁盘,再由 AI Worker 转码、分片;不会把整个文件读入内存。默认源文件上限为 256 MiB、视频时长不超过 3600 秒、下载超时为 120 秒。每个提交给 Groq 的分片仍严格受 GROQ_ASR_MAX_MB(默认 22 MiB)限制。可按服务器磁盘与并发能力调整,但不建议取消任一限制:
BILIBILI_ASR_MAX_DOWNLOAD_MB=256
BILIBILI_ASR_MAX_DURATION_SECONDS=3600
BILIBILI_ASR_DOWNLOAD_TIMEOUT_MS=120000
ASR_MAX_SOURCE_MB=256
GROQ_ASR_MAX_MB=22先构建应用镜像,再只启动 PostgreSQL 与 Redis,完成迁移和管理员初始化,最后启动全部服务:
pnpm docker:prod:build
docker compose --env-file .env.production -f docker-compose.prod.yml up -d postgres redis
pnpm db:migrate:prod
pnpm db:seed:prod
pnpm docker:prod:up查看服务日志:
pnpm docker:prod:logs在服务器本机执行:
curl --fail http://127.0.0.1:24000/health
curl --head http://127.0.0.1:23000预期 API 健康检查返回包含 "ok": true 的 JSON。随后在浏览器中打开网站域名,确认首页、地图、登录和后台入口能够访问;再检查 API 域名的 HTTPS 证书和跨域配置是否与 WEB_ORIGIN 一致。
建议在首次上线后验证一次备份:
pnpm backup:prod正常更新顺序如下:
git pull --ff-only
pnpm install --frozen-lockfile
pnpm docker:prod:build
pnpm db:migrate:prod
pnpm docker:prod:up如需停止应用但保留数据库、Redis 和上传卷:
pnpm docker:prod:down数据库迁移是向前执行的。发布前应先完成备份;若需要回退到旧应用版本,应先确认旧版本与现有数据库 Schema 兼容,不能仅凭重新构建旧镜像来假定能够回滚。
# 查看容器状态
docker compose --env-file .env.production -f docker-compose.prod.yml ps
# 跟踪全部服务日志
pnpm docker:prod:logs
# 创建一次加密项目备份
pnpm backup:prod
# 从指定备份恢复(会修改当前数据,先阅读命令提示)
pnpm backup:restore:prod -- --backup-id <backup-id> --apply不要提交 .env.production、对象存储密钥、Cookie、数据库导出文件或备份归档。升级镜像、调整环境变量、执行迁移或恢复之前,均应先确认最近一次备份可以读取。