services: mysql-storage-guard: image: busybox:1.36 restart: "no" user: "${MYSQL_CONTAINER_UID:-999}:${MYSQL_CONTAINER_GID:-999}" environment: MYSQL_STORAGE_ID: ${MYSQL_STORAGE_ID:?必须设置 MYSQL_STORAGE_ID} MYSQL_STORAGE_MARKER: /storage-id MYSQL_DATA_PATH: /data command: ["sh", "/usr/local/bin/mysql-storage-guard.sh"] volumes: - type: bind source: ${MYSQL_STORAGE_MOUNT:?必须设置 MYSQL_STORAGE_MOUNT}/.nianxx-mysql-storage-id target: /storage-id read_only: true bind: create_host_path: false - type: bind source: ${MYSQL_DATA_DIR:?必须设置 MYSQL_DATA_DIR} target: /data bind: create_host_path: false - type: bind source: ./docker/mysql-storage-guard.sh target: /usr/local/bin/mysql-storage-guard.sh read_only: true bind: create_host_path: false postgres: environment: POSTGRES_USER: ${POSTGRES_USER:?必须设置 POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?必须设置 POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB:?必须设置 POSTGRES_DB} mysql: environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?必须设置 MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE:-platform_control} MYSQL_USER: ${MYSQL_USER:?必须设置 MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD:?必须设置 MYSQL_PASSWORD} MYSQL_ACCESS_BROKER_USER: ${MYSQL_ACCESS_BROKER_USER:-access_broker} MYSQL_ACCESS_BROKER_PASSWORD: ${MYSQL_ACCESS_BROKER_PASSWORD:?必须设置 MYSQL_ACCESS_BROKER_PASSWORD} ports: !override - "127.0.0.1:${MYSQL_PORT:-3307}:3306" volumes: !override - type: bind source: ${MYSQL_DATA_DIR:?必须设置 MYSQL_DATA_DIR} target: /var/lib/mysql bind: create_host_path: false - type: bind source: ./docker/mysql-init/01-data-center-grants.sh target: /docker-entrypoint-initdb.d/01-data-center-grants.sh read_only: true bind: create_host_path: false depends_on: mysql-storage-guard: condition: service_completed_successfully dbeaver-gateway: ports: !override - "${DATA_MYSQL_SSH_BIND:-127.0.0.1}:${DATA_MYSQL_SSH_PORT:-2222}:22" api: network_mode: host ports: !override [] environment: APP_ENVIRONMENT: production SECURITY_STRICT_MODE: "true" DATABASE_URL: postgresql://${POSTGRES_USER:?必须设置 POSTGRES_USER}:${POSTGRES_PASSWORD:?必须设置 POSTGRES_PASSWORD}@127.0.0.1:${POSTGRES_PORT:-5433}/${POSTGRES_DB:?必须设置 POSTGRES_DB} DATA_MYSQL_URL: mysql://${MYSQL_USER:?必须设置 MYSQL_USER}:${MYSQL_PASSWORD:?必须设置 MYSQL_PASSWORD}@127.0.0.1:${MYSQL_PORT:-3307}/${MYSQL_DATABASE:-platform_control} AUTH_SECRET: ${AUTH_SECRET:?必须设置至少 32 位 AUTH_SECRET} AUTH_DEFAULT_PASSWORD: ${AUTH_DEFAULT_PASSWORD:?必须设置至少 12 位管理员密码} INTERFACE_API_SECRET: ${INTERFACE_API_SECRET:?必须设置独立的 INTERFACE_API_SECRET} INGEST_API_KEYS: ${INGEST_API_KEYS:?必须设置外部接口密钥} CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:?必须设置后台 HTTPS 来源} TRUSTED_HOSTS: ${TRUSTED_HOSTS:?必须设置服务器域名} MYSQL_HOST_BIND: 127.0.0.1 DATA_MYSQL_STORAGE_BACKEND: dedicated-block DATA_MYSQL_STORAGE_ID: ${MYSQL_STORAGE_ID:?必须设置 MYSQL_STORAGE_ID} DATA_MYSQL_STORAGE_MOUNT: ${MYSQL_STORAGE_MOUNT:?必须设置 MYSQL_STORAGE_MOUNT} DATA_MYSQL_DATA_DIR: ${MYSQL_DATA_DIR:?必须设置 MYSQL_DATA_DIR} DATA_BACKUP_ENABLED: ${DATA_BACKUP_ENABLED:?生产环境必须设置 DATA_BACKUP_ENABLED=true} DATA_BACKUP_ENCRYPTION_REQUIRED: "true" DATA_BACKUP_RETENTION_DAYS: ${DATA_BACKUP_RETENTION_DAYS:-30} DATA_BACKUP_ROOT: ${DATA_BACKUP_ROOT:?必须设置项目外 DATA_BACKUP_ROOT} DATA_MYSQL_SSH_TUNNEL_REQUIRED: "true" DATA_MYSQL_DIRECT_ACCESS_ENABLED: "true" DATA_MYSQL_MANAGED_ACCESS_ENABLED: "true" DATA_MYSQL_SSH_HOST: ${DATA_MYSQL_SSH_HOST:-} DATA_MYSQL_SSH_PORT: ${DATA_MYSQL_SSH_PORT:-2222} DATA_MYSQL_SSH_USERNAME: ${DATA_MYSQL_SSH_USERNAME:-dbeaver} DATA_MYSQL_SSH_AUTHORIZED_KEYS_FILE: /var/lib/travel-kg/dbeaver-access/authorized_keys DATA_MYSQL_SSH_HOST_PUBLIC_KEY_FILE: /var/lib/travel-kg/dbeaver-access/ssh_host_ed25519_key.pub DATA_MYSQL_PROVISIONER_USER: ${MYSQL_ACCESS_BROKER_USER:-access_broker} DATA_MYSQL_PROVISIONER_PASSWORD: ${MYSQL_ACCESS_BROKER_PASSWORD:?必须设置 MYSQL_ACCESS_BROKER_PASSWORD} DATA_SQL_CONSOLE_WRITE_ENABLED: "false" FALKORDB_HOST: 127.0.0.1 FALKORDB_PORT: ${FALKORDB_PORT:-6380} command: - python - -m - uvicorn - app.main:app - --host - ${API_BIND_HOST:-127.0.0.1} - --port - ${API_PORT:-8102} healthcheck: test: [ "CMD", "python", "-c", "import os, urllib.request; port=os.environ.get('API_PORT','8102'); urllib.request.urlopen(f'http://127.0.0.1:{port}/v1/admin/health', timeout=5).read()", ] interval: 30s timeout: 5s start_period: 30s retries: 3