增加腾讯云生产 Docker 部署编排与一键脚本

- 提供 API/Web 多阶段镜像、Nginx 反代与 WS/文件路径
- docker-compose.prod 含 Postgres、MinIO、API、前端
- deploy.sh 生成密钥、构建启动、可选种子与备份脚本
This commit is contained in:
yml2213
2026-07-15 15:19:04 +08:00
parent 2b18d654b3
commit d744fc790c
8 changed files with 740 additions and 0 deletions
+157
View File
@@ -0,0 +1,157 @@
# 客服云 — 生产 Docker Compose(适合腾讯云 CVM 单机)
# 使用:./deploy/scripts/deploy.sh
# 或:docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build
name: kefu-prod
services:
postgres:
image: postgres:16-alpine
container_name: kefu-prod-db
restart: unless-stopped
environment:
POSTGRES_USER: ${DB_USER:-kefu}
POSTGRES_PASSWORD: ${DB_PASSWORD:?请在 deploy/.env.prod 设置 DB_PASSWORD}
POSTGRES_DB: ${DB_NAME:-kefu_sys}
volumes:
- kefu_pgdata:/var/lib/postgresql/data
networks:
- kefu_net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-kefu} -d ${DB_NAME:-kefu_sys}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
minio:
image: minio/minio:latest
container_name: kefu-prod-minio
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${STORAGE_ACCESS_KEY:?请设置 STORAGE_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${STORAGE_SECRET_KEY:?请设置 STORAGE_SECRET_KEY}
volumes:
- kefu_miniodata:/data
networks:
- kefu_net
# 官方镜像极简,无 curl/bash;由 minio-init 重试建桶保证就绪
minio-init:
image: minio/mc:latest
container_name: kefu-prod-minio-init
depends_on:
minio:
condition: service_started
restart: "no"
networks:
- kefu_net
entrypoint: >
/bin/sh -c "
set -e;
i=0;
until mc alias set local http://minio:9000 \"$$MINIO_ROOT_USER\" \"$$MINIO_ROOT_PASSWORD\" 2>/dev/null; do
i=$$((i+1));
if [ $$i -gt 30 ]; then echo 'minio not ready'; exit 1; fi;
echo waiting minio...;
sleep 2;
done;
mc mb -p local/$${STORAGE_BUCKET:-kefu} || true;
mc anonymous set download local/$${STORAGE_BUCKET:-kefu};
echo 'MinIO bucket ready';
"
environment:
MINIO_ROOT_USER: ${STORAGE_ACCESS_KEY}
MINIO_ROOT_PASSWORD: ${STORAGE_SECRET_KEY}
STORAGE_BUCKET: ${STORAGE_BUCKET:-kefu}
api:
build:
context: .
dockerfile: deploy/docker/Dockerfile.api
image: kefu-api:${IMAGE_TAG:-latest}
container_name: kefu-prod-api
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
minio-init:
condition: service_completed_successfully
environment:
SERVER_PORT: "8080"
GIN_MODE: ${GIN_MODE:-release}
DB_HOST: postgres
DB_PORT: "5432"
DB_USER: ${DB_USER:-kefu}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-kefu_sys}
DB_SSLMODE: ${DB_SSLMODE:-disable}
JWT_SECRET: ${JWT_SECRET:?请设置 JWT_SECRET}
STORAGE_ENDPOINT: minio:9000
STORAGE_ACCESS_KEY: ${STORAGE_ACCESS_KEY}
STORAGE_SECRET_KEY: ${STORAGE_SECRET_KEY}
STORAGE_BUCKET: ${STORAGE_BUCKET:-kefu}
STORAGE_USE_SSL: "false"
STORAGE_REGION: ${STORAGE_REGION:-us-east-1}
# 浏览器访问图片的公网前缀(经 Nginx /files 反代)
STORAGE_PUBLIC_BASE_URL: ${STORAGE_PUBLIC_BASE_URL:?请设置 STORAGE_PUBLIC_BASE_URL,如 https://你的域名/files}
STORAGE_MAX_UPLOAD_MB: ${STORAGE_MAX_UPLOAD_MB:-10}
STORAGE_MAX_IMAGE_EDGE: ${STORAGE_MAX_IMAGE_EDGE:-1920}
STORAGE_WEBP_QUALITY: ${STORAGE_WEBP_QUALITY:-80}
networks:
- kefu_net
# 不对外暴露 8080,统一走 nginx
web:
build:
context: .
dockerfile: deploy/docker/Dockerfile.web
image: kefu-web:${IMAGE_TAG:-latest}
container_name: kefu-prod-web
restart: unless-stopped
depends_on:
api:
condition: service_healthy
minio:
condition: service_started
ports:
- "${HTTP_PORT:-80}:80"
networks:
- kefu_net
# 可选:导入演示数据(profile seed
# docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile seed run --rm seed
seed:
image: kefu-api:${IMAGE_TAG:-latest}
container_name: kefu-prod-seed
profiles: ["seed"]
depends_on:
api:
condition: service_healthy
environment:
DB_HOST: postgres
DB_PORT: "5432"
DB_USER: ${DB_USER:-kefu}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME:-kefu_sys}
DB_SSLMODE: ${DB_SSLMODE:-disable}
JWT_SECRET: ${JWT_SECRET}
STORAGE_ENDPOINT: minio:9000
STORAGE_ACCESS_KEY: ${STORAGE_ACCESS_KEY}
STORAGE_SECRET_KEY: ${STORAGE_SECRET_KEY}
STORAGE_BUCKET: ${STORAGE_BUCKET:-kefu}
STORAGE_USE_SSL: "false"
STORAGE_PUBLIC_BASE_URL: ${STORAGE_PUBLIC_BASE_URL}
entrypoint: ["/app/seed"]
networks:
- kefu_net
restart: "no"
networks:
kefu_net:
driver: bridge
volumes:
kefu_pgdata:
kefu_miniodata: