2026-10-28 19:07:11 +08:00
|
|
|
|
# =============================================================================
|
|
|
|
|
|
# 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 # 诊断套件持久化(规则历史 + 日志快照)
|
2026-10-29 11:33:58 +08:00
|
|
|
|
- ./tests/samples:/app/tests/samples:ro # 测试靶场样本库(CSV 对齐,可读扫描)
|
2026-10-28 19:07:11 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
# ---------- 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
|