services: postgres: image: postgres:18-alpine container_name: mumulingsi-postgres environment: POSTGRES_DB: ${POSTGRES_DB:-mumulingsi_novel} POSTGRES_USER: ${POSTGRES_USER:-mumulingsi} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-123456} POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C" TZ: ${TZ:-Asia/Shanghai} volumes: - postgres_data:/var/lib/postgresql - ./backend/scripts/init_postgres.sql:/docker-entrypoint-initdb.d/init.sql:ro ports: - "${POSTGRES_PORT:-5432}:5432" restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-mumulingsi} -d ${POSTGRES_DB:-mumulingsi_novel}"] interval: 10s timeout: 5s retries: 5 start_period: 10s networks: - ai-story-network command: - postgres - -c - max_connections=${POSTGRES_MAX_CONNECTIONS:-200} - -c - shared_buffers=${POSTGRES_SHARED_BUFFERS:-256MB} - -c - effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-1GB} - -c - maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB} - -c - checkpoint_completion_target=${POSTGRES_CHECKPOINT_COMPLETION_TARGET:-0.9} - -c - wal_buffers=${POSTGRES_WAL_BUFFERS:-16MB} - -c - default_statistics_target=${POSTGRES_DEFAULT_STATISTICS_TARGET:-100} - -c - random_page_cost=${POSTGRES_RANDOM_PAGE_COST:-1.1} - -c - effective_io_concurrency=${POSTGRES_EFFECTIVE_IO_CONCURRENCY:-200} - -c - work_mem=${POSTGRES_WORK_MEM:-4MB} - -c - min_wal_size=${POSTGRES_MIN_WAL_SIZE:-1GB} - -c - max_wal_size=${POSTGRES_MAX_WAL_SIZE:-4GB} mumulingsi: build: context: . dockerfile: Dockerfile args: - USE_CN_MIRROR=${USE_CN_MIRROR:-false} image: mumulingsi-project/mumulingsi:latest container_name: mumulingsi depends_on: postgres: condition: service_healthy ports: - "${APP_PORT:-8000}:8000" volumes: - ./logs:/app/logs - ./storage/generated_covers:/app/storage/generated_covers - ./.env:/app/.env:ro environment: # 时区配置 - TZ=${TZ:-Asia/Shanghai} # 应用配置 - APP_NAME=${APP_NAME:-墨木灵思} - APP_VERSION=${APP_VERSION:-1.0.0} - APP_HOST=${APP_HOST:-0.0.0.0} - APP_PORT=8000 - DEBUG=${DEBUG:-false} # 数据库配置 - DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER:-mumulingsi}:${POSTGRES_PASSWORD:-123456}@postgres:5432/${POSTGRES_DB:-mumulingsi_novel} # 数据库连接信息(用于 entrypoint.sh,须与 postgres 服务一致) - DB_HOST=postgres - DB_PORT=5432 - POSTGRES_USER=${POSTGRES_USER:-mumulingsi} - POSTGRES_DB=${POSTGRES_DB:-mumulingsi_novel} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-123456} # PostgreSQL 连接池配置 - DATABASE_POOL_SIZE=${DATABASE_POOL_SIZE:-30} - DATABASE_MAX_OVERFLOW=${DATABASE_MAX_OVERFLOW:-20} - DATABASE_POOL_TIMEOUT=${DATABASE_POOL_TIMEOUT:-60} - DATABASE_POOL_RECYCLE=${DATABASE_POOL_RECYCLE:-1800} - DATABASE_POOL_PRE_PING=${DATABASE_POOL_PRE_PING:-True} - DATABASE_POOL_USE_LIFO=${DATABASE_POOL_USE_LIFO:-True} # 代理配置(可选) - HTTP_PROXY=${HTTP_PROXY:-} - HTTPS_PROXY=${HTTPS_PROXY:-} - NO_PROXY=${NO_PROXY:-localhost,127.0.0.1} # AI 服务配置 - OPENAI_API_KEY=${OPENAI_API_KEY:-} - OPENAI_BASE_URL=${OPENAI_BASE_URL:-https://api.openai.com/v1} - GEMINI_API_KEY=${GEMINI_API_KEY:-} - GEMINI_BASE_URL=${GEMINI_BASE_URL:-} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - ANTHROPIC_BASE_URL=${ANTHROPIC_BASE_URL:-} - DEFAULT_AI_PROVIDER=${DEFAULT_AI_PROVIDER:-openai} - DEFAULT_MODEL=${DEFAULT_MODEL:-gpt-4o-mini} - DEFAULT_TEMPERATURE=${DEFAULT_TEMPERATURE:-0.7} - DEFAULT_MAX_TOKENS=${DEFAULT_MAX_TOKENS:-32000} # LinuxDO OAuth 配置 - LINUXDO_CLIENT_ID=${LINUXDO_CLIENT_ID:-11111} - LINUXDO_CLIENT_SECRET=${LINUXDO_CLIENT_SECRET:-11111} - LINUXDO_REDIRECT_URI=${LINUXDO_REDIRECT_URI:-http://localhost:8000/api/auth/linuxdo/callback} - FRONTEND_URL=${FRONTEND_URL:-http://localhost:8000} # 本地账户登录配置 - LOCAL_AUTH_ENABLED=${LOCAL_AUTH_ENABLED:-true} - LOCAL_AUTH_USERNAME=${LOCAL_AUTH_USERNAME:-admin} - LOCAL_AUTH_PASSWORD=${LOCAL_AUTH_PASSWORD:-admin123} - LOCAL_AUTH_DISPLAY_NAME=${LOCAL_AUTH_DISPLAY_NAME:-本地管理员} # 会话配置 - SESSION_EXPIRE_MINUTES=${SESSION_EXPIRE_MINUTES:-120} - SESSION_REFRESH_THRESHOLD_MINUTES=${SESSION_REFRESH_THRESHOLD_MINUTES:-30} - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true} restart: unless-stopped healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"] interval: 30s timeout: 10s retries: 3 start_period: 30s networks: - ai-story-network volumes: postgres_data: driver: local networks: ai-story-network: driver: bridge