Self-hosting Immich with Docker, Traefik, and CrowdSec
Table of Contents ๐
Immich is currently the most powerful open-source alternative to Google Photos. It offers high-performance backup, AI-driven face recognition, and a polished mobile app. This guide focuses on a robust deployment using Docker Compose, integrating it into our existing Traefik v3 reverse proxy and securing it with the CrowdSec IPS.
By placing Immich behind Traefik, we benefit from automatic TLS certificates and a central entry point for our mobile devices, while CrowdSec protects our personal memories from brute-force and bot attacks.
Changelog
| Date | Change |
|---|---|
| 2026-01-15 | Initial Version: Immich v1.12x+, Traefik v3 integration, pgvector, and specific CrowdSec bypass notes for mobile sync. |
1. Prerequisites
This deployment assumes you have followed our foundational security stack guide. Immich is resource-intensive, especially during the initial scan of your library.
| โ ๏ธ HARD REQUIREMENT |
The following steps will not work correctly without the Traefik stack running as described in the prerequisite guide:
|
System Recommendations:
- RAM: Minimum 4GB (8GB+ recommended for AI/Machine Learning).
- Storage: A large dedicated disk or mount point for your photo library.
- Domain: A subdomain like
photos.your-domain.com.
2. Directory Structure
Immich requires several volumes for its database, machine learning cache, and the actual photo library.
# Create the main directory
sudo mkdir -p /opt/containers/immich
cd /opt/containers/immich
# Create directories for data persistence
sudo mkdir -p volumes/db # Postgres data
sudo mkdir -p volumes/library # Your actual photos/videos
sudo mkdir -p volumes/model-cache # AI models3. Configuration
Immich uses a .env file for core settings and a docker-compose.yml for service orchestration.
3.1. Generate Database Password
DB_PASSWORD=$(openssl rand -hex 32)
echo "Your Immich DB password: $DB_PASSWORD"3.2. Environment Variables (.env)
Create the .env file. Replace placeholders with your values.
sudo tee .env > /dev/null << EOF
# --- Database ---
DB_PASSWORD=$DB_PASSWORD
DB_USERNAME=immich
DB_DATABASE_NAME=immich
# --- System ---
TZ=Europe/Vienna
IMMICH_VERSION=release
# --- Library Location ---
# Ensure this path has sufficient space (ideally a dedicated disk)
UPLOAD_LOCATION=./volumes/library
# --- Domain ---
DOMAIN_NAME=photos.your-domain.com
EOF3.3. Docker Compose (docker-compose.yml)
sudo tee docker-compose.yml > /dev/null << 'EOF'
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
depends_on:
- redis
- database
restart: unless-stopped
networks:
- proxy
- immich-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.immich.rule=Host(`${DOMAIN_NAME}`)"
- "traefik.http.routers.immich.entrypoints=websecure"
- "traefik.http.routers.immich.tls.certresolver=tls_resolver"
# See Section 4.3 for opting out of CrowdSec if needed
- "traefik.http.routers.immich.middlewares=security-headers@file,crowdsec-bouncer@docker"
- "traefik.http.services.immich.loadbalancer.server.port=2283"
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- ./volumes/model-cache:/cache
env_file:
- .env
restart: unless-stopped
networks:
- immich-net
redis:
container_name: immich_redis
image: redis:6.2-alpine
restart: unless-stopped
networks:
- immich-net
database:
container_name: immich_postgres
image: tensorchord/pgvecto-rs:pg16-v0.2.0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
volumes:
- ./volumes/db:/var/lib/postgresql/data
restart: unless-stopped
networks:
- immich-net
networks:
proxy:
external: true
immich-net:
driver: bridge
EOF4. Hardware & Security Tuning
4.1. Hardware Acceleration (Optional)
Using an iGPU or GPU speeds up video transcoding and AI processing significantly.
| ๐ก TRANSCODING & ML |
To enable Intel QuickSync, add the following to both |
4.2. Mobile Apps & CrowdSec
Immich mobile apps (especially on iOS) perform many rapid requests during background synchronization.
| โ ๏ธ MOBILE SYNC & FALSE POSITIVES |
If you experience โConnection Lostโ or sync issues in the mobile app, check your CrowdSec decisions ( |
4.3. Running Immich without CrowdSec (Optional)
If you find that the CrowdSec middleware frequently interferes with your mobile backups, you can choose to bypass it for Immich specifically while keeping your other services protected.
To disable CrowdSec for Immich, update the labels in your docker-compose.yml by removing crowdsec-bouncer@docker:
# In the immich-server labels section:
- "traefik.http.routers.immich.middlewares=security-headers@file"For more details on why you might want to do this, see:
5. Maintenance & Backup
Updating Immich
cd /opt/containers/immich
sudo docker compose pull
sudo docker compose up -dBackup Strategy
Gezieltes Database Backup:
# Export only the 'immich' database for a cleaner dump
sudo docker compose exec -t database pg_dump -U immich immich > immich_db_backup_$(date +%F).sqlConclusion
You now have a secure, high-performance photo management system. By integrating Immich with Traefik and CrowdSec (or selectively bypassing it for sync reliability), you achieve a โGoogle Photosโ experience while maintaining full control over your private data.





