# Immich - Self-hosted Photo & Video Management # Domain: photos.${DOMAIN} # Database: PostgreSQL (with VectorChord) + Redis # RAM: ~4GB minimum | Pi-compatible: No (ML too heavy) # # Environment variables (set in Portainer): # DOMAIN - Your domain (e.g., demo-felhom.eu) # HDD_PATH - HDD mount path (e.g., /mnt/hdd_1) # DB_PASSWORD - PostgreSQL password # # Storage layout: # User photos/videos → ${HDD_PATH}/storage/immich (HDD, host path) # PostgreSQL data → immich_postgres_data (named volume, NVMe) # ML model cache → immich_ml_cache (named volume, NVMe) # Redis data → immich_redis_data (named volume, NVMe) # # First-time setup: # Create admin account on first visit. services: immich-server: image: ghcr.io/immich-app/immich-server:v2.5.5 container_name: immich-server restart: unless-stopped depends_on: immich-postgres: condition: service_healthy immich-redis: condition: service_healthy environment: - DB_PASSWORD=${DB_PASSWORD} - DB_HOSTNAME=immich-postgres - DB_USERNAME=immich - DB_DATABASE_NAME=immich - REDIS_HOSTNAME=immich-redis - IMMICH_MACHINE_LEARNING_URL=http://immich-machine-learning:3003 - TZ=Europe/Budapest volumes: - ${HDD_PATH}/storage/immich:/usr/src/app/upload networks: - traefik-public - immich-internal healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:2283/api/server/ping"] interval: 30s timeout: 10s retries: 3 start_period: 60s labels: - "traefik.enable=true" - "traefik.http.routers.immich.rule=Host(`photos.${DOMAIN}`)" - "traefik.http.routers.immich.entrypoints=websecure" - "traefik.http.routers.immich.tls=true" - "traefik.http.routers.immich.tls.certresolver=letsencrypt" - "traefik.http.services.immich.loadbalancer.server.port=2283" immich-machine-learning: image: ghcr.io/immich-app/immich-machine-learning:v2.5.5 container_name: immich-machine-learning restart: unless-stopped environment: - TZ=Europe/Budapest - TRANSFORMERS_CACHE=/cache volumes: - immich_ml_cache:/cache networks: - immich-internal healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3003/ping')"] interval: 30s timeout: 10s retries: 3 start_period: 120s immich-postgres: image: ghcr.io/immich-app/postgres:16-vectorchord0.3.0 container_name: immich-postgres restart: unless-stopped environment: - POSTGRES_USER=immich - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=immich - POSTGRES_INITDB_ARGS=--data-checksums volumes: - immich_postgres_data:/var/lib/postgresql/data networks: - immich-internal healthcheck: test: ["CMD-SHELL", "pg_isready -U immich -d immich"] interval: 10s timeout: 5s retries: 5 start_period: 30s immich-redis: image: redis:7-alpine container_name: immich-redis restart: unless-stopped command: redis-server --appendonly yes volumes: - immich_redis_data:/data networks: - immich-internal healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 3 volumes: immich_ml_cache: immich_postgres_data: immich_redis_data: networks: traefik-public: external: true immich-internal: