2fd1b3da21
部署机首次 docker compose up -d 实测暴露: - .dockerignore 自"重写独立dockerfile"起排除整个 deploy/,而 Dockerfile.frontend COPY deploy/nginx/frontend.conf、Dockerfile.moldinsight COPY deploy/requirements-*.txt → COPY not found。历史一直有旧镜像兜底未暴露; BuildKit 不支持重包含被排除目录的子文件,直接移除该行 - Dockerfile.celery FROM gemold-backend:latest 在 compose 并行构建下引用 尚不存在的本地镜像必挂 → 删除 Dockerfile.celery,moldinsight-celery 改为 与 API 服务同一 build 声明 + 同一 gemold-backend:latest tag(compose 去重 只构建一次),celery 仅以 command: 覆盖启动 worker,参数语义不变 - build.sh/.bat 移除 gemold-celery 构建步骤;OPERATIONS / OCC_THROUGHPUT / TECH_DEBT / .env.example 的 Dockerfile.celery 指向同步改写;STATUS 补录 Co-Authored-By: Claude Code <noreply@anthropic.com>
133 lines
5.2 KiB
YAML
133 lines
5.2 KiB
YAML
# geMoldInsight — unified 模式(默认入口)
|
||
#
|
||
# 一键启动:
|
||
# docker compose up -d
|
||
#
|
||
# 其他模式(换文件名即可,无需 --profile):
|
||
# docker compose -f docker-compose.moldinsight.yml up -d
|
||
# docker compose -f docker-compose.inventory.yml up -d
|
||
#
|
||
# 注意:服务均未声明 profiles(compose 规则:声明了 profiles 的服务在
|
||
# 不带 --profile 时不会被选中,裸 up 会报 "no service selected"),
|
||
# 旧 --profile 写法不再是模式开关,模式切换唯一入口是 -f 文件名。
|
||
#
|
||
# 服务清单:frontend + backend(unified 入口) + moldinsight-celery
|
||
# 镜像:gemold-backend / gemold-frontend(celery 复用 gemold-backend,仅 command 不同)
|
||
|
||
# ---------------------------------------------------------------
|
||
# 公共环境变量(moldinsight 家族 backend/celery/moldinsight 共用)
|
||
# 通过 anchor 在本文件内复用,避免 environment 块重复
|
||
# ---------------------------------------------------------------
|
||
x-base-env: &base_env
|
||
DB_HOST: ${DB_HOST}
|
||
DB_PORT: ${DB_PORT:-5432}
|
||
DB_NAME: ${DB_NAME:-moldinsight}
|
||
DB_USER: ${DB_USER}
|
||
DB_PASSWORD: ${DB_PASSWORD}
|
||
REDIS_HOST: ${REDIS_HOST}
|
||
REDIS_PORT: ${REDIS_PORT:-6379}
|
||
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
|
||
RUSTFS_ENDPOINT: ${RUSTFS_ENDPOINT}
|
||
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY}
|
||
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY}
|
||
RUSTFS_TIMEOUT: ${RUSTFS_TIMEOUT:-30}
|
||
# SECRET_KEY 必须在 .env 中显式配置,否则 compose 直接失败
|
||
SECRET_KEY: ${SECRET_KEY:?SECRET_KEY 未配置:请在 .env 中设置}
|
||
ALGORITHM: ${ALGORITHM:-HS256}
|
||
ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-1440}
|
||
DEBUG: ${DEBUG:-false}
|
||
SERVE_FRONTEND_STATIC: ${SERVE_FRONTEND_STATIC:-false}
|
||
UPLOAD_DIR: ${UPLOAD_DIR:-./uploads}
|
||
MAX_FILE_SIZE: ${MAX_FILE_SIZE:-104857600}
|
||
ALLOWED_EXTENSIONS: ${ALLOWED_EXTENSIONS:-.stp,.step,.stp.gz}
|
||
POINTCLOUD_SAMPLE_COUNT: ${POINTCLOUD_SAMPLE_COUNT:-10000}
|
||
MESH_QUALITY: ${MESH_QUALITY:-high}
|
||
PARALLEL_PROCESSING: ${PARALLEL_PROCESSING:-true}
|
||
RUSTFS_PRESIGNED_URL_EXPIRES: ${RUSTFS_PRESIGNED_URL_EXPIRES:-3600}
|
||
ENABLE_FREECAD_VERIFICATION: ${ENABLE_FREECAD_VERIFICATION:-false}
|
||
FREECAD_VERIFICATION_TIMEOUT: ${FREECAD_VERIFICATION_TIMEOUT:-120}
|
||
LLM_ENABLED: ${LLM_ENABLED:-false}
|
||
LLM_API_URL: ${LLM_API_URL:-https://api.openai.com/v1}
|
||
LLM_API_KEY: ${LLM_API_KEY:-}
|
||
LLM_MODEL: ${LLM_MODEL:-gpt-4o-mini}
|
||
LLM_TIMEOUT: ${LLM_TIMEOUT:-60}
|
||
LLM_MAX_TOKENS: ${LLM_MAX_TOKENS:-2000}
|
||
|
||
services:
|
||
frontend:
|
||
build:
|
||
context: .
|
||
dockerfile: deploy/Dockerfile.frontend
|
||
image: gemold-frontend:latest
|
||
container_name: gemold_frontend
|
||
ports:
|
||
- "${FRONTEND_PORT:-80}:80"
|
||
depends_on:
|
||
- backend
|
||
restart: unless-stopped
|
||
networks:
|
||
- gemold_network
|
||
|
||
backend:
|
||
build:
|
||
context: .
|
||
dockerfile: deploy/Dockerfile.moldinsight
|
||
image: gemold-backend:latest
|
||
container_name: gemold_backend
|
||
command: ["python", "-m", "uvicorn", "entrypoints.unified:app", "--host", "0.0.0.0", "--port", "8000"]
|
||
ports:
|
||
- "${BACKEND_PORT:-8000}:8000"
|
||
environment:
|
||
<<: *base_env
|
||
HOST: 0.0.0.0
|
||
PORT: "8000"
|
||
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
|
||
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?ADMIN_PASSWORD 未配置:请在 .env 中设置}
|
||
ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@gemold.com}
|
||
ADMIN_FULL_NAME: ${ADMIN_FULL_NAME:-系统管理员}
|
||
AUTO_MIGRATE: ${AUTO_MIGRATE:-true}
|
||
# 共享卷过渡兜底(D6/D11):主链路已改走 RustFS。uploads 供 RustFS 异常时
|
||
# 本地路径回退;html_output 仅作 /html 报告代理的存量兜底读(新产物不落本地)
|
||
volumes:
|
||
- uploads_data:/app/uploads
|
||
- html_data:/app/html_output
|
||
restart: unless-stopped
|
||
networks:
|
||
- gemold_network
|
||
|
||
moldinsight-celery:
|
||
# 与 backend 共用同一镜像(同一 build 声明 + 同一 tag,compose 只构建一次),
|
||
# 仅以 command 覆盖启动 worker——消除旧 Dockerfile.celery(已删)FROM
|
||
# gemold-backend 在并行构建下的"镜像尚不存在"陷阱,干净机器裸 up 一把过
|
||
build:
|
||
context: .
|
||
dockerfile: deploy/Dockerfile.moldinsight
|
||
image: gemold-backend:latest
|
||
container_name: gemold_celery
|
||
command: ["sh", "-c", "exec celery -A celery_app worker --workdir=/app/src --concurrency=${CELERY_CONCURRENCY:-2} --max-tasks-per-child=${CELERY_MAX_TASKS_PER_CHILD:-50} --loglevel=info"]
|
||
environment:
|
||
<<: *base_env
|
||
# Celery/OCC 吞吐调优(OCC_THROUGHPUT 方案 A)
|
||
CELERY_CONCURRENCY: ${CELERY_CONCURRENCY:-2}
|
||
CELERY_MAX_TASKS_PER_CHILD: ${CELERY_MAX_TASKS_PER_CHILD:-50}
|
||
# uploads_data 共享卷(D6 过渡兜底):RustFS 异常时 worker 回退本地路径下载。
|
||
# D11 后 worker 不再写 HTML 产物(直传 RustFS 报告键),无需 html_data 卷
|
||
volumes:
|
||
- uploads_data:/app/uploads
|
||
depends_on:
|
||
- backend
|
||
restart: unless-stopped
|
||
networks:
|
||
- gemold_network
|
||
|
||
networks:
|
||
gemold_network:
|
||
# 固定 name,便于跨 compose 文件调试时容器互通(如 inventory-only 与 unified 临时联调)
|
||
name: gemold_network
|
||
driver: bridge
|
||
|
||
volumes:
|
||
uploads_data:
|
||
name: gemold_uploads_data
|
||
html_data:
|
||
name: gemold_html_data |