# =============================================================================
# Tanabata File Manager — Docker Compose
#
# Quick start:
#   cp .env.example .env        # then edit the secrets
#   docker compose up -d --build
#
# Database — two supported modes, selected in .env:
#
#   1. Bundled Postgres container (default).
#        COMPOSE_PROFILES=with-db
#        DATABASE_URL=postgres://tanabata:password@db:5432/tanabata?sslmode=disable
#
#   2. Postgres already running on the host.
#        COMPOSE_PROFILES=          # empty → the db container is not started
#        DATABASE_URL=postgres://tanabata:password@host.docker.internal:5432/tanabata?sslmode=disable
#
# Requires Docker Compose v2.20+ (for depends_on.required).
# =============================================================================

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped

    # All application config (secrets, DATABASE_URL, tunables) comes from .env.
    env_file: .env

    # Pin STATIC_DIR to the path baked into the image. .env intentionally leaves
    # it unset; pinning here guarantees in-container SPA serving can't be
    # disabled by an empty value leaking in through env_file.
    environment:
      STATIC_DIR: /app/static

    # The container always listens on 42776 (Dockerfile default); APP_PORT only
    # changes the host-published port.
    ports:
      - "${APP_PORT:-42776}:42776"

    # Wait for the bundled DB when the with-db profile is active. When using a
    # host Postgres the db service is disabled, and required:false keeps this
    # dependency from erroring or auto-starting it.
    depends_on:
      db:
        condition: service_healthy
        required: false

    # Lets DATABASE_URL reach a Postgres on the host via host.docker.internal
    # (needed on Linux; harmless elsewhere).
    extra_hosts:
      - "host.docker.internal:host-gateway"

    # Run as this uid:gid. Relevant when the mounts below are bind-mounted to
    # host folders: set PUID/PGID (in .env) to the owner of those folders so the
    # container can write to them. Defaults to the image's tanabata user
    # (42776), which owns the named volumes.
    user: "${PUID:-42776}:${PGID:-42776}"

    # Storage for originals, the thumbnail cache, and the import drop folder.
    # Each source defaults to a named volume but can be pointed at a specific
    # host folder via FILES_DIR / THUMBS_DIR / IMPORT_DIR in .env (a path turns
    # the mount into a host bind mount; a bare name stays a named volume).
    volumes:
      - "${FILES_DIR:-app_files}:/data/files"
      - "${THUMBS_DIR:-app_thumbs}:/data/thumbs"
      - "${IMPORT_DIR:-app_import}:/data/import"

  db:
    image: postgres:14-alpine
    restart: unless-stopped

    # Only started when COMPOSE_PROFILES includes "with-db". Disable it to point
    # the app at a Postgres running on the host instead.
    profiles: ["with-db"]

    environment:
      POSTGRES_DB: ${POSTGRES_DB:-tanabata}
      POSTGRES_USER: ${POSTGRES_USER:-tanabata}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password}

    # Defaults to a named volume; set DB_DIR in .env to a host folder to bind
    # mount it instead. Postgres fixes the folder's ownership itself, so DB_DIR
    # needs no PUID/PGID.
    volumes:
      - "${DB_DIR:-db_data}:/var/lib/postgresql/data"

    # Uncomment to reach the DB from the host (e.g. with psql) for debugging.
    # ports:
    #   - "5432:5432"

    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-tanabata} -d ${POSTGRES_DB:-tanabata}"]
      interval: 5s
      timeout: 5s
      retries: 10

volumes:
  app_files:
  app_thumbs:
  app_import:
  db_data:
