publish reactive resume install packages

This commit is contained in:
2026-05-18 23:47:24 +08:00
parent f77cf67b76
commit 663143a30a
19 changed files with 620 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# ===== Reactive Resume clean install environment =====
# Copy this file to .env, then replace every CHANGE_ME / YOUR_* value.
TZ=Asia/Shanghai
# Public URL behind your reverse proxy.
APP_URL=https://YOUR_DOMAIN.example.com
# Local debug binding on this Docker host.
# Use 127.0.0.1 if only frpc / local reverse proxy should reach the app.
LOCAL_BIND_IP=127.0.0.1
LOCAL_APP_PORT=CHANGE_ME_LOCAL_PORT
# PostgreSQL.
POSTGRES_DB=reactive_resume
POSTGRES_USER=reactive_resume
POSTGRES_PASSWORD=CHANGE_ME_POSTGRES_PASSWORD
DATABASE_URL=postgresql://reactive_resume:CHANGE_ME_POSTGRES_PASSWORD@postgres:5432/reactive_resume
# Generate with: openssl rand -hex 32
AUTH_SECRET=CHANGE_ME_64_HEX_AUTH_SECRET
ENCRYPTION_SECRET=CHANGE_ME_64_HEX_ENCRYPTION_SECRET
# Optional email/auth/storage/AI settings can be enabled later.
BETTER_AUTH_API_KEY=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=
OAUTH_PROVIDER_NAME=
OAUTH_CLIENT_ID=
OAUTH_CLIENT_SECRET=
OAUTH_DISCOVERY_URL=
OAUTH_AUTHORIZATION_URL=
OAUTH_TOKEN_URL=
OAUTH_USER_INFO_URL=
OAUTH_DYNAMIC_CLIENT_REDIRECT_HOSTS=
OAUTH_SCOPES=
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
SMTP_FROM=Reactive Resume <noreply@YOUR_DOMAIN.example.com>
SMTP_SECURE=false
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_REGION=us-east-1
S3_ENDPOINT=
S3_BUCKET=
S3_FORCE_PATH_STYLE=false
REDIS_URL=
CLOUDFLARE_ACCOUNT_ID=
CLOUDFLARE_API_TOKEN=
FLAG_DISABLE_SIGNUPS=false
FLAG_DISABLE_EMAIL_AUTH=false
FLAG_DISABLE_IMAGE_PROCESSING=false
FLAG_ALLOW_UNSAFE_AI_BASE_URL=false

View File

@@ -0,0 +1,38 @@
# Reactive Resume 纯净迁移安装包
这是一套不绑定具体域名、端口、FRP 服务器或密码的纯净安装包,适合迁移到新服务器或新 NAS 前作为模板使用。
## 文件说明
- `compose.yml`:通用 Linux / Docker Compose 部署版
- `compose-Nas.yml`:威联通 QNAP QTS / Container Station 部署模板
- `frpc.yaml`:通用服务器版 frpc 配置模板
- `.env.example`:通用服务器版环境变量模板
## 通用服务器部署
1. 复制环境变量文件:
```bash
cp .env.example .env
```
2. 编辑 `.env` 和 `frpc.yaml`,把所有 `CHANGE_ME` / `YOUR_*` 改成真实值。
3. 启动:
```bash
docker compose -f compose.yml up -d
```
## QNAP NAS 部署
1. 编辑 `compose-Nas.yml` 顶部注释中的路径、域名、端口、FRP 服务器等待填写项。
2. 在 QTS Container Station 中导入 `compose-Nas.yml`。
3. 启动后,确认 app 和 frpc 都为 healthy / running。
## 注意
- `AUTH_SECRET` 和 `ENCRYPTION_SECRET` 必须使用长期固定值,迁移后不要随意更换。
- `APP_URL` 必须与反向代理对外访问域名一致,例如 `https://resume.example.com`。
- FRP 的 `remotePort` 需要与公网服务器 Nginx Proxy Manager / 反向代理转发端口一致。

View File

@@ -0,0 +1,97 @@
# Reactive Resume / QNAP QTS 纯净模板。
# 使用前请填写:
# - NAS 数据目录,例如 /share/Container/Reactive_Resume
# - APP_URL例如 https://resume.example.com
# - 本地访问端口,例如 3004
# - PostgreSQL 密码、AUTH_SECRET、ENCRYPTION_SECRET
# - FRP serverAddr/serverPort/token/proxy name/remotePort
name: reactive-resume-nas
services:
reactive_resume_permissions:
image: alpine:3.20
restart: "no"
command: ["sh", "-c", "mkdir -p /app/data && chown -R 1000:1000 /app/data"]
volumes:
# 待填写:改成你的 NAS 数据目录。
- /share/Container/CHANGE_ME_REACTIVE_RESUME/data/uploads:/app/data
reactive_resume_db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: reactive_resume
POSTGRES_USER: reactive_resume
POSTGRES_PASSWORD: CHANGE_ME_POSTGRES_PASSWORD
volumes:
# 待填写:改成你的 NAS 数据目录。
- /share/Container/CHANGE_ME_REACTIVE_RESUME/data/postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U reactive_resume -d reactive_resume"]
interval: 10s
timeout: 5s
retries: 10
reactive_resume_app:
image: amruthpillai/reactive-resume:latest
restart: unless-stopped
depends_on:
reactive_resume_permissions:
condition: service_completed_successfully
reactive_resume_db:
condition: service_healthy
ports:
# 待填写NAS 本地访问端口。
- "CHANGE_ME_LOCAL_APP_PORT:3000"
volumes:
# 待填写:改成你的 NAS 数据目录。
- /share/Container/CHANGE_ME_REACTIVE_RESUME/data/uploads:/app/data
environment:
TZ: Asia/Shanghai
APP_URL: https://YOUR_DOMAIN.example.com
DATABASE_URL: postgresql://reactive_resume:CHANGE_ME_POSTGRES_PASSWORD@reactive_resume_db:5432/reactive_resume
AUTH_SECRET: CHANGE_ME_64_HEX_AUTH_SECRET
ENCRYPTION_SECRET: CHANGE_ME_64_HEX_ENCRYPTION_SECRET
SMTP_FROM: Reactive Resume <noreply@YOUR_DOMAIN.example.com>
SMTP_PORT: "587"
SMTP_SECURE: "false"
FLAG_DISABLE_SIGNUPS: "false"
FLAG_DISABLE_EMAIL_AUTH: "false"
FLAG_DISABLE_IMAGE_PROCESSING: "false"
FLAG_ALLOW_UNSAFE_AI_BASE_URL: "false"
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://127.0.0.1:3000/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
interval: 30s
timeout: 10s
retries: 8
start_period: 30s
reactive_resume_frpc:
image: snowdreamtech/frpc:latest
restart: unless-stopped
entrypoint: ["/bin/sh"]
command:
- -c
- |
cat > /tmp/frpc.toml <<'EOF'
serverAddr = "YOUR_FRP_SERVER_IP_OR_DOMAIN"
serverPort = CHANGE_ME_FRP_SERVER_PORT
auth.method = "token"
auth.token = "CHANGE_ME_FRP_TOKEN"
transport.poolCount = 5
transport.heartbeatTimeout = -1
[[proxies]]
name = "CHANGE_ME_PROXY_NAME"
type = "tcp"
localIP = "reactive_resume_app"
localPort = 3000
remotePort = CHANGE_ME_REMOTE_PORT
EOF
exec frpc -c /tmp/frpc.toml
depends_on:
reactive_resume_app:
condition: service_healthy

View File

@@ -0,0 +1,72 @@
# Reactive Resume 通用服务器纯净模板。
# 使用前请先复制 .env.example 为 .env并填写域名、端口、数据库密码和密钥。
name: reactive-resume
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- resume_net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
reactive-resume:
image: amruthpillai/reactive-resume:latest
restart: unless-stopped
env_file:
- .env
ports:
# 待填写LOCAL_BIND_IP / LOCAL_APP_PORT 在 .env 中配置。
# 例127.0.0.1:3004:3000仅允许本机反代或 frpc 访问。
- "${LOCAL_BIND_IP}:${LOCAL_APP_PORT}:3000"
volumes:
- reactive_resume_data:/app/data
networks:
- resume_net
depends_on:
postgres:
condition: service_healthy
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://127.0.0.1:3000/api/health').then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1));",
]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
frpc:
image: fatedier/frpc:v0.68.0
restart: unless-stopped
command: ["-c", "/etc/frp/frpc.yaml"]
volumes:
# 待填写frpc.yaml 中配置 FRP 服务器、token、remotePort。
- ./frpc.yaml:/etc/frp/frpc.yaml:ro
networks:
- resume_net
depends_on:
reactive-resume:
condition: service_healthy
networks:
resume_net:
driver: bridge
volumes:
postgres_data:
reactive_resume_data:

View File

@@ -0,0 +1,22 @@
# Reactive Resume frpc 纯净模板。
# 使用前把所有 CHANGE_ME / YOUR_* 改成真实值。
serverAddr: "YOUR_FRP_SERVER_IP_OR_DOMAIN"
serverPort: CHANGE_ME_FRP_SERVER_PORT
auth:
method: "token"
token: "CHANGE_ME_FRP_TOKEN"
transport:
poolCount: 5
heartbeatTimeout: -1
proxies:
- name: "CHANGE_ME_PROXY_NAME"
type: "tcp"
# Docker Compose 内部服务名,通常不用改。
localIP: "reactive-resume"
localPort: 3000
# 待填写:公网 FRP 远程端口,需与反向代理 forward port 一致。
remotePort: CHANGE_ME_REMOTE_PORT

View File

@@ -0,0 +1,50 @@
TZ=Asia/Shanghai
APP_URL=https://isiseg.huijutec.cn
# Local debug access only: http://127.0.0.1:3004
LOCAL_BIND_IP=127.0.0.1
LOCAL_APP_PORT=3004
POSTGRES_DB=reactive_resume
POSTGRES_USER=reactive_resume
POSTGRES_PASSWORD=2ed1869944c609f070699bdf8c92194f
DATABASE_URL=postgresql://reactive_resume:2ed1869944c609f070699bdf8c92194f@postgres:5432/reactive_resume
AUTH_SECRET=9ef1720ee316f9316241bdc84f5dfad99b52f139b48880300942ee61d81b7cda
ENCRYPTION_SECRET=20851888c2a96b11f1f6fc21b4eeb70f1e8258f2d0d414be8bace65eaff289ae
BETTER_AUTH_API_KEY=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=
OAUTH_PROVIDER_NAME=
OAUTH_CLIENT_ID=
OAUTH_CLIENT_SECRET=
OAUTH_DISCOVERY_URL=
OAUTH_AUTHORIZATION_URL=
OAUTH_TOKEN_URL=
OAUTH_USER_INFO_URL=
OAUTH_DYNAMIC_CLIENT_REDIRECT_HOSTS=
OAUTH_SCOPES=
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
SMTP_FROM=Reactive Resume <noreply@isiseg.huijutec.cn>
SMTP_SECURE=false
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_REGION=us-east-1
S3_ENDPOINT=
S3_BUCKET=
S3_FORCE_PATH_STYLE=false
REDIS_URL=
CLOUDFLARE_ACCOUNT_ID=
CLOUDFLARE_API_TOKEN=
FLAG_DISABLE_SIGNUPS=false
FLAG_DISABLE_EMAIL_AUTH=false
FLAG_DISABLE_IMAGE_PROCESSING=false
FLAG_ALLOW_UNSAFE_AI_BASE_URL=false

View File

@@ -0,0 +1,35 @@
# Reactive Resume isiseg.huijutec.cn 直接运行安装包
这套包已经按 `https://isiseg.huijutec.cn` 和 FRP `remotePort = 10004` 预置,可以在当前服务器上直接运行。
## 启动
```bash
docker compose -f compose.yml up -d
```
启动后:
- 本机调试地址:`http://127.0.0.1:3004`
- 公网访问地址:`https://isiseg.huijutec.cn`
- FRP 映射:本地 `reactive-resume:3000` -> 公网服务器 `10004`
## 反向代理要求
公网服务器上的 Nginx Proxy Manager / 反向代理应配置:
- Domain Names`isiseg.huijutec.cn`
- Scheme`http`
- Forward Hostname / IP`82.157.255.195`
- Forward Port`10004`
- Websockets Support开启
- SSL按现有 huijutec.cn 域名策略配置
## 数据
Compose 会创建独立项目名 `reactive-resume-isiseg`,默认使用 Docker named volumes
- `reactive-resume-isiseg_postgres_data`
- `reactive-resume-isiseg_reactive_resume_data`
如需迁移数据,请备份这些 volumes。

View File

@@ -0,0 +1,66 @@
name: reactive-resume-isiseg
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- resume_net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
reactive-resume:
image: amruthpillai/reactive-resume:latest
restart: unless-stopped
env_file:
- .env
ports:
- "${LOCAL_BIND_IP}:${LOCAL_APP_PORT}:3000"
volumes:
- reactive_resume_data:/app/data
networks:
- resume_net
depends_on:
postgres:
condition: service_healthy
healthcheck:
test:
[
"CMD",
"node",
"-e",
"fetch('http://127.0.0.1:3000/api/health').then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1));",
]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
frpc:
image: fatedier/frpc:v0.68.0
restart: unless-stopped
command: ["-c", "/etc/frp/frpc.yaml"]
volumes:
- ./frpc.yaml:/etc/frp/frpc.yaml:ro
networks:
- resume_net
depends_on:
reactive-resume:
condition: service_healthy
networks:
resume_net:
driver: bridge
volumes:
postgres_data:
reactive_resume_data:

View File

@@ -0,0 +1,17 @@
serverAddr: "82.157.255.195"
serverPort: 7000
auth:
method: "token"
token: "en.xjtu.edu.cn"
transport:
poolCount: 5
heartbeatTimeout: -1
proxies:
- name: "reactive-resume-isiseg"
type: "tcp"
localIP: "reactive-resume"
localPort: 3000
remotePort: 10004

View File

@@ -0,0 +1,31 @@
# Reactive Resume isiseg.huijutec.cn / QNAP NAS 安装包
这套包面向威联通 QNAP QTS / Container Station已按以下参数预置
- NAS 数据目录:`/share/Container/Reactive_Resume_Isiseg`
- 本地端口:`3004:3000`
- 公网域名:`https://isiseg.huijutec.cn`
- FRP 服务器:`82.157.255.195:7000`
- FRP remotePort`10004`
## 部署
1. 在 QTS 中确认目录可创建:`/share/Container/Reactive_Resume_Isiseg`
2. 打开 Container Station导入 `compose-Nas.yml`
3. 启动项目
4. 访问 `https://isiseg.huijutec.cn`
## 反向代理要求
公网服务器上的 Nginx Proxy Manager / 反向代理应配置:
- Domain Names`isiseg.huijutec.cn`
- Scheme`http`
- Forward Hostname / IP`82.157.255.195`
- Forward Port`10004`
- Websockets Support开启
## 数据目录
- PostgreSQL`/share/Container/Reactive_Resume_Isiseg/data/postgres`
- 上传与本地存储:`/share/Container/Reactive_Resume_Isiseg/data/uploads`

View File

@@ -0,0 +1,119 @@
# Reactive Resume isiseg.huijutec.cn / QNAP QTS 直接部署版。
# 本文件已按 /share/Container/Reactive_Resume_Isiseg、
# https://isiseg.huijutec.cn、192.168.31.5:3004 本地访问、
# frpc 公网映射 82.157.255.195:10004 预置。
name: reactive-resume-isiseg-nas
services:
reactive_resume_permissions:
image: alpine:3.20
restart: "no"
command: ["sh", "-c", "mkdir -p /app/data && chown -R 1000:1000 /app/data"]
volumes:
- /share/Container/Reactive_Resume_Isiseg/data/uploads:/app/data
reactive_resume_db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: reactive_resume
POSTGRES_USER: reactive_resume
POSTGRES_PASSWORD: 5b341c0ca29fefd6d648661150c00fa4
volumes:
- /share/Container/Reactive_Resume_Isiseg/data/postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U reactive_resume -d reactive_resume"]
interval: 10s
timeout: 5s
retries: 10
reactive_resume_app:
image: amruthpillai/reactive-resume:latest
restart: unless-stopped
depends_on:
reactive_resume_permissions:
condition: service_completed_successfully
reactive_resume_db:
condition: service_healthy
ports:
- "3004:3000"
volumes:
- /share/Container/Reactive_Resume_Isiseg/data/uploads:/app/data
environment:
TZ: Asia/Shanghai
APP_URL: https://isiseg.huijutec.cn
DATABASE_URL: postgresql://reactive_resume:5b341c0ca29fefd6d648661150c00fa4@reactive_resume_db:5432/reactive_resume
AUTH_SECRET: c76b0eaf79f731e9ee95918dc69d41696aec9d1deffeabc122944898037bfab1
ENCRYPTION_SECRET: df3a460fa2f92f6e8765927a169322980e18f63a88fbcfedb090819b5afb2408
BETTER_AUTH_API_KEY: ""
GOOGLE_CLIENT_ID: ""
GOOGLE_CLIENT_SECRET: ""
GITHUB_CLIENT_ID: ""
GITHUB_CLIENT_SECRET: ""
LINKEDIN_CLIENT_ID: ""
LINKEDIN_CLIENT_SECRET: ""
OAUTH_PROVIDER_NAME: ""
OAUTH_CLIENT_ID: ""
OAUTH_CLIENT_SECRET: ""
OAUTH_DISCOVERY_URL: ""
OAUTH_AUTHORIZATION_URL: ""
OAUTH_TOKEN_URL: ""
OAUTH_USER_INFO_URL: ""
OAUTH_DYNAMIC_CLIENT_REDIRECT_HOSTS: ""
OAUTH_SCOPES: ""
SMTP_HOST: ""
SMTP_PORT: "587"
SMTP_USER: ""
SMTP_PASS: ""
SMTP_FROM: "Reactive Resume <noreply@isiseg.huijutec.cn>"
SMTP_SECURE: "false"
S3_ACCESS_KEY_ID: ""
S3_SECRET_ACCESS_KEY: ""
S3_REGION: us-east-1
S3_ENDPOINT: ""
S3_BUCKET: ""
S3_FORCE_PATH_STYLE: "false"
REDIS_URL: ""
CLOUDFLARE_ACCOUNT_ID: ""
CLOUDFLARE_API_TOKEN: ""
FLAG_DISABLE_SIGNUPS: "false"
FLAG_DISABLE_EMAIL_AUTH: "false"
FLAG_DISABLE_IMAGE_PROCESSING: "false"
FLAG_ALLOW_UNSAFE_AI_BASE_URL: "false"
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://127.0.0.1:3000/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
interval: 30s
timeout: 10s
retries: 8
start_period: 30s
reactive_resume_frpc:
image: snowdreamtech/frpc:latest
restart: unless-stopped
entrypoint: ["/bin/sh"]
command:
- -c
- |
cat > /tmp/frpc.toml <<'EOF'
serverAddr = "82.157.255.195"
serverPort = 7000
auth.method = "token"
auth.token = "en.xjtu.edu.cn"
transport.poolCount = 5
transport.heartbeatTimeout = -1
[[proxies]]
name = "Reactive_Resume_Isiseg_NAS"
type = "tcp"
localIP = "reactive_resume_app"
localPort = 3000
remotePort = 10004
EOF
exec frpc -c /tmp/frpc.toml
depends_on:
reactive_resume_app:
condition: service_healthy