docker-compose.yml
Rama main · réplica de lectura del repositorio original.
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: tasktopia
POSTGRES_USER: tasktopia
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me}
volumes:
- tasktopia_postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U tasktopia -d tasktopia"]
interval: 5s
timeout: 5s
retries: 12
security_opt:
- no-new-privileges:true
pids_limit: 100
mem_limit: ${POSTGRES_MEMORY_LIMIT:-1g}
cpus: ${POSTGRES_CPU_LIMIT:-1.00}
cpu_shares: 512
redis:
image: redis:8-alpine
profiles: ["cache"]
restart: unless-stopped
command: ["redis-server", "--save", "", "--appendonly", "no", "--maxmemory", "${REDIS_MEMORY_LIMIT:-256mb}", "--maxmemory-policy", "allkeys-lru"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
pids_limit: 64
mem_limit: ${REDIS_CONTAINER_MEMORY_LIMIT:-320m}
cpus: ${REDIS_CPU_LIMIT:-0.50}
app:
stop_grace_period: 35s
image: ${APP_IMAGE:-${COMPOSE_PROJECT_NAME:-tasktopia}-app:latest}
build:
context: .
args:
STATIC_ORIGIN: ${STATIC_ORIGIN:-}
restart: unless-stopped
environment:
NODE_ENV: production
HOST: 0.0.0.0
PORT: 3000
RUNTIME_ROLE: web
DATABASE_POOL_MAX: 10
GENERATION_WAIT_MS: ${GENERATION_WAIT_MS:-55000}
REDIS_URL: ${REDIS_URL:-}
REDIS_CHUNK_TTL_SECONDS: ${REDIS_CHUNK_TTL_SECONDS:-300}
REDIS_OPERATION_TIMEOUT_MS: ${REDIS_OPERATION_TIMEOUT_MS:-40}
DATABASE_URL: postgres://tasktopia:${POSTGRES_PASSWORD:-change-me}@postgres:5432/tasktopia
APP_ORIGIN: ${APP_ORIGIN:-http://localhost:3000}
STATIC_ORIGIN: ${STATIC_ORIGIN:-}
SESSION_COOKIE_SECURE: ${SESSION_COOKIE_SECURE:-false}
REGISTRATION_ENABLED: ${REGISTRATION_ENABLED:-false}
VAPID_SUBJECT: ${VAPID_SUBJECT:-}
VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY:-}
VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY:-}
TRUST_PROXY: "true"
LOG_LEVEL: ${LOG_LEVEL:-info}
OBSERVABILITY_TOKEN: ${OBSERVABILITY_TOKEN:-}
UPLOAD_DIR: /data/uploads
volumes:
- tasktopia_uploads:/data/uploads
- tasktopia_asset_revisions:/app/dist/public/game-assets/v5/revisions
depends_on:
postgres:
condition: service_healthy
ports:
- "${APP_BIND_ADDRESS:-127.0.0.1}:${APP_PORT:-3000}:3000"
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
pids_limit: 160
mem_limit: ${APP_MEMORY_LIMIT:-1536m}
cpus: ${APP_CPU_LIMIT:-2.00}
cpu_shares: 1024
init: true
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
mcp:
stop_grace_period: 35s
image: ${APP_IMAGE:-${COMPOSE_PROJECT_NAME:-tasktopia}-app:latest}
restart: unless-stopped
environment:
NODE_ENV: production
HOST: 0.0.0.0
PORT: 3000
RUNTIME_ROLE: mcp
DATABASE_POOL_MAX: 4
GENERATION_WAIT_MS: ${GENERATION_WAIT_MS:-55000}
REDIS_URL: ${REDIS_URL:-}
REDIS_CHUNK_TTL_SECONDS: ${REDIS_CHUNK_TTL_SECONDS:-300}
REDIS_OPERATION_TIMEOUT_MS: ${REDIS_OPERATION_TIMEOUT_MS:-40}
DATABASE_URL: postgres://tasktopia:${POSTGRES_PASSWORD:-change-me}@postgres:5432/tasktopia
APP_ORIGIN: ${APP_ORIGIN:-http://localhost:3000}
SESSION_COOKIE_SECURE: ${SESSION_COOKIE_SECURE:-false}
TRUST_PROXY: "true"
LOG_LEVEL: ${LOG_LEVEL:-info}
OBSERVABILITY_TOKEN: ${OBSERVABILITY_TOKEN:-}
UPLOAD_DIR: /data/uploads
volumes:
- tasktopia_uploads:/data/uploads
depends_on:
postgres:
condition: service_healthy
ports:
- "127.0.0.1:${MCP_PORT:-3002}:3000"
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
pids_limit: 96
mem_limit: ${MCP_MEMORY_LIMIT:-768m}
cpus: ${MCP_CPU_LIMIT:-1.00}
cpu_shares: 512
init: true
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
world:
stop_grace_period: 35s
image: ${APP_IMAGE:-${COMPOSE_PROJECT_NAME:-tasktopia}-app:latest}
restart: unless-stopped
environment:
NODE_ENV: production
HOST: 0.0.0.0
PORT: 3000
RUNTIME_ROLE: world
DATABASE_POOL_MAX: 4
REDIS_URL: ${REDIS_URL:-}
REDIS_CHUNK_TTL_SECONDS: ${REDIS_CHUNK_TTL_SECONDS:-300}
REDIS_OPERATION_TIMEOUT_MS: ${REDIS_OPERATION_TIMEOUT_MS:-40}
DATABASE_URL: postgres://tasktopia:${POSTGRES_PASSWORD:-change-me}@postgres:5432/tasktopia
APP_ORIGIN: ${APP_ORIGIN:-http://localhost:3000}
SESSION_COOKIE_SECURE: ${SESSION_COOKIE_SECURE:-false}
REGISTRATION_ENABLED: "false"
TRUST_PROXY: "true"
LOG_LEVEL: ${LOG_LEVEL:-info}
OBSERVABILITY_TOKEN: ${OBSERVABILITY_TOKEN:-}
UPLOAD_DIR: /data/uploads
volumes:
- tasktopia_uploads:/data/uploads
depends_on:
postgres:
condition: service_healthy
ports:
- "127.0.0.1:${WORLD_PORT:-3003}:3000"
healthcheck:
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3000/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
pids_limit: 160
mem_limit: ${WORLD_MEMORY_LIMIT:-1536m}
cpus: ${WORLD_CPU_LIMIT:-2.00}
cpu_shares: 768
init: true
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
volumes:
tasktopia_postgres:
tasktopia_uploads:
tasktopia_asset_revisions: