Files
BYW-VoiceHub/docker-compose.yml
T
Henry_Du f999d58eef
构建 & 部署 BYW VoiceHub / 构建并推送镜像 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 部署到生产服务器 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / Preflight 语法 & 构建检查 (push) Canceled after 4m43s
fix: 删除 voicehub 顶层 cpus/mem_limit,避免与 deploy.resources 重复定义报错
2026-09-06 09:46:55 +08:00

163 lines
5.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ⚠️ Docker Compose v2 顶级 name 必须匹配正则 ^[a-z0-9][a-z0-9_-]*$
# 不能有大写、空格、括号、中文,否则会报 name Does not match pattern 错误
name: byw-voicehub
services:
# ========================================================================
# 应用本体 - Nuxt 4 (Node SSR)
# - 使用两阶段构建 Dockerfile,构建阶段内存友好
# - PREBUILT=true:告诉 scripts/deploy.js 跳过 npm install 和 nuxt build
# (因为第一阶段已经 build 好了,产物在 .output/ 里)
# ========================================================================
voicehub:
image: byw-voicehub:1.7.0.0
build:
context: .
dockerfile: Dockerfile
args:
BUILDKIT_INLINE_CACHE: "1"
container_name: voicehub-app
restart: unless-stopped
ports:
# 左边是宿主机端口(对外),右边是容器内端口(固定 3000)
# 如果要套 Nginx,就只监听 127.0.0.1:4456:3000 不直接暴露外网
- "4456:3000"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
env_file:
# 把密码、密钥都写在项目根的 .env 里,不要直接写进这个 yaml
- .env
environment:
# ===== 运行时基础(可以被 .env 覆盖) =====
NODE_ENV: production
PORT: 3000
HOST: 0.0.0.0
PREBUILT: "true"
SKIP_INSTALL: "true"
SKIP_BUILD: "true"
NITRO_PRESET: node-server
# ===== 数据库连接串(.env 写了就用 .env,没写就自动拼 compose 内部 postgres 服务) =====
DATABASE_URL: ${DATABASE_URL:-postgresql://${POSTGRES_USER:-voicehub}:${POSTGRES_PASSWORD:-voicehub}@postgres:5432/${POSTGRES_DB:-voicehub}?sslmode=disable}
# ===== Redis 连接串(同上,自动拼内部 redis 服务) =====
REDIS_URL: ${REDIS_URL:-redis://${REDIS_PASSWORD:+:${REDIS_PASSWORD}@}redis:6379/0}
# ===== 会话/Token(必须在 .env 里设,这里给一个占位提醒) =====
JWT_SECRET: ${JWT_SECRET:-请在.env里设置JWT_SECRET用openssl rand -hex 32生成}
# ===== 应用默认(可在 .env 覆盖,不会覆盖 .env 里同名字段) =====
NUXT_PUBLIC_SITE_URL: ${NUXT_PUBLIC_SITE_URL:-http://127.0.0.1:4456}
NUXT_PUBLIC_SITE_TITLE: ${NUXT_PUBLIC_SITE_TITLE:-校园广播站点歌系统}
NUXT_PUBLIC_DEFAULT_THEME: ${NUXT_PUBLIC_DEFAULT_THEME:-dark}
NUXT_PUBLIC_ENABLED_THEMES: ${NUXT_PUBLIC_ENABLED_THEMES:-dark,light}
# ===== 日志/性能 =====
NODE_OPTIONS: ${NODE_OPTIONS:-"--max-old-space-size=768"}
# 2C4G 机器的推荐配置(.env 可覆盖);小机器 1C2G 也能跑
# ⚠️ 关键:用 deploy.resources.{limits|reservations} 这一套,
# 不要同时在顶层写 cpus/mem_limit/mem_reservation!
# Docker Compose v2 禁止两套资源字段并存,会报 invalid compose project。
deploy:
resources:
limits:
cpus: ${APP_CPUS_LIMIT:-2}
memory: ${APP_MEM_LIMIT:-1400M}
reservations:
cpus: ${APP_CPUS_RESERVATION:-0.5}
memory: ${APP_MEM_RESERVATION:-384M}
healthcheck:
# 30s 后开始检查,每 15s 一次,连续 3 次失败就重启
test:
[
"CMD",
"node",
"-e",
"fetch('http://127.0.0.1:3000/').then(r=>{process.exit(r.ok?0:1)}).catch(()=>process.exit(1))"
]
interval: 15s
timeout: 5s
retries: 3
start_period: 30s
networks:
- voicehub-net
volumes:
# (可选)把自定义 logo/上传资源挂到宿主机
- voicehub-uploads:/app/app/public/uploads:rw
# ========================================================================
# PostgreSQL 16 - 主数据库
# ========================================================================
postgres:
image: postgres:16-alpine
container_name: voicehub-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-voicehub}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-请在.env里改这个密码}
POSTGRES_DB: ${POSTGRES_DB:-voicehub}
PGDATA: /var/lib/postgresql/data/pgdata
# .env 里没设 DATABASE_URL 时,自动拼一份给 app 用
# (如果 .env 里已经写了外部 Postgres,就以 .env 为准)
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-voicehub} -d ${POSTGRES_DB:-voicehub}"]
interval: 5s
timeout: 5s
retries: 10
volumes:
- postgres-data:/var/lib/postgresql/data
# 如需从宿主机用 Navicat 连,取消下一行注释
# ports:
# - "127.0.0.1:5433:5432"
mem_limit: ${PG_MEM_LIMIT:-1200m}
mem_reservation: ${PG_MEM_RESERVATION:-256m}
cpus: ${PG_CPUS:-"1.0"}
networks:
- voicehub-net
# ========================================================================
# Redis 7 - 缓存 / 会话 / 限流 / 队列
# ========================================================================
redis:
image: redis:7-alpine
container_name: voicehub-redis
restart: unless-stopped
command: >
sh -c "
if [ -n \"$$REDIS_PASSWORD\" ]; then
redis-server --appendonly yes --requirepass \"$$REDIS_PASSWORD\"
else
redis-server --appendonly yes
fi
"
environment:
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
volumes:
- redis-data:/data
mem_limit: ${REDIS_MEM_LIMIT:-384m}
mem_reservation: ${REDIS_MEM_RESERVATION:-64m}
cpus: ${REDIS_CPUS:-0.5}
networks:
- voicehub-net
volumes:
postgres-data:
name: voicehub-postgres-data
redis-data:
name: voicehub-redis-data
voicehub-uploads:
name: voicehub-uploads
networks:
voicehub-net:
name: voicehub-net
driver: bridge