After an Immich upgrade, Svelte chunk filenames rotate but the cached PWA shell still imports old ones — dynamic imports 500 or 404. Our auto-update mechanism only caught changes to our injected script, not upstream changes, so the stuck PWA never self-healed. Now /api/custom/inject-version returns a hash of (custom script || Immich chunk manifest fingerprint), so any upgrade bumps the version, the PWA detects it on next poll, unregisters the service worker, clears caches, and reloads with fresh chunks. We extract only the /_app/immutable/... references from the HTML to avoid hashing server-rendered per-user state (CSRF tokens etc) that would cause spurious version churn. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| backlog | ||
| heatmap-app | ||
| scripts | ||
| search-app | ||
| .env.example | ||
| .gitignore | ||
| README.md | ||
| docker-compose.yml | ||
README.md
Immich Docker Setup
Self-hosted photo and video management solution with Docker Compose.
Overview
This repository contains a production-ready Docker Compose setup for Immich, a high-performance self-hosted photo and video management solution.
Features
- 🐳 Easy Docker Compose deployment
- 🔒 Secure configuration with environment variables
- 📦 Automated daily database backups
- 🔄 Health checks for all services
- 🚀 Reverse proxy ready (Caddy/Nginx)
- 📱 Mobile app support (iOS/Android)
Architecture
This setup includes the following services:
- immich-server: Main application server
- immich-machine-learning: AI-powered photo recognition and classification
- postgres: Database with vector extensions for AI features
- redis/valkey: Caching layer
Quick Start
Prerequisites
- Docker 20.10+ and Docker Compose v2.0+
- At least 4GB RAM
- 10GB+ storage (plus space for your media)
Installation
-
Clone this repository:
git clone https://gitea.jeffemmett.com/jeff/immich-docker.git cd immich-docker -
Create your environment file:
cp .env.example .env -
Generate a secure database password:
# On Linux/macOS openssl rand -base64 32 | tr -d "=+/" | cut -c1-32 # Or use this one-liner to update .env directly sed -i "s/CHANGE_ME_TO_RANDOM_PASSWORD/$(openssl rand -base64 32 | tr -d '=+\/' | cut -c1-32)/" .env -
(Optional) Customize settings in
.env:UPLOAD_LOCATION: Where your photos/videos are storedDB_DATA_LOCATION: Database storage locationTZ: Your timezoneIMMICH_VERSION: Pin to specific version if desired
-
Start the services:
docker compose up -d -
Access Immich at
http://localhost:2283
Configuration
Environment Variables
All configuration is done through the .env file. See .env.example for all available options.
Key variables:
UPLOAD_LOCATION: Media storage path (default:./library)DB_DATA_LOCATION: Database path (default:./postgres)DB_PASSWORD: PostgreSQL password (must change before first run)IMMICH_VERSION: Version tag (default:v2)TZ: Timezone (default:Etc/UTC)
Reverse Proxy Setup
With Caddy
Create a Caddyfile:
photos.yourdomain.com {
reverse_proxy localhost:2283
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "no-referrer-when-downgrade"
}
}
With Nginx
server {
listen 443 ssl http2;
server_name photos.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:2283;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Backup & Restore
Automated Backups
Daily backups are configured via cron (if using the provided scripts):
# Run backup manually
./scripts/backup-database.sh
# Set up automated daily backups (2 AM)
crontab -e
# Add: 0 2 * * * /path/to/immich-docker/scripts/backup-database.sh >> /var/log/immich-backup.log 2>&1
Manual Backup
# Backup database
docker compose exec -T database pg_dump -U postgres immich | gzip > backup-$(date +%Y%m%d_%H%M%S).sql.gz
# Backup uploaded files
tar -czf library-backup-$(date +%Y%m%d).tar.gz library/
Restore from Backup
# Restore database
gunzip -c backup.sql.gz | docker compose exec -T database psql -U postgres immich
# Restore files
tar -xzf library-backup.tar.gz
Maintenance
Update Immich
# Pull latest images
docker compose pull
# Restart with new images
docker compose up -d
# Remove old images
docker image prune -f
View Logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f immich-server
# Last 100 lines
docker compose logs --tail=100
Health Check
# Check container status
docker compose ps
# Run health check script
./scripts/health-check.sh
Mobile Apps
Download the Immich mobile app to automatically backup your photos:
- iOS: App Store - Immich
- Android: Play Store - Immich
Configure the app with:
- Server URL:
https://photos.yourdomain.com(or your server address) - Email/Password: Created during first-time setup
Troubleshooting
Cannot connect to Immich
-
Check if containers are running:
docker compose ps -
Check logs for errors:
docker compose logs immich-server -
Verify port is accessible:
curl http://localhost:2283
Database connection errors
-
Check database is healthy:
docker compose exec database pg_isready -U postgres -
Verify DB_PASSWORD matches in
.env
Out of disk space
-
Check Docker disk usage:
docker system df -
Clean up old images and containers:
docker system prune -a
Hardware Acceleration
For better performance with video transcoding and ML inference, enable hardware acceleration:
- Uncomment the appropriate
extendssection indocker-compose.yml - Download the appropriate hwaccel file from Immich docs
- Restart services
See Immich Hardware Acceleration Docs for details.
Security Considerations
- ✅ Change
DB_PASSWORDto a strong random password - ✅ Use HTTPS with a reverse proxy
- ✅ Keep Immich updated regularly
- ✅ Restrict port 2283 to localhost if using a reverse proxy
- ✅ Enable firewall on your server
- ✅ Regular backups of database and media files
Documentation
License
This setup configuration is MIT licensed. Immich itself is AGPL-3.0 licensed.