services:
  ## PhotoPrism (Development Environment for Nvidia)
  photoprism:
    build: .
    image: photoprism/photoprism:develop
    runtime: nvidia
    depends_on:
      - mariadb
      - dummy-webdav
      - dummy-oidc
    stop_grace_period: 15s
    privileged: true
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ## Expose HTTP and debug ports
    ports:
      - "2342:2342"   # Default HTTP port (host:container)
      - "2443:2443"   # Default TLS port (host:container)
      - "2343:2343"   # Acceptance Test HTTP port (host:container)
      - "40000:40000" # Go Debugger (host:container)
    shm_size: "2gb"
    ## Set links and labels for use with Traefik reverse proxy
    links:
      - "traefik:localssl.dev"
      - "traefik:app.localssl.dev"
      - "traefik:vision.localssl.dev"
      - "traefik:qdrant.localssl.dev"
      - "traefik:keycloak.localssl.dev"
      - "traefik:dummy-oidc.localssl.dev"
      - "traefik:dummy-webdav.localssl.dev"
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=photoprism"
      - "traefik.http.services.photoprism.loadbalancer.server.port=2342"
      - "traefik.http.services.photoprism.loadbalancer.server.scheme=http"
      - "traefik.http.routers.photoprism.entrypoints=websecure"
      - "traefik.http.routers.photoprism.rule=Host(`localssl.dev`) || HostRegexp(`^.+\\.localssl\\.dev`)"
      - "traefik.http.routers.photoprism.priority=2"
      - "traefik.http.routers.photoprism.tls.domains[0].main=localssl.dev"
      - "traefik.http.routers.photoprism.tls.domains[0].sans=*.localssl.dev"
      - "traefik.http.routers.photoprism.tls=true"
    ## Configure development environment
    environment:
      ## Run as a non-root user after initialization (supported: 0, 33, 50-99, 500-600, and 900-1200):
      PHOTOPRISM_UID: ${UID:-1000}                         # user id, should match your host user id
      PHOTOPRISM_GID: ${GID:-1000}                         # group id
      ## Access Management:
      PHOTOPRISM_ADMIN_USER: "admin"                       # admin login username
      PHOTOPRISM_ADMIN_PASSWORD: "photoprism"              # initial admin password (8-72 characters)
      PHOTOPRISM_AUTH_MODE: "password"                     # authentication mode (public, password)
      PHOTOPRISM_REGISTER_URI: "https://keycloak.localssl.dev/admin/"
      PHOTOPRISM_PASSWORD_RESET_URI: "https://keycloak.localssl.dev/realms/master/login-actions/reset-credentials"
      PHOTOPRISM_USAGE_INFO: "true"
      PHOTOPRISM_FILES_QUOTA: "100"
      ## Customization:
      PHOTOPRISM_DEFAULT_LOCALE: "en"                      # default user interface language, e.g. "en" or "de"
      PHOTOPRISM_PLACES_LOCALE: "local"                    # location details language, e.g. "local", "en", or
      ## OpenID Connect (pre-configured for local tests):
      ## see https://keycloak.localssl.dev/realms/master/.well-known/openid-configuration
      PHOTOPRISM_OIDC_URI: "https://keycloak.localssl.dev/realms/master"
      PHOTOPRISM_OIDC_CLIENT: "photoprism-develop"
      PHOTOPRISM_OIDC_SECRET: "9d8351a0-ca01-4556-9c37-85eb634869b9"
      PHOTOPRISM_OIDC_PROVIDER: "Keycloak"
      PHOTOPRISM_OIDC_REGISTER: "true"
      PHOTOPRISM_OIDC_WEBDAV: "true"
      PHOTOPRISM_DISABLE_OIDC: "false"
      ## LDAP Authentication (pre-configured for local tests):
      PHOTOPRISM_LDAP_URI: "ldap://dummy-ldap:389"
      PHOTOPRISM_LDAP_INSECURE: "true"
      PHOTOPRISM_LDAP_SYNC: "true"
      PHOTOPRISM_LDAP_BIND: "simple"
      PHOTOPRISM_LDAP_BIND_DN: "cn"
      PHOTOPRISM_LDAP_BASE_DN: "dc=localssl,dc=dev"
      PHOTOPRISM_LDAP_ROLE: ""
      PHOTOPRISM_LDAP_ROLE_DN: "ou=photoprism-*,ou=groups,dc=localssl,dc=dev"
      PHOTOPRISM_LDAP_WEBDAV_DN: "ou=photoprism-webdav,ou=groups,dc=localssl,dc=dev"
      ## HTTPS/TLS Options:
      ## see https://docs.photoprism.app/getting-started/using-https/
      PHOTOPRISM_DISABLE_TLS: "true"
      PHOTOPRISM_DEFAULT_TLS: "true"
      ## Site Information:
      PHOTOPRISM_SITE_URL: "https://app.localssl.dev/"    # server URL in the format "http(s)://domain.name(:port)/(path)"
      PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
      PHOTOPRISM_SITE_DESCRIPTION: "Tags and finds pictures without getting in your way!"
      PHOTOPRISM_SITE_AUTHOR: "@photoprism_app"
      PHOTOPRISM_DEBUG: "true"
      PHOTOPRISM_READONLY: "false"
      PHOTOPRISM_EXPERIMENTAL: "true"
      PHOTOPRISM_HTTP_MODE: "debug"
      PHOTOPRISM_HTTP_HOST: "0.0.0.0"
      PHOTOPRISM_HTTP_PORT: 2342
      PHOTOPRISM_HTTP_COMPRESSION: "gzip"                  # improves transfer speed and bandwidth utilization (none or gzip)
      PHOTOPRISM_DATABASE_DRIVER: "mysql"
      PHOTOPRISM_DATABASE_SERVER: "mariadb:4001"
      PHOTOPRISM_DATABASE_NAME: "photoprism"
      PHOTOPRISM_DATABASE_USER: "root"
      PHOTOPRISM_DATABASE_PASSWORD: "photoprism"
      PHOTOPRISM_TEST_DRIVER: "sqlite"
      # PHOTOPRISM_TEST_DSN_MYSQL8: "root:photoprism@tcp(mysql:4001)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true&timeout=15s"
      PHOTOPRISM_ASSETS_PATH: "/go/src/github.com/photoprism/photoprism/assets"
      PHOTOPRISM_STORAGE_PATH: "/go/src/github.com/photoprism/photoprism/storage"
      PHOTOPRISM_ORIGINALS_PATH: "/go/src/github.com/photoprism/photoprism/storage/originals"
      PHOTOPRISM_ORIGINALS_LIMIT: 128000             # sets originals file size limit to 128 GB
      PHOTOPRISM_IMPORT_PATH: "/go/src/github.com/photoprism/photoprism/storage/import"
      PHOTOPRISM_DISABLE_CHOWN: "false"              # disables updating storage permissions via chmod and chown on startup
      PHOTOPRISM_DISABLE_BACKUPS: "false"            # disables backing up albums and photo metadata to YAML files
      PHOTOPRISM_DISABLE_WEBDAV: "false"             # disables built-in WebDAV server
      PHOTOPRISM_DISABLE_SETTINGS: "false"           # disables settings UI and API
      PHOTOPRISM_DISABLE_PLACES: "false"             # disables reverse geocoding and maps
      PHOTOPRISM_DISABLE_EXIFTOOL: "false"           # disables creating JSON metadata sidecar files with ExifTool
      PHOTOPRISM_DISABLE_TENSORFLOW: "false"         # disables all features depending on TensorFlow
      PHOTOPRISM_DISABLE_RAW: "false"                # disables indexing and conversion of RAW images
      PHOTOPRISM_RAW_PRESETS: "false"                # enables applying user presets when converting RAW images (reduces performance)
      PHOTOPRISM_DETECT_NSFW: "false"                # automatically flags photos as private that MAY be offensive (requires TensorFlow)
      PHOTOPRISM_UPLOAD_NSFW: "false"                # allows uploads that MAY be offensive (no effect without TensorFlow)
      PHOTOPRISM_UPLOAD_ALLOW: ""                    # restricts uploads to these file types (comma-separated list of EXTENSIONS; leave blank to allow all)
      PHOTOPRISM_UPLOAD_ARCHIVES: "true"             # allows upload of zip archives (will be extracted before import)
      PHOTOPRISM_THUMB_LIBRARY: "auto"               # image processing library to be used for generating thumbnails (auto, imaging, vips)
      PHOTOPRISM_THUMB_FILTER: "auto"                # downscaling filter (imaging best to worst: blackman, lanczos, cubic, linear, nearest)
      PHOTOPRISM_THUMB_UNCACHED: "true"              # enables on-demand thumbnail rendering (high memory and cpu usage)
      ## Run/install on first startup (options: update tensorflow https intel gpu davfs yt-dlp):
      PHOTOPRISM_INIT: "https tensorflow-gpu"
      ## Computer Vision API (https://docs.photoprism.app/getting-started/config-options/#computer-vision):
      PHOTOPRISM_VISION_API: "true"                  # server: enables service API endpoints under /api/v1/vision (requires access token)
      PHOTOPRISM_VISION_URI: ""                      # client: service URI, e.g. http://hostname/api/v1/vision (leave blank to disable)
      PHOTOPRISM_VISION_KEY: ""                      # client: service access token (for authentication)
      ## NVIDIA GPU Hardware Acceleration (see https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html):
      NVIDIA_VISIBLE_DEVICES: "all"
      NVIDIA_DRIVER_CAPABILITIES: "all"
      PHOTOPRISM_FFMPEG_ENCODER: "nvidia"            # H.264/AVC encoder (software, intel, nvidia, apple, raspberry, or vaapi)
      PHOTOPRISM_FFMPEG_SIZE: "1920"                 # video size limit in pixels (720-7680) (default: 3840)
      PHOTOPRISM_FFMPEG_BITRATE: "64"                # video bitrate limit in Mbps (default: 60)
      ## External dependencies and tools:
      TF_CPP_MIN_LOG_LEVEL: 1
      GOCACHE: "/go/src/github.com/photoprism/photoprism/.local/gocache"
      CODEX_HOME: "/go/src/github.com/photoprism/photoprism/.local/codex"
    ## Shared devices for video hardware transcoding (optional):
    # devices:
    #  - "/dev/dri:/dev/dri"                         # Required Intel QSV or VAAPI hardware transcoding
    #  - "/dev/video11:/dev/video11"                 # Video4Linux Video Encode Device (h264_v4l2m2m)
    working_dir: "/go/src/github.com/photoprism/photoprism"
    volumes:
      - ".:/go/src/github.com/photoprism/photoprism"
      - "./storage:/photoprism"
      - "go-mod:/go/pkg/mod"
    ## NVIDIA GPU Hardware Acceleration (see https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html):
    deploy:
      resources:
        reservations:
          devices:
            - driver: "nvidia"
              capabilities: [gpu]
              count: "all"

  ## Ollama Large-Language Model Runner
  ## run "ollama pull [name]:[version]" to download a vision model
  ## listed at <https://ollama.com/search?c=vision>, for example:
  ## docker compose exec ollama ollama pull gemma3:latest
  ollama:
    image: ollama/ollama:latest
    stop_grace_period: 15s
    ## Only starts this service if the "all", "ollama", or "vision" profile is specified::
    ## docker compose --profile ollama up -d
    profiles: ["all", "ollama", "vision"]
    ## Insecurely exposes the Ollama service on port 11434
    ## without authentication (for private networks only):
    # ports:
    #  - "11434:11434"
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=photoprism"
      - "traefik.http.services.ollama.loadbalancer.server.port=11434"
      - "traefik.http.routers.ollama.rule=Host(`ollama.localssl.dev`)"
      - "traefik.http.routers.ollama.entrypoints=websecure"
      - "traefik.http.routers.ollama.tls=true"
    environment:
      ## Ollama Configuration Options:
      OLLAMA_HOST: "0.0.0.0:11434"
      OLLAMA_MODELS: "/root/.ollama"   # model storage path (see volumes section below)
      OLLAMA_MAX_QUEUE: "100"          # maximum number of queued requests
      OLLAMA_NUM_PARALLEL: "1"         # maximum number of parallel requests
      OLLAMA_MAX_LOADED_MODELS: "1"    # maximum number of loaded models per GPU
      OLLAMA_LOAD_TIMEOUT: "5m"        # maximum time for loading models (default "5m")
      OLLAMA_KEEP_ALIVE: "5m"          # duration that models stay loaded in memory (default "5m")
      OLLAMA_CONTEXT_LENGTH: "4096"    # maximum input context length
      OLLAMA_MULTIUSER_CACHE: "false"  # optimize prompt caching for multi-user scenarios
      OLLAMA_NOPRUNE: "false"          # disables pruning of model blobs at startup
      OLLAMA_NOHISTORY: "true"         # disables readline history
      OLLAMA_FLASH_ATTENTION: "false"  # enables the experimental flash attention feature
      OLLAMA_KV_CACHE_TYPE: "f16"      # cache quantization (f16, q8_0, or q4_0)
      OLLAMA_SCHED_SPREAD: "false"     # allows scheduling models across all GPUs.
      OLLAMA_NEW_ENGINE: "true"        # enables the new Ollama engine
      # OLLAMA_DEBUG: "true"             # shows additional debug information
      # OLLAMA_INTEL_GPU: "true"         # enables experimental Intel GPU detection
      ## NVIDIA GPU Hardware Acceleration (see https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html):
      NVIDIA_VISIBLE_DEVICES: "all"
      NVIDIA_DRIVER_CAPABILITIES: "compute,utility"
    volumes:
      - "./storage/services/ollama:/root/.ollama"
    ## NVIDIA GPU Hardware Acceleration (see https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html):
    deploy:
      resources:
        reservations:
          devices:
            - driver: "nvidia"
              capabilities: [ gpu ]
              count: "all"

  mariadb:
    extends:
      file: ./compose.yaml
      service: mariadb
  qdrant:
    extends:
      file: ./compose.yaml
      service: qdrant
  open-webui:
    extends:
      file: ./compose.yaml
      service: open-webui
  photoprism-vision:
    extends:
      file: ./compose.yaml
      service: photoprism-vision
  traefik:
    extends:
      file: ./compose.yaml
      service: traefik
  dummy-webdav:
    extends:
      file: ./compose.yaml
      service: dummy-webdav
  dummy-oidc:
    extends:
      file: ./compose.yaml
      service: dummy-oidc
  dummy-ldap:
    extends:
      file: ./compose.yaml
      service: dummy-ldap
  keycloak:
    extends:
      file: ./compose.yaml
      service: keycloak
  prometheus:
    extends:
      file: ./compose.yaml
      service: prometheus

## Create named volume for Go module cache
volumes:
  go-mod:
    driver: local
  mariadb:
    driver: local

## Create shared "photoprism" network for connecting with services in other compose.yaml files
networks:
  default:
    name: photoprism
    driver: bridge
