# ============================================================================= # VM PRINCIPAL — Project Afterlife (Soft Launch) # ============================================================================= # IP Privada: 10.0.0.10 # Puertos Publicos: 80, 443 # Servicios: Next.js, Strapi CMS, Authentik SSO, PostgreSQL x2, Redis, MinIO, Nginx, Certbot # # Esta es la VM principal donde corre toda la plataforma web, autenticacion # y administracion. Los servidores de juegos corren en VMs separadas. # ============================================================================= services: # --------------------------------------------------------------------------- # PostgreSQL — Base de datos para Strapi CMS # --------------------------------------------------------------------------- postgres: image: postgres:16-alpine restart: unless-stopped container_name: main-postgres volumes: - postgres_data:/var/lib/postgresql/data environment: POSTGRES_DB: ${DATABASE_NAME:-afterlife} POSTGRES_USER: ${DATABASE_USERNAME:-afterlife} POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-afterlife} ports: - "127.0.0.1:5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME:-afterlife}"] interval: 5s timeout: 5s retries: 5 networks: - main-internal # --------------------------------------------------------------------------- # PostgreSQL — Base de datos para Authentik # --------------------------------------------------------------------------- authentik-postgres: image: docker.io/library/postgres:16-alpine restart: unless-stopped container_name: main-authentik-postgres healthcheck: test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] start_period: 20s interval: 30s retries: 5 timeout: 5s volumes: - authentik_postgres_data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik} POSTGRES_USER: ${AUTHENTIK_POSTGRES_USER:-authentik} POSTGRES_DB: ${AUTHENTIK_POSTGRES_DB:-authentik} ports: - "127.0.0.1:5433:5432" networks: - main-internal # --------------------------------------------------------------------------- # Redis — Cache para Authentik # --------------------------------------------------------------------------- authentik-redis: image: docker.io/library/redis:alpine restart: unless-stopped container_name: main-authentik-redis healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] start_period: 20s interval: 30s retries: 5 timeout: 3s volumes: - authentik_redis_data:/data networks: - main-internal # --------------------------------------------------------------------------- # MinIO — Almacenamiento S3-compatible # --------------------------------------------------------------------------- minio: image: minio/minio:latest restart: unless-stopped container_name: main-minio command: server /data --console-address ":9001" volumes: - minio_data:/data environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER:-afterlife} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-afterlife123} ports: - "127.0.0.1:9000:9000" - "127.0.0.1:9001:9001" networks: - main-internal # --------------------------------------------------------------------------- # Authentik Server — SSO / Identity Provider # --------------------------------------------------------------------------- authentik-server: image: ghcr.io/goauthentik/server:latest restart: unless-stopped container_name: main-authentik-server command: server environment: AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_REDIS__HOST: authentik-redis AUTHENTIK_POSTGRESQL__HOST: authentik-postgres AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRES_DB:-authentik} AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRES_USER:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik} AUTHENTIK_LISTEN__HTTP: 0.0.0.0:9000 AUTHENTIK_LISTEN__HTTPS: 0.0.0.0:9443 expose: - "9000" - "9443" volumes: - authentik_media:/media - authentik_custom_templates:/templates depends_on: - authentik-postgres - authentik-redis networks: - main-internal # --------------------------------------------------------------------------- # Authentik Worker — Tareas en background # --------------------------------------------------------------------------- authentik-worker: image: ghcr.io/goauthentik/server:latest restart: unless-stopped container_name: main-authentik-worker command: worker environment: AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_REDIS__HOST: authentik-redis AUTHENTIK_POSTGRESQL__HOST: authentik-postgres AUTHENTIK_POSTGRESQL__NAME: ${AUTHENTIK_POSTGRES_DB:-authentik} AUTHENTIK_POSTGRESQL__USER: ${AUTHENTIK_POSTGRES_USER:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:-authentik} user: root volumes: - authentik_media:/media - authentik_custom_templates:/templates - /var/run/docker.sock:/var/run/docker.sock depends_on: - authentik-postgres - authentik-redis networks: - main-internal # --------------------------------------------------------------------------- # Strapi CMS — Content Management # --------------------------------------------------------------------------- cms: build: context: ../apps/cms dockerfile: Dockerfile restart: unless-stopped container_name: main-cms depends_on: postgres: condition: service_healthy environment: HOST: 0.0.0.0 PORT: 1337 DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_NAME: ${DATABASE_NAME:-afterlife} DATABASE_USERNAME: ${DATABASE_USERNAME:-afterlife} DATABASE_PASSWORD: ${DATABASE_PASSWORD:-afterlife} APP_KEYS: ${APP_KEYS} API_TOKEN_SALT: ${API_TOKEN_SALT} ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET} TRANSFER_TOKEN_SALT: ${TRANSFER_TOKEN_SALT} JWT_SECRET: ${JWT_SECRET} # Authentik OIDC for CMS admin SSO AUTHENTIK_URL: ${AUTHENTIK_URL:-http://authentik-server:9000} AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID_CMS:-} AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET_CMS:-} AUTHENTIK_REDIRECT_URI: ${AUTHENTIK_REDIRECT_URI_CMS:-} PUBLIC_STRAPI_URL: ${PUBLIC_STRAPI_URL:-https://play.consultoria-as.com} expose: - "1337" networks: - main-internal # --------------------------------------------------------------------------- # Next.js — Frontend Web # --------------------------------------------------------------------------- web: build: context: ../ dockerfile: apps/web/Dockerfile restart: unless-stopped container_name: main-web depends_on: - cms - authentik-server environment: STRAPI_URL: http://cms:1337 STRAPI_API_TOKEN: ${STRAPI_API_TOKEN:-} NEXT_PUBLIC_STRAPI_URL: ${PUBLIC_STRAPI_URL:-https://play.consultoria-as.com} # Authentik OIDC AUTHENTIK_URL: ${AUTHENTIK_URL:-http://authentik-server:9000} AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID_WEB:-} AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET_WEB:-} AUTHENTIK_REDIRECT_URI: ${AUTHENTIK_REDIRECT_URI_WEB:-} # Public game server IPs (displayed to players) NEXT_PUBLIC_NIER_IP: ${NIER_PUBLIC_IP:-play.consultoria-as.com} NEXT_PUBLIC_DBO_IP: ${DBO_PUBLIC_IP:-play.consultoria-as.com} NEXT_PUBLIC_MAPLE2_IP: ${MAPLE2_PUBLIC_IP:-play.consultoria-as.com} NEXT_PUBLIC_FUSIONFALL_IP: ${FUSIONFALL_PUBLIC_IP:-play.consultoria-as.com} NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-https://play.consultoria-as.com} expose: - "3000" networks: - main-internal # --------------------------------------------------------------------------- # Nginx — Reverse Proxy + SSL # --------------------------------------------------------------------------- nginx: image: nginx:alpine restart: unless-stopped container_name: main-nginx depends_on: - web - cms - authentik-server ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.main.conf:/etc/nginx/nginx.conf:ro - certbot_certs:/etc/letsencrypt:ro - certbot_www:/var/www/certbot:ro networks: - main-internal # --------------------------------------------------------------------------- # Certbot — SSL automático # --------------------------------------------------------------------------- certbot: image: certbot/certbot container_name: main-certbot volumes: - certbot_certs:/etc/letsencrypt - certbot_www:/var/www/certbot entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h; done'" volumes: postgres_data: authentik_postgres_data: authentik_redis_data: authentik_media: authentik_custom_templates: minio_data: certbot_certs: certbot_www: networks: main-internal: driver: bridge