Immich in Podman instead of Docker

Immich is a pretty cool open source, web-based photo library management software designed to easily be self-hosted. 100% of that appeals to me, but unfortunately their recommended installation process uses Docker Compose.

I'm a curmudgeon and I don't like Docker. I prefer Podman because I don't want my containers running as root and I don't like Docker's daemon. Yes, I know it's technically possible to do no-root Docker, but it's slightly off the beaten path and I'd rather just use Podman, which was designed for non-root execution from the get-go.

Podman can do pretty much everything Docker does, often with the same interface, but it doesn't have built-in support for Docker Compose files. Instead, podman compose shells out to an external “provider”, either docker-compose itself, or podman-compose, a big complicated python-based reimplementation.

I wanted to avoid all of that, so I just configured Immich to run in a podman pod.

Here's my shell script for creating the pod:

#!/bin/bash

systemctl --user disable pod-immich
systemctl --user stop pod-immich

cd /home/someuser/.config/systemd/user
rm pod-immich.service
rm container-redis.service
rm container-immich-server.service
rm container-immich-machine-learning.service
rm container-database.service
systemctl --user daemon-reload

podman pod stop immich
podman pod rm immich
podman pod create --name immich --publish 0.0.0.0:2283:2283

podman run --replace --detach --pod immich --name immich-machine-learning --env-file /home/someuser/immich/.env --volume /home/someuser/immich/model-cache:/cache --memory-reservation=2g --memory=4g ghcr.io/immich-app/immich-machine-learning:release

# docker.io/redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
podman run --replace --detach --pod immich --memory-reservation=2g --memory=4g --name redis docker.io/redis@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8

# docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
podman run --replace --detach --pod immich --name database --env-file /home/someuser/immich/.env --volume /home/someuser/immich/postgres:/var/lib/postgresql/data --memory-reservation=2g --memory=4g docker.io/tensorchord/pgvecto-rs@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52  postgres -c shared_preload_libraries=vectors.so -c 'search_path="$$user", public, vectors' -c logging_collector=on -c max_wal_size=2GB -c shared_buffers=512MB -c wal_compression=on

podman run --replace --detach --pod immich --name immich-server --env-file /home/someuser/immich/.env --volume /home/someuser/immich/upload:/usr/src/app/upload --volume /etc/localtime:/etc/localtime:ro --volume /home/someuser/Pictures:/mnt/media/megapictures:ro --requires redis,database,immich-machine-learning --memory-reservation=2g --memory=4g ghcr.io/immich-app/immich-server:release

podman generate systemd --files --name --name immich
systemctl --user daemon-reload
systemctl --user enable pod-immich.service

This creates a pod, then creates four containers within it for the services that Immich requires. It also registers it with systemd.

Some notes:

You may ask: “Isn't this essentially just re-creating the docker compose file in a script that makes a Podman pod?” Yep.