Immich offers a refreshing alternative to services like Google Photos by prioritizing privacy and control. As a self-hosted solution, it keeps your photos and videos entirely on your own hardware, avoiding third-party data mining or subscription fees. You get full ownership of your media, support for RAW files, and customizable organization tools—like auto-sorting photos into folders based on dates, cameras, or custom rules. While setup requires some technical work and , it’s a trade-off for avoiding vendor lock-in and ads. Its local AI features (face/object recognition) may not match Google’s polish, but for users valuing transparency and flexibility, Immich is a compelling, ethical choice.
Prerequisites
- A server running Docker (Ubuntu/Debian recommended)
- Portainer installed and accessible via web UI
- Domain name (optional, for remote access)
- Minimum 2GB RAM (4GB+ recommended if using ML features)
Step 1: Prepare Your Environment
Create directories for Immich data:
mkdir -p /docker/immich/{data,uploads,photos,model-cache} chmod -R 775 /docker/immich
(Adjust paths according to your preferences)
Note your server’s IP address or domain name
Step 2: Create Immich Stack in Portainer
- Log into Portainer UI
- Go to Stacks > Add Stack
- Name:
immich
- Build Method: Web Editor
- Paste this compose file (adjust highlighted values):
version: "3.8"
services:
immich-server:
image: ghcr.io/immich-app/immich-server:release
container_name: immich_server
command: ["start.sh", "immich"]
volumes:
- /docker/immich/uploads:/usr/src/app/upload
- /docker/immich/photos:/usr/src/app/photos
environment:
- NODE_ENV=production
- DB_HOSTNAME=immich_postgres
- DB_USERNAME=postgres
- DB_PASSWORD=postgres
- DB_DATABASE_NAME=immich
- REDIS_HOSTNAME=immich_redis
- JWT_SECRET=your_strong_secret_here
- ENABLE_MAPBOX=false
depends_on:
- redis
- database
restart: always
networks:
- immich
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release
container_name: immich_machine_learning
volumes:
- /docker/immich/model-cache:/cache
environment:
- MODEL_CACHE_FOLDER=/cache
restart: always
networks:
- immich
redis:
image: redis:6.2-alpine
container_name: immich_redis
restart: always
networks:
- immich
database:
image: postgres:14-alpine
container_name: immich_postgres
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: immich
volumes:
- /docker/immich/data:/var/lib/postgresql/data
restart: always
networks:
- immich
networks:
immich:
Step 3: Configuration Adjustments
Mandatory Changes:
- Replace
your_strong_secret_here
with a random string (useopenssl rand -base64 48
) - Verify all volume paths match your created directories
- Replace
Optional Changes:
- To enable Mapbox (for map view):
- Set
ENABLE_MAPBOX=true
- Add
- MAPBOX_ACCESS_KEY=your_mapbox_key
- Set
- To disable ML container: Remove the entire
immich-machine-learning
section - Add GPU support: Add
deploy.resources.reservations.devices
section under ML service
- To enable Mapbox (for map view):
Step 4: Deploy the Stack
- Click Deploy the stack
- Wait 2-5 minutes for all containers to initialize
- Check logs in Portainer if any containers fail to start
Step 5: Access Immich
- Open
http://your-server-ip:2283
in browser - Create admin account (first user becomes admin)
- Configure settings:
- Library > Add library path
/usr/src/app/photos
- Machine Learning > Enable facial recognition (if using ML container)
- Storage Template > Configure backup location
- Library > Add library path
Step 6: Mobile App Setup
- Install Immich from App Store or Play Store
- Connect to your server:
- Server URL:
http://your-server-ip:2283
- Use admin credentials
- Server URL:
- Enable auto-backup in app settings
Post-Installation Tasks
Reverse Proxy Setup (Recommended):
- Configure Nginx Proxy Manager or Traefik
- Example NPM config:
- Domain:
photos.yourdomain.com
- Forward to
http://immich-server:2283
- Domain:
Backup Strategy:
- Regularly back up
/docker/immich/data
(PostgreSQL database) - Consider using Portainer’s backup feature
- Regularly back up
Troubleshooting
Common Issues:
- Port Conflicts: Ensure ports 2283 (web) and 5432 (PostgreSQL) are available
- Permission Errors: Verify volume permissions with
ls -l /docker/immich
- ML Container Failing: Try disabling GPU support or allocate more RAM
Useful Commands:
# Check container logs docker logs immich_server # Reset admin password docker exec immich_server npm run reset-admin-password
Maintenance
Updates:
- Re-deploy stack in Portainer with updated image tags
- Follow Immich releases
Storage Management:
- Monitor
/docker/immich/uploads
growth - Set retention policies in Immich web UI
- Monitor
This setup provides a fully functional Immich instance with optional AI features. The ML container will automatically analyze photos for faces/objects in the background after upload.
(Due to technical issues, the search service is temporarily unavailable.)
Storage Templates: Automate Your Media Organization Like a Pro
Storage Templates are one of Immich’s most powerful (and underrated) features. They let you define custom folder structures and naming rules for your uploaded media, transforming chaotic file dumps into a beautifully organized library. Here’s why they’re game-changing and how to configure them:
Why Storage Templates Are Awesome
Automated Sorting:
- Automatically sort photos/videos into folders based on metadata like date, time, camera model, or custom tags.
- Example: Group all iPhone photos by year/month or separate DSLR shots by camera model.
Flexibility:
- Use variables like
{{DATE}}
,{{TIME}}
,{{CAMERA}}
, or{{FILENAME}}
to create dynamic paths. - Example template:Generates:
/Photos/{{DATE:YYYY}}/{{DATE:MMMM}}-{{DATE:DD}}/{{CAMERA}}_{{DATE:HHmmss}}
/Photos/2024/July-15/Nikon-Z6_143045.jpg
- Use variables like
Consistency:
- Eliminate manual folder creation—Immich handles it every time you upload.
Future-Proof Backups:
- Structured folders make it easier to sync with cloud storage (e.g., Backblaze, S3) or external drives.
Multi-User Support:
- Assign unique templates for different users (e.g.,
/Family/Jane/{{DATE}}
vs./Family/John/{{DATE}}
).
- Assign unique templates for different users (e.g.,
How to Set Up Storage Templates
Step 1: Access Storage Templates
- Log into your Immich web UI.
- Go to Settings (gear icon) > Storage Template.
Step 2: Build Your Template
Use variables in the Template field. Supported variables include:
{{DATE}} # 2024-07-15 {{DATE:YYYY}} # 2024 {{DATE:MMMM}} # July {{TIME}} # 14:30:45 {{CAMERA}} # Nikon Z6 {{FILENAME}} # IMG_1234.jpg {{USERNAME}} # jane_doe
Example Templates:
- By Year/Month:
/Photos/{{DATE:YYYY}}/{{DATE:MMMM}}
- By Camera + Date:
/Photos/{{CAMERA}}/{{DATE:YYYY}}-{{DATE:MM}}-{{DATE:DD}}
- For Events:
/Events/{{ALBUM_NAME}}/{{DATE:YYYY}}
- By Year/Month:
Step 3: Apply the Template
For New Uploads:
- Enable Apply template to new uploads to auto-organize future media.
For Existing Libraries:
- Go to Library > Select your library > Re-run Storage Template.
- Immich will reorganize files according to the new rules.
Step 4: Test and Refine
- Upload a test photo to verify the folder structure.
- Tweak the template if needed (e.g., add
{{TIME}}
to avoid filename conflicts).
Pro Tips
- Backup Compatibility: Pair with tools like
rclone
orrsync
to mirror your structured folders to cloud storage. - Reverse Proxy: Use a domain (e.g.,
photos.yourdomain.com
) for remote access to your organized library. - Avoid Overcomplicating: Start simple (e.g.,
/Photos/{{DATE:YYYY}}
) and add complexity later.
Real-World Use Cases
- Photographers: Sort raw files by camera model and shoot date:
/RAW/{{CAMERA}}/{{DATE:YYYY-MM-DD}}
- Families: Separate media by user and year:
/Family/{{USERNAME}}/{{DATE:YYYY}}
- Travelers: Group by location (if GPS metadata exists):
/Travel/{{DATE:YYYY}}/{{COUNTRY}}
By leveraging Storage Templates, you’re not just storing photos—you’re building an intuitive, searchable media archive that scales effortlessly. No more “2024-07-15-IMG_1234.jpg” chaos! 🎯