Files
FruitServer/docker-compose.yml
T
Zhou Weidong 20f19b13f2 fix(deploy): admin-api 端口改为对局域网开放以支持内网联调
compose 里 admin-api 原先把宿主端口绑在 127.0.0.1,只有本机能访问;
Web 后台在另一台机器上,走局域网连不上 8080,联调起不来。

改为监听局域网(8080:8080)。管理端仍然"仅内网":不在路由器做端口转发,
外网探测 154.16.27.173:8080 为 Connection refused,与
specs 04-部署架构 §四「管理后台仅内网/VPN 可访问」一致。

门禁:docker compose config 校验通过;tools/smoke.sh 全部 PASS;
内网实测 http://192.168.31.250:8080/healthz 与 /doc.html 均 200。
本次只改编排文件,未触碰 Java 代码,故未重跑 mvn test。
2026-10-16 16:25:26 +08:00

149 lines
5.2 KiB
YAML

# Author: fruit.com.cn
#
# 办公室单机部署(docs/04-部署架构.md §三 精简方案 + §五 第一阶段用 Compose):
# app-api(8081) + admin-api(8080,只绑本机) + transcode-worker + PostgreSQL 18 + Redis
# 转码 worker 与在线服务**同机但独立进程/容器**(§8.5 隔离要求:不抢在线服务资源)。
#
# 用法(目标主机需要 Docker + Compose):
# cp .env.example .env # 填密钥与数据库密码
# docker compose up -d --build
# tools/smoke.sh
#
# 本文件在本机**未验证**(本机没有 Docker),见 DEPLOY.md「未在本机验证的部分」。
services:
# ─────────── 基础设施 ───────────
db:
image: postgres:18-alpine
container_name: fruitshorts-db
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_NAME:-fruitshorts}
POSTGRES_USER: ${DB_USER:-fruitshorts}
POSTGRES_PASSWORD: ${DB_PASSWORD:?数据库密码必填,见 .env.example}
# 中文与印尼语内容需要 UTF-8(镜像默认已是 UTF8,这里显式一次)
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
volumes:
# PostgreSQL 18 起镜像把数据放在 /var/lib/postgresql/<major>/,卷必须挂到父目录
- db-data:/var/lib/postgresql
# 首次启动自动建表 + 造种子数据;顺序即文件名顺序(脚本本身幂等,可重复执行)
- ./sql/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro
- ./sql/schema-phase1.sql:/docker-entrypoint-initdb.d/02-schema-phase1.sql:ro
- ./sql/partition-maintenance.sql:/docker-entrypoint-initdb.d/03-partition-maintenance.sql:ro
- ./sql/data.sql:/docker-entrypoint-initdb.d/04-data.sql:ro
- ./sql/data-phase1.sql:/docker-entrypoint-initdb.d/05-data-phase1.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-fruitshorts} -d ${DB_NAME:-fruitshorts}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
# 不映射端口:只有同网络的容器需要访问;本机要连库时再放开 5432
expose:
- "5432"
redis:
# 第一阶段还没有代码依赖 Redis(C2 才接缓存与限流),先把基础设施就位,
# 免得上线时再改编排。要持久化就留 volume,纯缓存场景可去掉。
image: redis:7-alpine
container_name: fruitshorts-redis
restart: unless-stopped
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 10
expose:
- "6379"
# ─────────── 应用 ───────────
app-api:
build:
context: .
args:
MODULE: fruitshorts-app-api
image: fruitshorts/app-api:latest
container_name: fruitshorts-app-api
restart: unless-stopped
env_file: .env
environment:
SERVER_PORT: "8081"
# 默认连编排里的 db;要连外部库就在 .env 里覆盖 DB_URL
DB_URL: ${DB_URL:-jdbc:postgresql://db:5432/${DB_NAME:-fruitshorts}}
ports:
- "8081:8081"
volumes:
# 媒资落盘:三个服务共享同一个卷
- ./data/uploads:/data/uploads
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8081/healthz || exit 1"]
interval: 30s
timeout: 5s
start_period: 40s
retries: 3
admin-api:
build:
context: .
args:
MODULE: fruitshorts-admin-api
image: fruitshorts/admin-api:latest
container_name: fruitshorts-admin-api
restart: unless-stopped
env_file: .env
environment:
SERVER_PORT: "8080"
DB_URL: ${DB_URL:-jdbc:postgresql://db:5432/${DB_NAME:-fruitshorts}}
ports:
# docs/12-上线检查清单「管理端仅内网」:只对局域网开放;不在路由器做端口转发,公网访问不到
- "8080:8080"
volumes:
- ./data/uploads:/data/uploads
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8080/healthz || exit 1"]
interval: 30s
timeout: 5s
start_period: 40s
retries: 3
transcode-worker:
build:
context: .
args:
MODULE: fruitshorts-transcode-worker
# worker 镜像里装 ffmpeg,两个 API 镜像不装(省 80MB)
INSTALL_FFMPEG: "true"
image: fruitshorts/transcode-worker:latest
container_name: fruitshorts-transcode-worker
restart: unless-stopped
env_file: .env
environment:
DB_URL: ${DB_URL:-jdbc:postgresql://db:5432/${DB_NAME:-fruitshorts}}
volumes:
# 与两个入口同一个媒资根,否则找不到源文件
- ./data/uploads:/data/uploads
depends_on:
db:
condition: service_healthy
healthcheck:
# worker 不监听端口(server.port=0),用进程存活判断
test: ["CMD-SHELL", "pgrep -f app.jar >/dev/null || exit 1"]
interval: 60s
timeout: 5s
start_period: 40s
retries: 3
volumes:
# 命名卷:跟着 compose 项目走,`docker compose down -v` 才会删
db-data:
redis-data: