Immich in Docker Swarm
Immich is a promising self-hosted alternative to Google Photos. Its UI and features are clearly heavily inspired by Google Photos, and like Photoprism, Immich uses tensorflow-based machine learning to auto-tag your photos!
Pre-production warning
The developer makes it abundantly clear that Immich is under heavy development (although it's covered by "wife-insurance"1), features and APIs may change, and all your photos may be lost, or (worse) auto-shared with your mother-in-law! Take due care
See my detailed review of Immich, as a Google Photos replacement, here
Immich requirements
Ingredients
Already deployed:
- Docker swarm cluster with persistent shared storage
- Traefik configured per design
New:
- DNS entry for your Immich instance, pointed to your keepalived IP
Setup data locations
First, we create a directory to hold the immich docker-compose configuration:
mkdir /var/data/config/immich
Then we setup directories to hold all the various data:
mkdir -p /var/data/immich/database-dump
mkdir -p /var/data/immich/upload
mkdir -p /var/data/runtime/immich/database
Setup Immich environment
Create /var/data/config/immich/immich.env
something like the example below..
###################################################################################
# Database
###################################################################################
# These are for the Immich components
DB_HOSTNAME=db
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE_NAME=immich
# These are specific to how the postgres image likes to receive its ENV vars
POSTGRES_PASSWORD=postgres
#POSTGRES_USER=postgres
POSTGRES_DB=immich
###################################################################################
# Redis
###################################################################################
REDIS_HOSTNAME=redis
# Optional Redis settings:
# REDIS_PORT=6379
# REDIS_DBINDEX=0
# REDIS_PASSWORD=
# REDIS_SOCKET=
###################################################################################
# JWT SECRET
###################################################################################
JWT_SECRET=randomstringthatissolongandpowerfulthatnoonecanguess # (1)!
###################################################################################
# MAPBOX
####################################################################################
# ENABLE_MAPBOX is either true of false -> if true, you have to provide MAPBOX_KEY
ENABLE_MAPBOX=false
MAPBOX_KEY=
###################################################################################
# WEB - Required
###################################################################################
# This is the URL of your vm/server where you host Immich, so that the web frontend
# know where can it make the request to.
# For example: If your server IP address is 10.1.11.50, the environment variable will
# be VITE_SERVER_ENDPOINT=http://10.1.11.50:2283/api
# !CAUTION! THERE IS NO FORWARD SLASH AT THE END
VITE_SERVER_ENDPOINT=https://immich.example.com/api
####################################################################################
# WEB - Optional
####################################################################################
# Custom message on the login page, should be written in HTML form.
# For example VITE_LOGIN_PAGE_MESSAGE="This is a demo instance of Immich.<br><br>Email: <i>demo@demo.de</i><br>Password: <i>demo</i>"
VITE_LOGIN_PAGE_MESSAGE=
NODE_ENV=production
- Yes, this has to be long. At least 20 characters.
Immich Docker Swarm config
Create a docker swarm config file in docker-compose syntax (v3), something like the example below.. example:
Fast-track with premix! 🚀
"Premix" is a git repository which includes necessary docker-compose and env files for all published recipes. This means that you can launch any recipe with just a git pull
and a docker stack deploy
👍.
🚀 Update: Premix now includes an ansible playbook, enabling you to deploy an entire stack + recipes, with a single ansible command! (more here)
version: "3.2"
services:
immich-server:
image: altran1502/immich-server:release
entrypoint: ["/bin/sh", "./start-server.sh"]
volumes:
- /var/data/immich/upload:/usr/src/app/upload
env_file: /var/data/config/immich/immich.env
networks:
- internal
immich-microservices:
image: altran1502/immich-server:release
entrypoint: ["/bin/sh", "./start-microservices.sh"]
volumes:
- /var/data/immich/upload:/usr/src/app/upload
env_file: /var/data/config/immich/immich.env
networks:
- internal
immich-machine-learning:
image: altran1502/immich-machine-learning:release
entrypoint: ["/bin/sh", "./entrypoint.sh"]
volumes:
- /var/data/immich/upload:/usr/src/app/upload
env_file: /var/data/config/immich/immich.env
networks:
- internal
immich-web:
image: altran1502/immich-web:release
entrypoint: ["/bin/sh", "./entrypoint.sh"]
env_file: /var/data/config/immich/immich.env
networks:
- internal
redis:
image: redis:6.2
networks:
- internal
db:
image: postgres:14
env_file: /var/data/config/immich/immich.env
volumes:
- /var/data/runtime/immich/database:/var/lib/postgresql/data
networks:
- internal
db-backup:
image: postgres:14
env_file: /var/data/config/immich/immich-db-backup.env
volumes:
- /var/data/immich/database-dump:/dump
entrypoint: |
bash -c 'bash -s <<EOF
trap "break;exit" SIGHUP SIGINT SIGTERM
sleep 2m
while /bin/true; do
pg_dump -Fc > /dump/dump_\`date +%d-%m-%Y"_"%H_%M_%S\`.psql
ls -tr /dump/dump_*.psql | head -n -"$$BACKUP_NUM_KEEP" | xargs -r rm
sleep $$BACKUP_FREQUENCY
done
EOF'
networks:
- internal
immich-proxy:
container_name: immich_proxy
image: altran1502/immich-proxy:release
ports:
- 2283:80
deploy:
replicas: 1
labels:
# traefik
- traefik.enable=true
- traefik.docker.network=traefik_public
# traefikv1
- traefik.frontend.rule=Host:immich.example.com
- traefik.port=80
# traefikv2
- "traefik.http.routers.immich.rule=Host(`immich.example.com`)"
- "traefik.http.routers.immich.entrypoints=https"
- "traefik.http.services.immich.loadbalancer.server.port=80"
networks:
- internal
- traefik_public
networks:
traefik_public:
external: true
internal:
driver: overlay
ipam:
config:
- subnet: 172.16.8.0/24
Note
Setup unique static subnets for every stack you deploy. This avoids IP/gateway conflicts which can otherwise occur when you're creating/removing stacks a lot. See my list here.
Launch Immich!
Launch the Immich stack by running
docker stack deploy immich -c /var/data/config/immich/immich.yml
Now hit the URL you defined in your config, and you should be prompted to create your first (admin) account, after which you can login (with the details you just created), and start admin-ing. Install a mobile app, connect using the same credentials, and start backing up all your photos!
Summary
What have we achieved? We have an HTTPS-protected endpoint to target with the native mobile apps, allowing us to backup photos from mobile devices and have them become searchable, shareable, and browseable via a beautiful, Google Photos-esque interface!
Summary
Created:
- Photos can be synced from mobile device, or manually uploaded via web UI
Setup Immich in < 60s
Sponsors have access to a Premix playbook, which will set up Immich in under 60s (see below):
Chef's notes 📓
-
"wife-insurance": When the developer's wife is a primary user of the platform, you can bet he'll be writing quality code! ↩
-
There's a friendly Discord server for Immich too! ↩
Tip your waiter (sponsor) 👏
Did you receive excellent service? Want to compliment the chef? (..and support development of current and future recipes!) Sponsor me on Github / Ko-Fi / Patreon, or see the contribute page for more (free or paid) ways to say thank you! 👏
Employ your chef (engage) 🤝
Is this too much of a geeky PITA? Do you just want results, stat? I do this for a living - I'm a full-time Kubernetes contractor, providing consulting and engineering expertise to businesses needing short-term, short-notice support in the cloud-native space, including AWS/Azure/GKE, Kubernetes, CI/CD and automation.
Learn more about working with me here.
Flirt with waiter (subscribe) 💌
Want to know now when this recipe gets updated, or when future recipes are added? Subscribe to the RSS feed, or leave your email address below, and we'll keep you updated.