-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
168 lines (163 loc) · 7.95 KB
/
docker-compose.yml
File metadata and controls
168 lines (163 loc) · 7.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
services:
backend:
image: involutionhell-backend:latest
pull_policy: never
container_name: involution-hell-backend
restart: always
env_file:
- .env
environment:
SERVER_PORT: ${SERVER_PORT:-8080}
SPRING_APPLICATION_NAME: ${SPRING_APPLICATION_NAME:-backend}
# 数据库连接(使用 PG* 变量,与 application.properties 保持一致)
SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL:-jdbc:postgresql://postgres:5432/involution_hell}
PGUSER: ${PGUSER:-involution}
PGPASSWORD: ${PGPASSWORD:-change_me}
SPRING_SQL_INIT_MODE: ${SPRING_SQL_INIT_MODE:-always}
# GitHub OAuth2
AUTH_GITHUB_ID: ${AUTH_GITHUB_ID:-}
AUTH_GITHUB_SECRET: ${AUTH_GITHUB_SECRET:-}
AUTH_SECRET: ${AUTH_SECRET:-}
# OAuth 回调前缀:JustAuth 的 redirect-uri 用 ${AUTH_URL:http://localhost:3000}/api/auth/callback/github
# 拼接(见 application.properties)。当前 compose 已通过 env_file: .env 和
# environment 把 AUTH_URL 注入容器;如果生产上仍是旧值/回退到 localhost,
# 通常是因为容器未重建,环境变量变更需要 recreate 后才会生效,否则会报 redirect_uri_mismatch。
AUTH_URL: ${AUTH_URL:-https://involutionhell.com}
# AI 模型(默认 GLM-4.6V-Flash 免费 fallback,OpenAI 兼容协议)
# 变量名沿用 OPENAI_*:Java 用的是 /chat/completions 规范协议,URL+Key+Model
# 三件套指哪打哪,OpenAI / 智谱 / Anthropic-compat 任选,无需改代码。
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
OPENAI_API_URL: ${OPENAI_API_URL:-https://open.bigmodel.cn/api/paas/v4}
OPENAI_MODEL: ${OPENAI_MODEL:-glm-4.6v-flash}
# Actuator
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: ${MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE:-health}
MANAGEMENT_ENDPOINT_HEALTH_PROBES_ENABLED: ${MANAGEMENT_ENDPOINT_HEALTH_PROBES_ENABLED:-true}
# GA4 凭证文件路径:容器内统一放 /app/ga4-sa-key.json,下面 volume 挂载主机文件进来。
# 主机文件不存在时 Ga4ClientConfig 会降级到 stub(/analytics/top-docs 返回 503),不影响启动。
GA4_CREDENTIALS_PATH: ${GA4_CREDENTIALS_PATH:-/app/ga4-sa-key.json}
# GitHub REST API token:DocHistoryService 调 /repos/.../commits 需要,
# 匿名限流 60/hour,带 token 5000/hour。未设置时 service 仍可用,只是容易被限流。
GITHUB_TOKEN: ${GITHUB_TOKEN:-}
ports:
- "8080:8080"
volumes:
# 挂载主机 ga4-sa-key.json 到容器,避免把 service account 私钥打进镜像。
# 主机文件必须存在(可以是空文件,Spring 会识别为无效走 stub),否则 docker compose up 会失败。
- ./ga4-sa-key.json:/app/ga4-sa-key.json:ro
healthcheck:
test: ["CMD-SHELL", "curl -fsS \"http://127.0.0.1:${SERVER_PORT:-8080}/actuator/health\" | grep '\"status\":\"UP\"' >/dev/null || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
networks:
- InvolutionHell-net
# 让容器内可用 host.docker.internal 访问宿主机(ChatBot 的 alert webhook
# 绑在宿主机 0.0.0.0:6200)。Linux Docker 不自带这个别名,必须显式声明。
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:18-alpine
container_name: involution-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB:-involution_hell}
POSTGRES_USER: ${POSTGRES_USER:-involution}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change_me}
# 只 bind 到 loopback,不再暴露公网。
# Spring Boot / pgAdmin / 自动备份容器都在同 docker network,走容器名 postgres:5432 即可。
# 历史上是 "5432:5432" 让 Vercel build 脚本远程查 doc_contributors 生成排行榜,
# 现已改走后端 /api/public/leaderboard,DB 不再需要对外开放。
ports:
- "127.0.0.1:5432:5432"
volumes:
- ./docker/init-db:/docker-entrypoint-initdb.d
- involution-postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-involution} -d ${POSTGRES_DB:-involution_hell}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- InvolutionHell-net
# pgAdmin:PostgreSQL 的 Web GUI,带完整的备份/恢复按钮。
# 登录 http://<host>:8082,预注册服务器见 docker/pgadmin/servers.json,
# 密码通过 /pgpass 自动填充,不需要每次手输。
# 备份卷挂到 /var/lib/pgadmin/storage/.../backups,在 Restore 对话框里直接看得到。
pgadmin:
image: dpage/pgadmin4:latest
container_name: involution-pgadmin
restart: unless-stopped
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL:-admin@involutionhell.com}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD:-change_me}
# pgAdmin 保持 SERVER_MODE=False(desktop / single-user,无登录页)——
# 关键前提:**外层 Caddy 做 forward_auth**,只有带合法 admin satoken
# cookie 的请求才被代理到这里。直接对公网暴露 8082 绝对不行。
PGADMIN_CONFIG_SERVER_MODE: "False"
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
# pgAdmin 被 iframe 嵌入在 involutionhell.com 主站的 /admin/database 页里,
# 流量路径:involutionhell.com(Vercel 前端) → iframe → api.involutionhell.com/admin/pgadmin/*
# SCRIPT_NAME 让 pgAdmin 生成的所有 URL 自带 /admin/pgadmin 前缀,
# X_FRAME_OPTIONS 清空让 Caddy 层自己控制 CSP frame-ancestors。
SCRIPT_NAME: "/admin/pgadmin"
PGADMIN_CONFIG_X_FRAME_OPTIONS: "''"
PGADMIN_CONFIG_WTF_CSRF_SSL_STRICT: "False"
ports:
- "127.0.0.1:8082:80"
volumes:
- pgadmin-data:/var/lib/pgadmin
- ./docker/pgadmin/servers.json:/pgadmin4/servers.json:ro
# pgpass 主机文件必须是 UID 5050 所有且 0600,否则 pgAdmin 拒绝加载。
# 用 `sudo chown 5050:5050 docker/pgadmin/pgpass && sudo chmod 600 …` 设好。
- ./docker/pgadmin/pgpass:/tmp/pgpass
# 备份卷挂到容器内 /backups(只读)。SERVER_MODE=True 下 /var/lib/pgadmin/
# storage/<email>/ 目录由 pgAdmin 运行时自建并校验 5050 所有权,把 root
# 所有的 pg-backups 挂进去会触发 "user does not have permission" 启动失败。
# 在 pgAdmin Restore 对话框里手填路径 /backups/daily/xxx.dump 即可。
- pg-backups:/backups:ro
depends_on:
postgres:
condition: service_healthy
networks:
- InvolutionHell-net
# 自动定时备份:每天 03:00 对 postgres 容器做 pg_dump(custom format),
# 输出到共享卷 pg-backups,pgAdmin 能直接在 Restore 对话框里看到这些文件。
# 保留最近 30 天日备 / 8 周周备 / 12 个月月备。
pg-backup:
image: prodrigestivill/postgres-backup-local:18-alpine
container_name: involution-pg-backup
restart: unless-stopped
environment:
POSTGRES_HOST: postgres
POSTGRES_DB: ${POSTGRES_DB:-involution_hell}
POSTGRES_USER: ${POSTGRES_USER:-involution}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change_me}
# -Fc 产出 custom 格式(.dump),pgAdmin 右键 Restore 直接一键恢复;
# 镜像包装脚本默认会 gzip,这里必须显式设 BACKUP_SUFFIX=.dump 且不加 gzip
# 选项,让镜像按 custom 格式直接落盘。
POSTGRES_EXTRA_OPTS: "-Fc --blobs"
BACKUP_SUFFIX: ".dump"
BACKUP_COMPRESS: "none"
SCHEDULE: "@daily"
BACKUP_KEEP_DAYS: 30
BACKUP_KEEP_WEEKS: 8
BACKUP_KEEP_MONTHS: 12
HEALTHCHECK_PORT: 8080
volumes:
- pg-backups:/backups
depends_on:
postgres:
condition: service_healthy
networks:
- InvolutionHell-net
networks:
InvolutionHell-net:
driver: bridge
volumes:
involution-postgres-data:
pgadmin-data:
pg-backups: