Files
MeshSate/docker-compose.yml
zhaolei da8496adfd infra: 自动定时任务 — cron 服务
新增:
  - scripts/cron_entrypoint.py: 纯 Python 调度器, 零依赖
    任务1: 每天 03:00 跑 archive_old_tasks.py --apply
    任务2: 每周一 03:10 VACUUM ANALYZE (维护表统计信息)
  - docker-compose.yml: 加 cron 服务 (共享 meshsafe:latest 镜像)

归档策略 (archive_old_tasks.py):
  - scan_tasks  90天前: 清 detail JSONB (省空间)
  - scan_tasks  365天前: 移到 scan_tasks_archive
  - idempotency_records:  清 7 天前 (幂等 TTL)
  - policy_versions:      只留最新 5 个

启动: docker compose up -d cron
日志: docker compose logs -f cron
docker compose up 会自动拉起 (restart: unless-stopped)
2026-10-29 17:05:41 +08:00

182 lines
7.0 KiB
YAML
Raw Permalink 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.
# =============================================================================
# MeshSafe 单机部署(内网光闸摆渡场景)
# =============================================================================
#
# 启动顺序:
# 1) 准备 .env(cp .env.example .env 并填 MESHSAFE_MASTER_KEY)
# 2) 准备数据目录(mkdir -p data/{postgres,redis,clamav,logs,temp})
# 3) docker compose up -d postgres redis # 先起基础设施
# 4) docker compose up -d clamav # ClamAV(如首次启动尝试 freshclam 拉签名库)
# 5) bash scripts/import_clamav_db.sh clamav-db-*.tar.gz # 光闸摆渡导入签名库(可选)
# 6) docker compose up -d --build api # 起主服务
# 7) docker compose exec api python scripts/init_db.py # 建表 + admin + 初始策略
# 8) docker compose up -d nginx # 最后起 Nginx
#
# 外部访问:http://<内网服务器IP>:44380/console/login
# =============================================================================
services:
# ---------- PostgreSQL ----------
postgres:
image: postgres:16-alpine
container_name: meshsafe-postgres
restart: unless-stopped
networks: [meshsafe_net]
environment:
- TZ=Asia/Shanghai
- POSTGRES_DB=meshsafe
- POSTGRES_USER=meshsafe
- POSTGRES_PASSWORD=${MESHSAFE_DB_PASSWORD:-meshsafe}
volumes:
- ./data/postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U meshsafe -d meshsafe"]
interval: 10s
timeout: 3s
retries: 5
# ---------- Redis ----------
redis:
image: redis:7-alpine
container_name: meshsafe-redis
restart: unless-stopped
networks: [meshsafe_net]
environment:
- TZ=Asia/Shanghai
command: ["redis-server", "--maxmemory", "128mb", "--maxmemory-policy", "allkeys-lru"]
volumes:
- ./data/redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
# ---------- ClamAV ----------
# 生产:签名库通过光闸离线同步
# 外网 → bash scripts/sync_clamav_db.sh 生成 clamav-db-*.tar.gz
# 光闸摆渡 → bash scripts/import_clamav_db.sh clamav-db-*.tar.gz(放 ./data/clamav 下)
# 首次启动脚本(scripts/init_clamav.sh):如 ./data/clamav 为空则尝试 freshclam
clamav:
image: clamav/clamav:latest
container_name: meshsafe-clamav
restart: unless-stopped
networks: [meshsafe_net]
environment:
- TZ=Asia/Shanghai
volumes:
- ./data/clamav:/var/lib/clamav
- ./scripts/init_clamav.sh:/init_clamav.sh:ro
- ./data/clamav/clamd.conf:/etc/clamav/clamd.conf:ro
entrypoint: ["/init_clamav.sh"]
healthcheck:
test: ["CMD-SHELL", "echo PING | nc -w 2 localhost 3310 || exit 1"]
interval: 60s
timeout: 5s
start_period: 180s
retries: 5
# ---------- API 主服务 ----------
api:
build:
context: .
dockerfile: Dockerfile
image: meshsafe:latest
container_name: meshsafe-api
restart: unless-stopped
networks: [meshsafe_net]
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
clamav:
condition: service_started
environment:
- TZ=Asia/Shanghai
- MESHSAFE_ENV=prod
- MESHSAFE_HOST=0.0.0.0
- MESHSAFE_PORT=8443
- MESHSAFE_LOG_LEVEL=INFO
- MESHSAFE_DB_URL=postgresql+psycopg2://meshsafe:${MESHSAFE_DB_PASSWORD:-meshsafe}@postgres:5432/meshsafe
- MESHSAFE_MASTER_KEY=${MESHSAFE_MASTER_KEY:?MASTER_KEY_REQUIRED}
- MESHSAFE_ADMIN_PASSWORD=${MESHSAFE_ADMIN_PASSWORD:-admin123}
- MESHSAFE_POLICY_FILE=/app/config/policy.yaml
- MESHSAFE_CLAMAV_HOST=clamav
# API 调用方白名单:client_id:client_secret,client_id2:client_secret2
# ⚠️ 生产环境必须替换为真实密钥,切勿把生产密钥提交到仓库
- MESHSAFE_API_CLIENTS=${MESHSAFE_API_CLIENTS:-test-client:test-secret}
- MESHSAFE_CLAMAV_PORT=3310
- MESHSAFE_REDIS_URL=redis://redis:6379/0
- MESHSAFE_WORKERS=2
- MESHSAFE_RULES_DIR=/app/rules
# uvicorn / DB 连接池(并发优化)
- UVICORN_WORKERS=${UVICORN_WORKERS:-8}
- DB_POOL_SIZE=${DB_POOL_SIZE:-30}
- DB_MAX_OVERFLOW=${DB_MAX_OVERFLOW:-50}
volumes:
- ./data/logs:/var/log/meshsafe
- ./data/temp:/tmp/meshsafe
- ./rules:/app/rules:ro
- ./config/policy.yaml:/app/config/policy.yaml:ro
- ./config/diagnostics.yaml:/app/config/diagnostics.yaml:ro
- ./data/clamav:/var/lib/clamav # 共享签名库目录(api 可写入上传的 .cvd 文件,clamd 自动热加载)
- /var/run/docker.sock:/var/run/docker.sock:ro # 诊断套件只读访问 Docker(可选;没有也能降级)
- ./data/diagnostics:/app/data/diagnostics # 诊断套件持久化(规则历史 + 日志快照)
- ./tests/samples:/app/tests/samples:ro # 测试靶场样本库(CSV 对齐,可读扫描)
group_add:
- "999" # docker.sock 的 GID,让 api 容器能读
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8443/api/v1/health', timeout=3).read()"]
interval: 30s
timeout: 5s
start_period: 15s
retries: 3
# ---------- Cron (定时任务: DB 归档 + VACUUM) ----------
# 纯 Python 实现, 零额外依赖, 和 api 共享 meshsafe:latest 镜像
# 任务:
# 每天 03:00 archive_old_tasks.py --apply (清 90 天 detail / 365 天归档 / 幂等 TTL)
# 每周一 03:10 VACUUM ANALYZE (维护表统计信息)
cron:
image: meshsafe:latest
container_name: meshsafe-cron
restart: unless-stopped
networks: [meshsafe_net]
depends_on:
postgres:
condition: service_healthy
environment:
- TZ=Asia/Shanghai
- MESHSAFE_ENV=prod
- MESHSAFE_DB_URL=postgresql+psycopg2://meshsafe:${MESHSAFE_DB_PASSWORD:-meshsafe}@postgres:5432/meshsafe
- MESHSAFE_MASTER_KEY=${MESHSAFE_MASTER_KEY:?MASTER_KEY_REQUIRED}
volumes:
- ./data/logs:/var/log/meshsafe # 归档日志共享目录
- ./scripts:/app/scripts:ro # archive_old_tasks.py + cron_entrypoint.py
entrypoint: ["python3", "/app/scripts/cron_entrypoint.py"]
# ---------- Nginx(反向代理,内网 HTTP 明文)----------
# 外部端口 44380 → 内部 80 → api:8443
# 无 TLS,外层防护靠光闸
nginx:
image: nginx:1.27-alpine
container_name: meshsafe-nginx
restart: unless-stopped
networks: [meshsafe_net]
environment:
- TZ=Asia/Shanghai
depends_on:
api:
condition: service_healthy
ports:
- "0.0.0.0:44380:80"
volumes:
- ./deploy/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
# ---------- 独立 bridge 网络 ----------
# 容器间走服务名通信,IP 由 Docker 自动分配,无需固定网段
networks:
meshsafe_net:
driver: bridge