# ─── Self-hosting this project ───────────────────────────────────────
#
# Two containers: PostgreSQL, and the Rebase runtime with your built project
# mounted into it. There is no application image to build here — the runtime is
# the same published image every Rebase deployment runs, and your project
# travels as a bundle.
#
# That is the point: the artifact you self-host is the artifact Rebase Cloud
# runs. Nothing about this repository changes when you move between them; only
# the destination does, and that lives in `.rebase/cloud.json`, which is not
# committed.
#
#   rebase build              # produces ./dist-bundle
#   docker compose up -d db
#   rebase db push            # create the collection tables, once
#   docker compose up
#
# One container then serves the API at /api and the admin at / — same origin, so
# there is no CORS to configure between them and no second web server.
#
# For development, use `rebase dev` instead.
#
# To upgrade Rebase, change REBASE_VERSION and restart. Your bundle is untouched.
# To run your OWN server code instead, `rebase eject` — it writes the entrypoint,
# a Dockerfile and a compose file that builds them.
# ─────────────────────────────────────────────────────────────────────

name: {{PROJECT_NAME}}

services:
  # ── PostgreSQL ───────────────────────────────────────────────────────
  db:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: rebase_app
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-changeme}
      POSTGRES_DB: rebase
    # Published so `rebase db push` can reach it from the host. Remove this
    # mapping once the schema is in place if the database should not be
    # reachable from outside the compose network.
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql
    healthcheck:
      # The runtime must not start before the database can answer, or its first
      # boot fails on a connection refused and the container restarts for no
      # reason a reader would understand.
      test: ["CMD-SHELL", "pg_isready -U rebase_app -d rebase"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 10s
    command:
      - "postgres"
      - "-c"
      - "shared_buffers=256MB"
      - "-c"
      - "max_connections=100"
      - "-c"
      - "work_mem=4MB"
      - "-c"
      - "effective_cache_size=768MB"
      - "-c"
      - "log_min_duration_statement=1000"

  # ── The Rebase runtime, booting your bundle ──────────────────────────
  api:
    image: rebasepro/server:${REBASE_VERSION:-latest}
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "${PORT:-3001}:3001"
    environment:
      DATABASE_URL: postgresql://rebase_app:${DATABASE_PASSWORD:-changeme}@db:5432/rebase?options=-c%20search_path%3Dpublic
      ADMIN_CONNECTION_STRING: postgresql://rebase_app:${DATABASE_PASSWORD:-changeme}@db:5432/rebase?options=-c%20search_path%3Dpublic
      JWT_SECRET: ${JWT_SECRET:?set JWT_SECRET in .env — `rebase init` generates one}
      REBASE_SERVICE_KEY: ${REBASE_SERVICE_KEY:?set REBASE_SERVICE_KEY in .env — `rebase init` generates one}
      NODE_ENV: production
      PORT: "3001"

      # The origins a browser will load the admin from. With the admin folded
      # into the bundle it is served from this very container, so this is just
      # your own address — but it is still required, because an API that guesses
      # its allowed origins is one that eventually allows the wrong one.
      CORS_ORIGINS: ${CORS_ORIGINS:?set CORS_ORIGINS to the origin you browse to, e.g. http://localhost:3001}

      # Auth tables are created at boot. Collection tables are not: run
      # `rebase db push` once, against the database above. A container restart
      # must not be able to change a schema as a side effect.
      REBASE_MIGRATE_ON_BOOT: ${REBASE_MIGRATE_ON_BOOT:-ensure}

      # Uploads land on the named volume below, which survives restarts. That is
      # the case FORCE_LOCAL_STORAGE exists to acknowledge — without a durable
      # mount the server refuses local storage in production, because the
      # container filesystem is destroyed on the next deploy and every uploaded
      # file goes with it. Switch to STORAGE_TYPE=s3 or gcs and drop both lines
      # if you move storage off-box.
      STORAGE_PATH: /uploads
      FORCE_LOCAL_STORAGE: "true"
    volumes:
      # Your built project. Writable, because the runtime installs the bundle's
      # declared dependencies into it on first start — `rebase build` emits a
      # package.json but not a node_modules.
      - ./dist-bundle:/bundle
      - uploads:/uploads

volumes:
  postgres_data:
    driver: local
  uploads:
    driver: local
