Files
geMoldInsight/docker-compose.yml
T

144 lines
6.2 KiB
YAML
Raw Normal View History

# 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}
2026-02-11 22:40:35 +08:00
services:
2026-08-31 18:01:34 +08:00
frontend:
build:
context: .
dockerfile: deploy/Dockerfile.frontend
image: gemold-frontend:latest
container_name: gemold_frontend
ports:
# 浏览器入口端口(无默认值:必须由 .env 中 FRONTEND_PORT 显式配置)
- "${FRONTEND_PORT}:8000"
2026-08-31 18:01:34 +08:00
depends_on:
- backend
restart: unless-stopped
networks:
- gemold_network
backend:
2026-08-27 14:53:22 +08:00
build:
context: .
dockerfile: deploy/Dockerfile.moldinsight
2026-08-31 18:01:34 +08:00
image: gemold-backend:latest
container_name: gemold_backend
command: ["python", "-m", "uvicorn", "entrypoints.unified:app", "--host", "0.0.0.0", "--port", "8000"]
# 宿主机端口由 .env 的 BACKEND_PORT 决定:空/不设则不暴露宿主机端口
# (仅经前端 /api 反代同域访问,避免与 frontend 抢占宿主 10003)。
# 调试时设 BACKEND_PORT=10003 即可独立访问。
ports:
- "${BACKEND_PORT:-}:8000"
2026-02-11 22:40:35 +08:00
environment:
<<: *base_env
2026-08-27 14:53:22 +08:00
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
2026-09-16 17:55:04 +08:00
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?ADMIN_PASSWORD 未配置:请在 .env 中设置}
2026-08-27 14:53:22 +08:00
ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@gemold.com}
ADMIN_FULL_NAME: ${ADMIN_FULL_NAME:-系统管理员}
2026-09-16 17:55:04 +08:00
AUTO_MIGRATE: ${AUTO_MIGRATE:-true}
# 共享卷过渡兜底(D6/D11):主链路已改走 RustFS。uploads 供 RustFS 异常时
# 本地路径回退;html_output 仅作 /html 报告代理的存量兜底读(新产物不落本地)
2026-09-16 17:55:04 +08:00
volumes:
- uploads_data:/app/uploads
- html_data:/app/html_output
2026-02-11 22:40:35 +08:00
restart: unless-stopped
networks:
2026-08-27 14:53:22 +08:00
- gemold_network
2026-02-11 22:40:35 +08:00
2026-08-27 14:53:22 +08:00
moldinsight-celery:
# 与 backend 共用同一镜像(同一 build 声明 + 同一 tag,compose 只构建一次),
# 仅以 command 覆盖启动 worker——消除旧 Dockerfile.celery(已删)FROM
# gemold-backend 在并行构建下的"镜像尚不存在"陷阱,干净机器裸 up 一把过
2026-08-27 14:53:22 +08:00
build:
context: .
dockerfile: deploy/Dockerfile.moldinsight
image: gemold-backend:latest
2026-08-27 14:53:22 +08:00
container_name: gemold_celery
# cd /app/src 是必须的:celery_app / celery_tasks 是 src/ 的子模块,
# 而其 import 用的是裸模块名(celery_app.py 内 include=["celery_tasks"]),
# 所以 worker 必须从 src/ 目录启动;不依赖 celery 版本是否支持 --workdir
# --pool=solo:任务在 celery 主进程内执行。prefork 的 worker 子进程是
# daemonic,multiprocessing 禁止守护进程再生子进程,OCC 常驻进程池
# (OccProcessPool spawn 拉起)在 prefork 下必报
# "daemonic processes are not allowed to have children"(2026-09-26)。
# solo 天然单任务串行,与 processing_service / redis_task_manager /
# db_manager 等模块级单例(其 asyncio.Lock 不可跨循环并发)也匹配;
# 需要吞吐时横向加容器副本,而不是调并发。
command: ["sh", "-c", "cd /app/src && exec celery -A celery_app worker --pool=solo --loglevel=info"]
2026-02-11 22:40:35 +08:00
environment:
<<: *base_env
# 旧 CELERY_CONCURRENCY / CELERY_MAX_TASKS_PER_CHILD 已随 --pool=solo 移除:
# solo 单进程串行,二者不适用(.env 里残留定义会被 compose 静默忽略)
# uploads_data 共享卷(D6 过渡兜底):RustFS 异常时 worker 回退本地路径下载。
# D11 后 worker 不再写 HTML 产物(直传 RustFS 报告键),无需 html_data 卷
2026-09-16 17:55:04 +08:00
volumes:
- uploads_data:/app/uploads
2026-02-11 22:40:35 +08:00
depends_on:
2026-08-31 18:01:34 +08:00
- backend
2026-02-11 22:40:35 +08:00
restart: unless-stopped
networks:
2026-08-27 14:53:22 +08:00
- gemold_network
2026-02-11 22:40:35 +08:00
networks:
2026-08-27 14:53:22 +08:00
gemold_network:
# 固定 name,便于跨 compose 文件调试时容器互通(如 inventory-only 与 unified 临时联调)
name: gemold_network
2026-02-11 22:40:35 +08:00
driver: bridge
2026-09-16 17:55:04 +08:00
volumes:
uploads_data:
name: gemold_uploads_data
2026-09-16 17:55:04 +08:00
html_data:
name: gemold_html_data