# Restora — self-hosted local stack, for a single restaurant/tenant running
# on its own server, reachable from the restaurant's own LAN (staff phones,
# kitchen tablets, POS terminals). No source code involved: every app
# service runs from a pre-built image, never `build: .` — this is the file
# a customer downloads and runs, they never see or touch the codebase.
#
# Unlike a cloud/SaaS stack (Traefik + HTTPS + a public domain), this stack
# is meant for a LAN with no domain name: services are exposed directly on
# their ports, and the app resolves its own API/asset URLs from whatever
# hostname/IP the browser used to load the page (see restora-frontend's
# src/lib/runtime-endpoints.ts) — the same mechanism that already makes
# table QR codes work correctly from a configurable LAN IP (Configuration →
# Paramètres avancés → URL de base).
#
# Usage:
#   1. cp .env.local.example .env
#   2. Edit .env — at minimum set RESTORA_API_IMAGE / RESTORA_WEB_IMAGE /
#      RESTORA_WORKER_IMAGE to wherever you published the images (see
#      docs/PUBLISHING_IMAGES.md), and change every secret.
#   3. ./scripts/install-local.sh
#
# This file is downloadable as-is from the Restora app's "Télécharger" /
# "Installer en local" page — it never changes based on who downloads it.

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 5s
      timeout: 5s
      retries: 10
    networks: [restora]

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 5s
      retries: 10
    networks: [restora]

  minio:
    image: minio/minio:latest
    restart: unless-stopped
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
    volumes:
      - minio-data:/data
    ports:
      # Console only — useful on a LAN to inspect uploaded product photos.
      # Never publish this port on a server reachable from the internet.
      - "${MINIO_CONSOLE_PORT:-9001}:9001"
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 5s
      timeout: 5s
      retries: 10
    networks: [restora]

  api:
    image: ${RESTORA_API_IMAGE:?Set RESTORA_API_IMAGE in .env to your published api image}
    restart: unless-stopped
    environment:
      NODE_ENV: production
      # The LAN address staff/kitchen devices use to reach this server — the
      # same value the web service uses for QR codes. Signup confirmation
      # and password reset emails build their links from this, so it must
      # be the real reachable address, not the container-internal default.
      APP_BASE_URL: ${APP_BASE_URL:-http://localhost:3001}
      DATABASE_URL: ${DATABASE_URL}
      REDIS_URL: redis://redis:6379
      JWT_ACCESS_SECRET: ${JWT_ACCESS_SECRET}
      JWT_ACCESS_TTL: ${JWT_ACCESS_TTL:-15m}
      # LAN deployment: any device on the restaurant's own network may load
      # the app from a different local IP than the server's — never
      # internet-facing, so reflecting any origin here is the correct
      # (not just convenient) choice, unlike a real public deployment.
      CORS_ALLOW_PRIVATE_NETWORK: "true"
      PORT: 3000
      LOG_LEVEL: ${LOG_LEVEL:-info}
      # Provider-neutral names read by the api container (see the main
      # Restora repo's apps/api/src/storage/storage.service.ts) — mapped
      # here from the local MinIO container's own credentials below.
      STORAGE_ENDPOINT: http://minio:9000
      STORAGE_ACCESS_KEY_ID: ${MINIO_ROOT_USER}
      STORAGE_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}
      STORAGE_BUCKET: ${MINIO_BUCKET:-restora-uploads}
      # Until SMTP_PASSWORD is changed from the placeholder, the API logs
      # emails instead of sending them — the restaurant admin's password
      # reset link still works via docker compose logs even with no SMTP
      # configured.
      SMTP_HOST: ${SMTP_HOST:-}
      SMTP_PORT: ${SMTP_PORT:-465}
      SMTP_SECURE: ${SMTP_SECURE:-true}
      SMTP_USER: ${SMTP_USER:-}
      SMTP_PASSWORD: ${SMTP_PASSWORD:-change_me}
      SMTP_FROM: ${SMTP_FROM:-Restora <no-reply@example.com>}
    # The runtime image has no pnpm workspace root, so migrations run via
    # the local prisma binary rather than `pnpm --filter`.
    command: sh -c "./node_modules/.bin/prisma migrate deploy && node -r tsx/cjs dist/main.js"
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      minio:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    ports:
      - "${API_PORT:-3000}:3000"
    networks: [restora]

  worker:
    image: ${RESTORA_WORKER_IMAGE:?Set RESTORA_WORKER_IMAGE in .env to your published worker image}
    restart: unless-stopped
    environment:
      NODE_ENV: production
      REDIS_URL: redis://redis:6379
    depends_on:
      redis:
        condition: service_healthy
    networks: [restora]

  web:
    image: ${RESTORA_WEB_IMAGE:?Set RESTORA_WEB_IMAGE in .env to your published web image}
    restart: unless-stopped
    environment:
      NODE_ENV: production
      PORT: 3001
    depends_on:
      - api
    ports:
      - "${WEB_PORT:-3001}:3001"
    networks: [restora]

networks:
  restora:
    driver: bridge

volumes:
  postgres-data:
  redis-data:
  minio-data:
