services: # Jellyfin - Media streaming server jellyfin: image: ${MEDIA_JELLYFIN_IMAGE:-jellyfin/jellyfin:latest} container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_jellyfin restart: unless-stopped volumes: - jellyfin_config:/config - jellyfin_cache:/cache - /mnt/hidrive/users/valknar/Pictures:/media/pictures:ro - /mnt/hidrive/users/valknar/Videos:/media/videos:ro - /mnt/hidrive/users/valknar/Music:/media/music:ro environment: TZ: ${TIMEZONE:-Europe/Berlin} networks: - compose_network labels: - 'traefik.enable=${MEDIA_TRAEFIK_ENABLED}' # HTTP to HTTPS redirect - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-redirect-web-secure.redirectscheme.scheme=https' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-redirect-web-secure' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web.rule=Host(`${MEDIA_JELLYFIN_TRAEFIK_HOST}`)' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web.entrypoints=web' # HTTPS router - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure.rule=Host(`${MEDIA_JELLYFIN_TRAEFIK_HOST}`)' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure.tls.certresolver=resolver' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure.entrypoints=web-secure' - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure-compress.compress=true' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure-compress,security-headers@file' # Service - 'traefik.http.services.${MEDIA_COMPOSE_PROJECT_NAME}-jellyfin-web-secure.loadbalancer.server.port=8096' - 'traefik.docker.network=${NETWORK_NAME}' # Watchtower - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' # Pinchflat - YouTube download manager pinchflat: image: ${MEDIA_PINCHFLAT_IMAGE:-ghcr.io/kieraneglin/pinchflat:latest} container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_pinchflat restart: unless-stopped volumes: - pinchflat_config:/config - /mnt/hidrive/users/valknar/Downloads/pinchflat:/downloads environment: TZ: ${TIMEZONE:-Europe/Berlin} JOURNAL_MODE: delete networks: - compose_network labels: - 'traefik.enable=${MEDIA_TRAEFIK_ENABLED}' # HTTP to HTTPS redirect - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-redirect-web-secure.redirectscheme.scheme=https' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-redirect-web-secure' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web.rule=Host(`${MEDIA_PINCHFLAT_TRAEFIK_HOST}`)' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web.entrypoints=web' # HTTPS router with Authelia SSO protection - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure.rule=Host(`${MEDIA_PINCHFLAT_TRAEFIK_HOST}`)' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure.tls.certresolver=resolver' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure.entrypoints=web-secure' - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure-compress.compress=true' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure-compress,net-authelia,security-headers@file' # Service - 'traefik.http.services.${MEDIA_COMPOSE_PROJECT_NAME}-pinchflat-web-secure.loadbalancer.server.port=8945' - 'traefik.docker.network=${NETWORK_NAME}' # Watchtower - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' # Immich PostgreSQL - Dedicated database with vector extensions immich_postgres: image: ${MEDIA_IMMICH_POSTGRES_IMAGE:-ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0} container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_postgres restart: unless-stopped environment: TZ: ${TIMEZONE:-Europe/Berlin} POSTGRES_USER: ${MEDIA_IMMICH_DB_USER:-immich} POSTGRES_PASSWORD: ${MEDIA_IMMICH_DB_PASSWORD} POSTGRES_DB: ${MEDIA_IMMICH_DB_NAME:-immich} POSTGRES_INITDB_ARGS: --data-checksums volumes: - immich_postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${MEDIA_IMMICH_DB_USER:-immich} -d ${MEDIA_IMMICH_DB_NAME:-immich}"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - compose_network # Immich Server - Main application immich_server: image: ${MEDIA_IMMICH_SERVER_IMAGE:-ghcr.io/immich-app/immich-server:release} container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_server restart: unless-stopped environment: TZ: ${TIMEZONE:-Europe/Berlin} DB_HOSTNAME: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_postgres DB_PORT: 5432 DB_USERNAME: ${MEDIA_IMMICH_DB_USER:-immich} DB_PASSWORD: ${MEDIA_IMMICH_DB_PASSWORD} DB_DATABASE_NAME: ${MEDIA_IMMICH_DB_NAME:-immich} REDIS_HOSTNAME: ${CORE_COMPOSE_PROJECT_NAME}_redis REDIS_PORT: ${CORE_REDIS_PORT:-6379} IMMICH_MACHINE_LEARNING_URL: http://${MEDIA_COMPOSE_PROJECT_NAME}_immich_ml:3003 volumes: - immich_upload:/usr/src/app/upload - /etc/localtime:/etc/localtime:ro depends_on: immich_postgres: condition: service_healthy networks: - compose_network labels: - 'traefik.enable=${MEDIA_TRAEFIK_ENABLED}' # HTTP to HTTPS redirect - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-immich-redirect-web-secure.redirectscheme.scheme=https' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-immich-redirect-web-secure' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web.rule=Host(`${MEDIA_IMMICH_TRAEFIK_HOST}`)' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web.entrypoints=web' # HTTPS router - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure.rule=Host(`${MEDIA_IMMICH_TRAEFIK_HOST}`)' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure.tls.certresolver=resolver' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure.entrypoints=web-secure' - 'traefik.http.middlewares.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure-compress.compress=true' - 'traefik.http.routers.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure.middlewares=${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure-compress,security-headers@file' # Service - 'traefik.http.services.${MEDIA_COMPOSE_PROJECT_NAME}-immich-web-secure.loadbalancer.server.port=2283' - 'traefik.docker.network=${NETWORK_NAME}' # Watchtower - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' # Immich Machine Learning - AI inference for faces, search, etc. immich_ml: image: ${MEDIA_IMMICH_ML_IMAGE:-ghcr.io/immich-app/immich-machine-learning:release} container_name: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_ml restart: unless-stopped environment: TZ: ${TIMEZONE:-Europe/Berlin} volumes: - immich_model_cache:/cache networks: - compose_network labels: # Watchtower - 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}' volumes: jellyfin_config: name: ${MEDIA_COMPOSE_PROJECT_NAME}_jellyfin_config jellyfin_cache: name: ${MEDIA_COMPOSE_PROJECT_NAME}_jellyfin_cache pinchflat_config: name: ${MEDIA_COMPOSE_PROJECT_NAME}_pinchflat_config immich_postgres_data: name: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_postgres_data immich_upload: name: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_upload immich_model_cache: name: ${MEDIA_COMPOSE_PROJECT_NAME}_immich_model_cache networks: compose_network: name: ${NETWORK_NAME} external: true