Reactive Resume 6.0.8 Docker Compose 部署指南
Ubuntu 22.04 上用 Docker Compose 从零部署 Reactive Resume v6.0.8(应用 + PostgreSQL 18 官方精简双服务编排),覆盖镜像选型、部署验证、数据持久化、备份升级与排障,命令与回显逐条实测照抄。
Reactive Resume 6.0.8 Docker Compose 部署指南
目标:在一台 Ubuntu 22.04 服务器上,用 Docker Compose 从零部署 Reactive Resume v6.0.8(官方精简编排:应用 + PostgreSQL 18 双服务),覆盖镜像选型、部署、验证、数据持久化、备份、升级与排障。本文全部命令与回显均在 2026-10-29 于 Ubuntu 22.04 实测环境逐条执行并照抄,演示账号
admin/q1w2e3r4。产品定位与同类对比见《Reactive Resume 介绍与选型指南》,环境变量全量说明见《Reactive Resume 6.0.8 配置参数详解》,REST API 实测见《Reactive Resume 6.0.8 API 使用详解》。
一、环境信息
本文实测环境的关键信息如下,读者在同样规格的服务器上按步骤操作应得到一致结果:
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04(x86_64) |
| Docker Engine | 29.9.2(docker --version 实测) |
| Docker Compose | v5.6.1(docker compose version 实测) |
| 应用版本 | Reactive Resume v6.0.8(发布于 2026-10-29,官方最新稳定版) |
| 数据库 | PostgreSQL 18(postgres:18 官方镜像) |
| 应用监听 | 容器内 3000 端口,映射到宿主机 8150 端口 |
| PostgreSQL 监听 | 仅编排内网 5432,不向宿主机发布端口 |
| 编排目录 | /opt/reactive-resume/ |
| 编排项目名 | reactive-resume-6.0.8-stack |
| 演示账号 | admin / q1w2e3r4 |
先确认本机工具链版本(输出为实测回显,下同):
docker --version
docker compose version
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
v6 的官方镜像运行单进程 Node.js 服务:一个进程同时提供 Web 站点、REST API、认证、MCP 服务与上传文件下载,监听 3000 端口,镜像内置健康检查每 30 秒调用一次 GET /api/health。反向代理(若部署)只需转发这一个端口。
二、镜像选型说明
官方镜像发布到两个注册表、tag 完全一致:
| 注册表 | 镜像路径 |
|---|---|
| Docker Hub | amruthpillai/reactive-resume |
| GitHub Container Registry | ghcr.io/reactive-resume/reactive-resume |
可用 tag 与取舍:
| Tag | 含义 | 适用 |
|---|---|---|
v6.0.8 | 精确版本 | 生产推荐,升级完全可控 |
v6.0 / v6 | 大/中版本浮动 | 想自动获得同版本线内修复 |
latest | 最新发布 | 追新,但大版本升级(v6→v7)会自动发生 |
nightly | main 分支每日构建 | 仅测试,不用于生产 |
镜像提供 linux/amd64 与 linux/arm64 双架构,x86 服务器与树莓派 4+(64 位系统)均可运行。
💡 技术拓展:容器镜像 tag 不止「精确版本」一种钉法,常见策略对比——
策略 做法 取舍 精确版本 v6.0.8升级显式可控,生产首选 浮动次版本 v6.0自动拿补丁,偶发行为变化 浮动大版本 v6省心,但需接受同大版本内的一切变更 latest latest总是最新,升级不可预期 nightly nightly当日主干,随时可能坏 本文采用精确版本
v6.0.8:自托管简历平台数据价值高,升级节奏应由运维者显式决定,而不是被docker compose pull隐式推动。
数据库镜像选 postgres:18——与官方自托管文档完全一致;v6 应用启动时自动执行数据库迁移(Drizzle ORM 管理),无需手工建表。实测两个镜像的体积(docker images 回显,DISK USAGE 列):
amruthpillai/reactive-resume v6.0.8 1.85GB
postgres 18 650MB
拉取命令:
docker pull amruthpillai/reactive-resume:v6.0.8
docker pull postgres:18
v6.0.8: Pulling from amruthpillai/reactive-resume
...
Status: Downloaded newer image for amruthpillai/reactive-resume:v6.0.8
docker.io/amruthpillai/reactive-resume:v6.0.8
⚠️ 网络说明:本次实测从 Docker Hub 直连拉取应用镜像时曾在解压阶段出现
read: connection reset by peer中断,重新执行docker pull断点续传后完成。若拉取反复失败,可改用 GitHub Container Registry(docker pull ghcr.io/reactive-resume/reactive-resume:v6.0.8,tag 与 Docker Hub 一致)或为本机 Docker 配置镜像加速/代理后重试。实测当日可用的渠道为 Docker Hub 直连重试 + 代理兜底。
三、前置条件
- 硬件:应用本体 1 vCPU + 1 GB 内存起步,与 PostgreSQL 同机部署建议 2 GB;磁盘 10 GB 起步(含图片上传空间)。
- 软件:Docker Engine 与 Docker Compose 插件已安装(见第一章版本核验);
openssl命令可用(用于生成密钥,Ubuntu 22.04 默认自带)。 - 端口:宿主机 8150 端口空闲。验证方法与实测回显:
ss -ltn | grep 8150 || echo "8150 端口空闲"
8150 端口空闲
- 无需安装 Chromium:v4 时代需要外挂浏览器渲染 PDF,v6 改用内置 Forme PDF 引擎在应用进程内直接渲染,官方文档明确「PDFs are rendered by the app itself, so there is no printer service to configure」。
- 无需手工初始化数据库:应用容器每次启动自动执行迁移(多实例并发启动时以数据库咨询锁协调,只有一个实例执行)。
四、部署步骤
本节从空目录开始,三份文件(.env、compose.yml)加一条启动命令完成部署。所有文件放在 /opt/reactive-resume/。
4.1 创建目录与 .env 配置
mkdir -p /opt/reactive-resume && cd /opt/reactive-resume
先生成两个 64 位十六进制密钥(会话签名密钥与个人密钥加密盐,生产环境必须各自独立生成):
openssl rand -hex 32
openssl rand -hex 32
0e267e3527f632dcbc4220a6c30ab02a44b6c4311cc28589c2a6298db1b57a6f
677df7be6cc66b50ea27265d90fde2be068143c0042946a059d4aafd495239c6
⚠️ 上面两行是本文实测实例的真实输出,仅作示例展示。你的实例必须用自己执行
openssl rand -hex 32的结果替换,且AUTH_SECRET与ENCRYPTION_SECRET不要相同:AUTH_SECRET变更会使全体用户会话失效、两步验证不可用;ENCRYPTION_SECRET变更使用户保存的个人 AI/网络访问密钥不可读。服务器在生产模式下会拒绝启动仍在使用.env.example示例值的AUTH_SECRET或ENCRYPTION_SECRET(官方安全设计)。
写入 .env(本文件全部值为实测实例所用):
cat > /opt/reactive-resume/.env <<'EOF'
APP_URL=http://<服务器IP或域名>:8150
POSTGRES_PASSWORD=q1w2e3r4
DATABASE_URL=postgresql://postgres:q1w2e3r4@postgres:5432/postgres
AUTH_SECRET=0e267e3527f632dcbc4220a6c30ab02a44b6c4311cc28589c2a6298db1b57a6f
ENCRYPTION_SECRET=677df7be6cc66b50ea27265d90fde2be068143c0042946a059d4aafd495239c6
EOF
关键项说明:
| 变量 | 本例取值 | 说明 |
|---|---|---|
APP_URL | http://<服务器IP或域名>:8150 | 必须与浏览器地址栏完全一致(含协议与端口)。它决定登录回跳地址、OAuth 回调、邮件链接与公开简历链接;不一致会导致登录后回跳错位、会话 Cookie 不生效。<服务器IP或域名> 按你的实际访问地址填写,如 http://192.168.1.10:8150 |
POSTGRES_PASSWORD | q1w2e3r4 | PostgreSQL 密码,与 DATABASE_URL 中的密码保持一致 |
DATABASE_URL | postgresql://postgres:q1w2e3r4@postgres:5432/postgres | 连接串中主机名 postgres 是 compose.yml 里的数据库服务名,容器内网解析;不要写 localhost(那指向应用容器自身) |
AUTH_SECRET | (64 位 hex) | 会话签名密钥,生产环境至少 32 字符,生命周期内保持不变 |
ENCRYPTION_SECRET | (64 位 hex) | 个人密钥加密盐,至少 32 字符;不启用用户自带 AI 密钥功能时暂不生效,但建议部署时一并设置以免日后变更 |
4.2 编写 compose.yml
cat > /opt/reactive-resume/compose.yml <<'EOF'
name: reactive-resume-6.0.8-stack
services:
postgres:
image: postgres:18
container_name: reactive-resume-6.0.8-postgres
restart: unless-stopped
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: q1w2e3r4
networks:
- app_network
volumes:
- postgres_data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
interval: 10s
timeout: 5s
retries: 10
reactive-resume:
image: amruthpillai/reactive-resume:v6.0.8
container_name: reactive-resume-6.0.8-server
restart: unless-stopped
networks:
- app_network
ports:
- "8150:3000"
env_file: .env
volumes:
- reactive_resume_data:/app/data
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
reactive_resume_data:
networks:
app_network:
driver: bridge
ipam:
config:
- subnet: 10.89.74.0/24
EOF
逐项说明:
| 配置项 | 作用 |
|---|---|
name: reactive-resume-6.0.8-stack | Compose 项目名。必须显式指定:多套编排共存于一台宿主机时,docker compose down 只会操作本项目名的资源,避免同名项目互删 |
container_name | 固定容器名,便于 docker logs/docker exec 直接引用 |
restart: unless-stopped | 开机自启、异常退出自动拉起;人工 docker stop 后不自动重启 |
healthcheck(postgres) | pg_isready 每 10 秒探测数据库就绪,最多重试 10 次 |
depends_on: service_healthy | 应用容器等数据库健康后再启动,避免迁移在数据库未就绪时执行失败 |
ports: "8150:3000" | 宿主机 8150 → 容器 3000 |
env_file: .env | 将环境变量注入应用容器 |
reactive_resume_data:/app/data | 上传文件持久化卷(头像、附件等) |
postgres_data:/var/lib/postgresql | 数据库数据持久化卷(PostgreSQL 18 的数据根目录) |
networks 显式网段 | 固定 10.89.74.0/24 网段,避免 Docker 随机分配与其他 compose 项目网段冲突;若该网段已被占用,换一个空闲 /24 即可 |
4.3 启动并等待健康
cd /opt/reactive-resume
docker compose up -d --wait --wait-timeout 240
实测回显(--wait 会阻塞直到两个服务都通过健康检查):
[+] Running 5/5
✔ Network reactive-resume-608-stack_app_network Created
✔ Volume "reactive-resume-608-stack_postgres_data" Created
✔ Volume "reactive-resume-608-stack_reactive_resume_data" Created
✔ Container reactive-resume-6.0.8-postgres Healthy
✔ Container reactive-resume-6.0.8-server Healthy
4.4 验证部署
三步验证:服务状态、启动日志、健康端点。
docker compose -f /opt/reactive-resume/compose.yml ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
reactive-resume-6.0.8-postgres postgres:18 "docker-entrypoint.s…" postgres 9 minutes ago Up 9 minutes (healthy) 5432/tcp
reactive-resume-6.0.8-server amruthpillai/reactive-resume:v6.0.8 "docker-entrypoint.s…" reactive-resume 9 minutes ago Up 9 minutes (healthy) 0.0.0.0:8150->3000/tcp, [::]:8150->3000/tcp
应用首启日志(实测,迁移与应用启动过程):
docker logs reactive-resume-6.0.8-server 2>&1 | head -4
Running database migrations...
Database migrations completed
Validating local storage path: /app/data
🚀 Up and running on http://localhost:3000
健康端点返回 200 与各依赖状态(curl 实测):
curl -s http://localhost:8150/api/health
{"service":"reactive-resume","version":"6.0.8","revision":"84b19140c7a6f80e1da0381a09f5597b56815d3f","status":"healthy","timestamp":"2026-10-29T14:09:01.939Z","uptime":"10.09s","database":{"status":"healthy","latencyMs":0},"storage":{"type":"local","status":"healthy","message":"Local filesystem storage is accessible and has read/write permission.","latencyMs":0}}
字段含义:status: healthy 且 database、storage 均为 healthy 即部署成功;若配置了 Redis 还会多出 redis 字段;任一依赖异常时整体返回 503,对应项显示 unhealthy。
4.5 创建账号
浏览器打开 APP_URL(本例 http://<服务器IP>:8150),点 Sign up 注册第一个账号:用户名 admin、邮箱任意、密码 q1w2e3r4(演示环境约定值)。注册后立即处于登录态。
未配置 SMTP 时验证邮件不会真正发出,而是写入应用日志(实测回显):
docker logs reactive-resume-6.0.8-server 2>&1 | grep "Verify your email"
SMTP not configured; skipping email send. { to: 'admin@example.com', subject: 'Verify your email' }
邮件内容只写日志、验证链接不真正投递——自托管单人使用可无视邮件验证直接使用全部功能。第一个账号建好后,若要禁止他人注册,在 .env 追加 FLAG_DISABLE_SIGNUPS=true 后 docker compose up -d 重建生效。
五、数据持久化说明
数据落在两个命名卷里,卷名自动带上项目名前缀(reactive-resume-6.0.8-stack 中的点被规范化,实测前缀为 reactive-resume-608-stack):
docker volume ls | grep reactive-resume
local reactive-resume-608-stack_postgres_data
local reactive-resume-608-stack_reactive_resume_data
| 卷 | 容器内挂载点 | 内容 |
|---|---|---|
reactive-resume-608-stack_postgres_data | /var/lib/postgresql | 全部业务数据:账号、简历、求职信、申请看板、AI 会话等 |
reactive-resume-608-stack_reactive_resume_data | /app/data | 上传文件:头像、简历照片、申请附件、助手附件 |
两个要点:
- 应用以
node用户(UID 1000)运行。若改用 bind mount(宿主目录直挂/app/data),目录属主必须可被 UID 1000 写入,否则启动时自检Local storage path is not writable直接退出;命名卷由 Docker 自动处理属主,无需关心。 - 重建容器不丢数据,
down -v会丢。docker compose down默认保留卷,down -v连卷一起删除——生产环境严禁对带卷编排执行-v,除非确认已有备份。
六、环境变量表
.env 中与应用相关的变量分两类:必填(缺一不可启动)与可选(按需追加)。本部署实际用到的前 5 项,可选行为按需启用:
| 变量 | 必填 | 默认 | 作用 |
|---|---|---|---|
APP_URL | 是 | — | 对外访问地址,必须与浏览器地址栏完全一致 |
DATABASE_URL | 是 | — | PostgreSQL 连接串,主机名用服务名 postgres |
AUTH_SECRET | 是 | — | 会话签名密钥,≥32 字符,生命周期内不变 |
POSTGRES_PASSWORD | 是 | — | 数据库密码(供 postgres 服务初始化,需与 DATABASE_URL 一致) |
ENCRYPTION_SECRET | 建议 | 未设置 | 个人 AI/网络访问密钥的加密盐,≥32 字符且与 AUTH_SECRET 不同 |
STORAGE_BACKEND | 否 | 自动(本形态为 local) | 上传存储后端:local/s3/blob/r2 |
LOCAL_STORAGE_PATH | 否 | /app/data | 本地存储目录,绝对路径 |
REDIS_URL | 否 | 未设置 | 可选 Redis;单机不配也能完整运行 |
FLAG_DISABLE_SIGNUPS | 否 | false | 设 true 关闭注册入口 |
SMTP_HOST/SMTP_PORT/SMTP_USER/SMTP_PASS/SMTP_FROM | 否 | 未设置 | 四项 SMTP_HOST/SMTP_USER/SMTP_PASS/SMTP_FROM 全配齐才发真实邮件 |
STRICT_SCHEMA_CHECK | 否 | false | 启动时校验数据库 schema,不匹配则拒绝启动 |
FLAG_DISABLE_API_RATE_LIMIT | 否 | false | 关闭 API 与认证限流(仅测试环境使用) |
以上为部署常用子集;服务器可读的全量变量(双域名、字体镜像、AI 供应商、特性开关、Vercel 部署别名等)逐条释义见《Reactive Resume 6.0.8 配置参数详解》。
七、配置参数说明
对第四章 compose.yml 中容易踩坑的三处再展开:
--wait与健康检查是部署验证的一部分。docker compose up -d --wait会等 postgres 的pg_isready通过、应用内置健康检查(调/api/health)通过才返回 0;任一服务起不来会以非零码退出并打印失败服务,比「起来再看日志」更适合写进自动化脚本。depends_on只保证顺序,不保证可用。condition: service_healthy让应用容器等数据库健康检查通过才创建,这是本编排能在空库上一次启动成功的关键;去掉该条件时应用可能抢跑,迁移失败退出(容器Restarting循环),等待restart: unless-stopped拉起重试直到数据库就绪。APP_URL与端口映射必须自洽。本例把 3000 映射到 8150,则APP_URL必须写成http://<主机>:8150;若前端再挂反向代理提供 HTTPS 域名,则APP_URL应改为https://resume.example.com并重启应用,否则登录回跳与公开页链接仍指向旧地址。
八、配置文件挂载
部署产生的三份东西与挂载关系:
| 文件/目录 | 位置 | 挂载方式 |
|---|---|---|
compose.yml | /opt/reactive-resume/compose.yml | 不挂载,是编排定义本身 |
.env | /opt/reactive-resume/.env | 经 env_file 注入应用容器环境变量,不落盘到容器内 |
| 数据卷 | Docker 管理的命名卷 | postgres_data→/var/lib/postgresql、reactive_resume_data→/app/data |
改 .env 后必须重建容器才生效(环境变量在容器创建时注入):
cd /opt/reactive-resume && docker compose up -d
Compose 检测到环境变化会只重建应用容器,数据库卷不受影响。
九、等价 docker run
不用 Compose 时,以下三条命令与上述编排完全等价(先建网络,再先后启动数据库与应用):
docker network create --driver bridge --subnet 10.89.74.0/24 reactive-resume-6.0.8-net
docker run -d \
--name reactive-resume-6.0.8-postgres \
--network reactive-resume-6.0.8-net \
--restart unless-stopped \
-e POSTGRES_DB=postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=q1w2e3r4 \
-v reactive-resume-608-stack_postgres_data:/var/lib/postgresql \
--health-cmd "pg_isready -U postgres -d postgres" \
--health-interval 10s \
--health-timeout 5s \
--health-retries 10 \
postgres:18
docker run -d \
--name reactive-resume-6.0.8-server \
--network reactive-resume-6.0.8-net \
--restart unless-stopped \
-p 8150:3000 \
--env-file /opt/reactive-resume/.env \
-v reactive-resume-608-stack_reactive_resume_data:/app/data \
amruthpillai/reactive-resume:v6.0.8
说明:--env-file 直接引用同一份 .env;docker run 没有 depends_on,需等数据库 healthy 后再执行第三条(docker ps 看 STATUS 出现 (healthy))。日常运维仍建议用 Compose,升级与重建更可控。
十、常用运维命令
以下命令均在 /opt/reactive-resume/ 目录内执行。
状态与日志:
docker compose ps # 两服务应显示 (healthy)
docker compose logs --tail=50 reactive-resume # 应用最近 50 行日志
docker compose logs -f postgres # 跟踪数据库日志
重启与停止:
docker compose restart reactive-resume # 只重启应用
docker compose stop # 停止(保留容器与卷)
docker compose down # 删除容器与网络,保留卷
docker compose down -v # ⚠️ 连卷一起删,等于清空全部数据,先备份
版本升级(官方流程,先备份再升级):
docker compose pull reactive-resume # 拉取新版本镜像
docker compose up -d reactive-resume # 只重建应用容器
docker compose logs -f reactive-resume # 观察新版本迁移与启动日志
应用启动时自动执行新版本的数据库迁移,PostgreSQL 容器保持运行不受影响。compose.yml 中的镜像 tag 改为目标版本(如 v6.0.9)后再执行上述命令;大版本升级(如未来 v6→v7)前先读官方迁移说明。
数据库备份与恢复(实测):
docker exec reactive-resume-6.0.8-postgres pg_dump -U postgres -d postgres --format=custom > /opt/reactive-resume/rr-backup.dump
ls -la /opt/reactive-resume/rr-backup.dump
-rw-r--r-- 1 root root 151127 Oct 29 22:18 /opt/reactive-resume/rr-backup.dump
验证备份可读(实测回显):
docker exec -i reactive-resume-6.0.8-postgres pg_restore --list < /opt/reactive-resume/rr-backup.dump | head -7
;
; Archive created at 2026-10-29 14:18:07 UTC
; dbname: postgres
; TOC Entries: 311
; Compression: gzip
; Dump Version: 1.16-0
; Format: CUSTOM
恢复到空库(灾难重建时使用):
docker exec -i reactive-resume-6.0.8-postgres pg_restore -U postgres -d postgres --clean --if-exists < /opt/reactive-resume/rr-backup.dump
上传文件备份:直接打包数据卷内容(本地存储形态下备份即拷贝 /app/data):
docker run --rm -v reactive-resume-608-stack_reactive_resume_data:/data -v /opt/reactive-resume:/backup alpine tar czf /backup/rr-uploads.tar.gz -C /data .
⚠️ 备份要同时覆盖数据库与上传文件两处,并保留一份
.env副本:没有原AUTH_SECRET,恢复出的实例会让所有会话失效、两步验证不可用;没有原ENCRYPTION_SECRET,用户保存的个人 AI 密钥不可读。
十一、常见问题(FAQ)
Q1:docker compose up 时应用容器反复重启,日志报 Database migrations failed 或 ECONNREFUSED?
DATABASE_URL 错误或数据库不可达。逐项核对:主机名必须是服务名 postgres(不是 localhost);密码与 POSTGRES_PASSWORD 一致;密码含特殊字符时要在连接串里做 URL 编码。实测在本编排中应用由 depends_on: service_healthy 保护,正常配置下不会出现抢跑。
Q2:/api/health 返回 503?
看响应 JSON 里哪个依赖是 unhealthy:database 异常查数据库连接与状态;storage 异常查 /app/data 挂载可写性(UID 1000)或 S3 配置;redis 异常查 REDIS_URL。修复对应依赖后健康检查在 30 秒内自动恢复。实测正常实例返回 database/storage 双 healthy(见 4.4 节回显)。
Q3:登录后跳回登录页,或登录后页面功能异常?
APP_URL 与浏览器实际访问地址不一致(协议、域名、端口任一不符都会导致会话 Cookie 不生效)。把 .env 的 APP_URL 改成与地址栏完全一致的值后 docker compose up -d 重建。
Q4:拉取镜像时出现 failed to copy: ... connection reset by peer?
网络中断导致层下载失败,重新执行 docker pull 断点续传即可(本次实测即靠重试完成)。反复失败时改用 GHCR 路径或配置代理/镜像加速(见第二章 ⚠️ 网络说明)。
Q5:升级后上传的头像、附件消失了?
/app/data 没有挂持久卷,历史数据留在旧容器里随重建丢失。按第四章编排补上 reactive_resume_data:/app/data 卷;此前未落卷的旧文件无法找回,重建后重新上传。
Q6:想在生产收口注册入口?
第一个账号创建完成后,在 .env 追加 FLAG_DISABLE_SIGNUPS=true 并 docker compose up -d。已注册账号不受影响,新访客无法注册(邮箱、社交登录、来宾模式三条路全关)。
十二、参考链接
- 官方自托管文档(Docker):https://github.com/reactive-resume/reactive-resume/blob/main/docs/self-hosting/docker.mdx
- 官方环境变量参考:https://github.com/reactive-resume/reactive-resume/blob/main/docs/self-hosting/environment-variables.mdx
- GitHub 仓库:https://github.com/reactive-resume/reactive-resume
- 相关篇目:《Reactive Resume 介绍与选型指南》 · 《Reactive Resume 6.0.8 配置参数详解》 · 《Reactive Resume 6.0.8 API 使用详解》