Ctrl K
ComunidadGuías…

compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
name: eve-space

services:
  postgres:
    image: postgres:17-alpine
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-eve_space}
      POSTGRES_USER: ${POSTGRES_USER:-eve_space}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}
    ports:
      - '${POSTGRES_PORT:-5432}:5432'
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}']
      interval: 10m
      timeout: 3s
      retries: 3
      start_period: 30s
      start_interval: 2s

  queue-redis:
    image: redis:7.4.7-alpine
    command:
      [
        'redis-server',
        '--appendonly',
        'yes',
        '--appendfsync',
        'always',
        '--maxmemory',
        '${QUEUE_REDIS_MAXMEMORY:-512mb}',
        '--maxmemory-policy',
        'noeviction',
      ]
    volumes:
      - queue_redis_data:/data
    ports:
      - '${QUEUE_REDIS_PORT:-6379}:6379'
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'redis-cli ping | grep -qx PONG && redis-cli --raw config get maxmemory-policy | grep -qx noeviction && maxmemory=$$(redis-cli --raw config get maxmemory | grep -E ''^[0-9]+$$'') && used=$$(redis-cli --raw info memory | grep ''^used_memory:'' | cut -d: -f2) && test "$$maxmemory" -gt 0 && test "$$used" -lt "$$((maxmemory * 90 / 100))"',
        ]
      interval: 10m
      timeout: 3s
      retries: 3
      start_period: 30s
      start_interval: 2s

  cache-redis:
    image: redis:7.4.7-alpine
    command:
      [
        'redis-server',
        '--appendonly',
        'no',
        '--save',
        '',
        '--maxmemory',
        '${CACHE_REDIS_MAXMEMORY:-256mb}',
        '--maxmemory-policy',
        'allkeys-lfu',
      ]
    ports:
      - '${CACHE_REDIS_PORT:-6380}:6379'
    healthcheck:
      test:
        [
          'CMD-SHELL',
          'redis-cli ping | grep -qx PONG && redis-cli --raw config get maxmemory-policy | grep -qx allkeys-lfu && maxmemory=$$(redis-cli --raw config get maxmemory | grep -E ''^[0-9]+$$'') && used=$$(redis-cli --raw info memory | grep ''^used_memory:'' | cut -d: -f2) && test "$$maxmemory" -gt 0 && test "$$used" -lt "$$((maxmemory * 90 / 100))"',
        ]
      interval: 10m
      timeout: 3s
      retries: 3
      start_period: 30s
      start_interval: 2s

  api:
    build:
      context: .
      dockerfile: api/Dockerfile
    stop_grace_period: 40s
    # Pool, refresh, cache, and heartbeat tuning is documented in `.env.example` and read by
    # `env.ts` in both processes. The explicit `environment` map below still wins, so topology
    # stays container-relative.
    env_file:
      - path: .env
        required: false
    environment:
      NODE_ENV: production
      PORT: 8787
      DATABASE_URL: postgres://${POSTGRES_USER:-eve_space}@postgres:5432/${POSTGRES_DB:-eve_space}
      PGPASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}
      WEB_ORIGIN: ${WEB_ORIGIN:-http://localhost:3000}
      EVE_CLIENT_ID: ${EVE_CLIENT_ID:-}
      EVE_CLIENT_SECRET: ${EVE_CLIENT_SECRET:-}
      EVE_CALLBACK_URL: ${EVE_CALLBACK_URL:-http://localhost:8788/auth/eve/callback}
      EVE_SCOPES: ${EVE_SCOPES:-esi-assets.read_assets.v1 esi-wallet.read_character_wallet.v1 esi-markets.read_character_orders.v1 esi-markets.structure_markets.v1 esi-contracts.read_character_contracts.v1 esi-location.read_location.v1 esi-location.read_ship_type.v1 esi-skills.read_skills.v1 esi-skills.read_skillqueue.v1 esi-clones.read_clones.v1 esi-clones.read_implants.v1 esi-mail.read_mail.v1 esi-mail.organize_mail.v1 esi-mail.send_mail.v1 esi-search.search_structures.v1 esi-characters.read_contacts.v1 esi-characters.read_corporation_roles.v1 esi-corporations.read_corporation_membership.v1 esi-characters.read_freelance_jobs.v1 esi-corporations.read_freelance_jobs.v1 esi-corporations.read_projects.v1 esi.activity.char:read}
      ESI_USER_AGENT: ${ESI_USER_AGENT:-EveSpace/0.1 (+https://github.com/mskry/eve-space) @evespace/esi-client/3.1.0}
      TOKEN_ENCRYPTION_KEY: ${TOKEN_ENCRYPTION_KEY:-}
      ADMIN_SETUP_SECRET: ${ADMIN_SETUP_SECRET:-}
      QUEUE_REDIS_URL: redis://queue-redis:6379
      CACHE_REDIS_URL: redis://cache-redis:6379
    ports:
      - '8788:8787'
    depends_on:
      postgres:
        condition: service_healthy
      queue-redis:
        condition: service_healthy
      cache-redis:
        condition: service_started
    healthcheck:
      test:
        [
          'CMD',
          'node',
          '-e',
          "fetch('http://localhost:8787/health').then(r => { if (!r.ok) process.exit(1) })",
        ]
      interval: 10m
      timeout: 3s
      retries: 3
      start_period: 30s
      start_interval: 2s

  worker:
    build:
      context: .
      dockerfile: api/Dockerfile
    init: true
    entrypoint: ['node', 'dist/worker.js']
    stop_grace_period: 40s
    env_file:
      - path: .env
        required: false
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://${POSTGRES_USER:-eve_space}@postgres:5432/${POSTGRES_DB:-eve_space}
      PGPASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in .env}
      QUEUE_REDIS_URL: redis://queue-redis:6379
      CACHE_REDIS_URL: redis://cache-redis:6379
      EVE_SCOPES: ${EVE_SCOPES:-esi-assets.read_assets.v1 esi-wallet.read_character_wallet.v1 esi-markets.read_character_orders.v1 esi-markets.structure_markets.v1 esi-contracts.read_character_contracts.v1 esi-location.read_location.v1 esi-location.read_ship_type.v1 esi-skills.read_skills.v1 esi-skills.read_skillqueue.v1 esi-clones.read_clones.v1 esi-clones.read_implants.v1 esi-mail.read_mail.v1 esi-mail.organize_mail.v1 esi-mail.send_mail.v1 esi-search.search_structures.v1 esi-characters.read_contacts.v1 esi-characters.read_corporation_roles.v1 esi-corporations.read_corporation_membership.v1 esi-characters.read_freelance_jobs.v1 esi-corporations.read_freelance_jobs.v1 esi-corporations.read_projects.v1 esi.activity.char:read}
      QUEUE_PLANNER_SCHEDULE: ${QUEUE_PLANNER_SCHEDULE:-*/15 * * * *}
      QUEUE_PLANNER_SCHEDULE_OFFSET_MS: ${QUEUE_PLANNER_SCHEDULE_OFFSET_MS:-}
      QUEUE_PLANNER_INITIAL_DELAY_MAX_MS: ${QUEUE_PLANNER_INITIAL_DELAY_MAX_MS:-60000}
    depends_on:
      api:
        condition: service_healthy
      queue-redis:
        condition: service_healthy
      cache-redis:
        condition: service_started
    healthcheck:
      test: ['CMD', 'node', 'dist/worker/health.js']
      interval: 10m
      timeout: 3s
      retries: 3
      start_period: 30s
      start_interval: 2s

volumes:
  postgres_data:
  queue_redis_data: