From d5ec25018483c552ef0817936da5538301c7bace Mon Sep 17 00:00:00 2001 From: iven Date: Sun, 17 May 2026 15:06:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(docker):=20=E4=BA=91=E7=AB=AF=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E9=85=8D=E7=BD=AE=20=E2=80=94=20host=20=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E6=A8=A1=E5=BC=8F=20+=20=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dockerfile: Rust 版本升级为 latest stable, 添加 curl (healthcheck), 前端产物 VOLUME 暴露供 OpenResty 挂载 - docker-compose.cloud.yml: 仅 app 容器, host 网络直连宿主机 PG/Redis - .env.production.example: 环境变量模板含必填/可选项注释 --- Dockerfile | 9 ++-- docker/.env.production.example | 79 +++++++++++++++++---------------- docker/.gitignore | 1 + docker/docker-compose.cloud.yml | 40 +++++++++++++++++ 4 files changed, 86 insertions(+), 43 deletions(-) create mode 100644 docker/.gitignore create mode 100644 docker/docker-compose.cloud.yml diff --git a/Dockerfile b/Dockerfile index 4b59c6a..b22a9da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ============================== # Stage 1: Build Rust backend # ============================== -FROM rust:1.85-bookworm AS rust-builder +FROM rust:1-bookworm AS rust-builder WORKDIR /app @@ -75,6 +75,7 @@ FROM debian:bookworm-slim AS runtime RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ + curl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app @@ -85,7 +86,7 @@ COPY --from=rust-builder /app/target/release/erp-server /app/erp-server # 复制配置文件 COPY config/ /app/config/ -# 复制前端构建产物 +# 复制前端构建产物(可通过 volume 暴露给 OpenResty) COPY --from=frontend-builder /app/apps/web/dist/ /app/static/ # 创建上传目录 @@ -96,7 +97,7 @@ RUN useradd -r -s /bin/false appuser \ && chown -R appuser:appuser /app USER appuser -# 环境变量(运行时通过 docker-compose 覆盖) +# 环境变量(运行时通过 docker-compose / .env 覆盖) ENV ERP__SERVER__HOST=0.0.0.0 ENV ERP__SERVER__PORT=3000 ENV ERP__SERVER__METRICS_PORT=9090 @@ -104,7 +105,7 @@ ENV ERP__STORAGE__UPLOAD_DIR=/app/uploads EXPOSE 3000 9090 -VOLUME ["/app/uploads"] +VOLUME ["/app/uploads", "/app/static"] HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \ CMD curl -f http://localhost:3000/api/v1/health || exit 1 diff --git a/docker/.env.production.example b/docker/.env.production.example index e23a46f..ade2ad1 100644 --- a/docker/.env.production.example +++ b/docker/.env.production.example @@ -1,51 +1,52 @@ -# ============================================== -# HMS 生产环境变量模板 -# 复制为 .env.production 并填写实际值 -# ============================================== +# HMS 云端部署环境变量 +# 复制此文件为 .env.production 并填写实际值 +# cp .env.production.example .env.production -# ---- 应用 ---- -APP_PORT=3000 -METRICS_PORT=9090 +# ===== 必填 ===== -# ---- 数据库(必填)---- -POSTGRES_USER=erp -POSTGRES_PASSWORD=__CHANGE_ME__ -POSTGRES_DB=erp -POSTGRES_PORT=5432 +# PostgreSQL 连接(host 网络模式,直连宿主机) +ERP__DATABASE__URL=postgres://erp:YOUR_PG_PASSWORD@localhost:5432/erp -# ---- Redis(必填)---- -REDIS_PASSWORD=__CHANGE_ME__ -REDIS_PORT=6379 +# Redis 连接 +ERP__REDIS__URL=redis://:YOUR_REDIS_PASSWORD@localhost:6379 -# ---- JWT(必填)---- -ERP__JWT__SECRET=__CHANGE_ME__ -ERP__JWT__ACCESS_TOKEN_TTL=15m -ERP__JWT__REFRESH_TOKEN_TTL=7d +# JWT 密钥(至少 32 字符随机字符串) +ERP__JWT__SECRET=CHANGE_ME_TO_A_RANDOM_STRING_AT_LEAST_32_CHARS -# ---- 超级管理员(必填)---- -ERP__AUTH__SUPER_ADMIN_PASSWORD=__CHANGE_ME__ +# 超级管理员初始密码(首次启动时创建 admin 用户) +ERP__AUTH__SUPER_ADMIN_PASSWORD=CHANGE_ME_ADMIN_PASSWORD -# ---- PII 加密密钥(必填)---- -ERP__CRYPTO__KEK=__CHANGE_ME__ -ERP__HEALTH__AES_KEY=__CHANGE_ME__ -ERP__HEALTH__HMAC_KEY=__CHANGE_ME__ +# PII 加密密钥(AES-256 KEK,64 位十六进制) +ERP__CRYPTO__KEK=CHANGE_ME_64_HEX_CHARS_FOR_AES256_KEY -# ---- CORS ---- -ERP__CORS__ALLOWED_ORIGINS=["https://your-domain.com"] +# 健康数据加密密钥 +ERP__HEALTH__AES_KEY=CHANGE_ME_64_HEX_CHARS +ERP__HEALTH__HMAC_KEY=CHANGE_ME_64_HEX_CHARS -# ---- 微信小程序(可选,dev_mode=true 可跳过)---- -ERP__WECHAT__DEV_MODE=false -ERP__WECHAT__APPID= -ERP__WECHAT__SECRET= +# ===== 可选 ===== -# ---- AI 配置(可选)---- -ERP__AI__DEFAULT_PROVIDER=ollama -ERP__AI__OLLAMA__BASE_URL=http://ollama:11434 -ERP__AI__OLLAMA__MODEL=qwen3:4b +# 服务端口(默认 3000) +ERP__SERVER__PORT=3000 -# ---- 日志 ---- +# Prometheus 指标端口(默认 9090) +ERP__SERVER__METRICS_PORT=9090 + +# CORS 允许的来源(逗号分隔) +ERP__CORS__ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com + +# 上传目录 +ERP__STORAGE__UPLOAD_DIR=/app/uploads + +# 日志级别 ERP__LOG__LEVEL=info -# ---- 存储 ---- -ERP__STORAGE__UPLOAD_DIR=/app/uploads -ERP__STORAGE__MAX_FILE_SIZE=10485760 +# 微信小程序配置(不需要小程序功能可留空) +ERP__WECHAT__APPID= +ERP__WECHAT__SECRET= +ERP__WECHAT__DEV_MODE=false + +# AI 模块配置(不需要 AI 功能可留空) +ERP__AI__DEFAULT_PROVIDER=ollama +ERP__AI__API_KEY= +ERP__AI__BASE_URL=http://localhost:11434 +ERP__AI__MODEL=qwen2.5:7b diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 0000000..69f29bd --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +.env.production diff --git a/docker/docker-compose.cloud.yml b/docker/docker-compose.cloud.yml new file mode 100644 index 0000000..efd8486 --- /dev/null +++ b/docker/docker-compose.cloud.yml @@ -0,0 +1,40 @@ +# 云端部署配置 — 仅启动应用容器,PG/Redis 使用宿主机已安装的服务 +# 使用方式: docker compose -f docker/docker-compose.cloud.yml up -d +# +# 前置条件: +# 1. 宿主机已安装 PostgreSQL 16 + Redis 7 +# 2. PostgreSQL 已创建数据库和用户 +# 3. 复制 .env.production.example 为 .env.production 并填写实际值 +# 4. OpenResty 反代配置: +# - /api/* → http://localhost:3000 +# - /uploads/* → http://localhost:3000 +# - / → 前端静态文件 (挂载 /opt/hms/static/) + +services: + app: + build: + context: .. + dockerfile: Dockerfile + container_name: hms-server + restart: unless-stopped + network_mode: host + env_file: + - .env.production + volumes: + - ../uploads:/app/uploads + - ../config:/app/config:ro + - ../static:/app/static + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/health"] + interval: 30s + timeout: 5s + start_period: 60s + retries: 3 + deploy: + resources: + limits: + cpus: "2" + memory: 1024M + reservations: + cpus: "0.5" + memory: 256M