Self-hosted service
imagegenius/docker-immich avatar
imagegenius/docker-immich

docker-immich: four variants, and the accelerated two are amd64 only

Monolithic (Single) Docker Container for Immich

1,109 stars61 forksDockerfileGPL-3.0

At a glance

What is it?
This repository packages Immich, the self-hosted photo and video backup, as a single container with four variants and an external database. The packaging is carefully built, with a multi-stage Dockerfile, a Go test suite that starts containers and a Renovate configuration. The documentation has two gaps that matter on the first afternoon: the example compose file binds both servers to all interfaces while mounting nothing, and the upgrade instruction tells you to recreate the container with the same run parameters that the page never shows you.
Who is it for?
Take docker-immich if you want Immich as one container, you already run or can run PostgreSQL 14 to 17 with the vector extension, and your host is either amd64 or an arm64 machine that will run machine learning on the CPU. Leave it if you need CUDA on arm64 hardware, because the accelerated variants are published for amd64 only, or if you want the database included, because it never is.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Dockerfile, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four variants, two architectures, and only one combination of the two

The variant table is the whole product in four rows, and the platform column is where the constraint lives.

`latest` is Ubuntu with machine learning on the CPU, built for amd64 and arm64. `noml` is the same with machine learning disabled and a smaller image, also amd64 and arm64. `cuda` is Ubuntu with machine learning on NVIDIA, amd64 only. `openvino` is Ubuntu with machine learning on Intel, amd64 only.

So both hardware-accelerated builds are single-architecture. An arm64 host with an NVIDIA GPU, which is not an exotic machine any more, has no tag in this table that serves it: the arm64 images run machine learning on the CPU or not at all. The README does not discuss this case at all.

Pinning is documented with the upstream release number and an optional variant suffix:

code
ghcr.io/imagegenius/immich:2.7.5
ghcr.io/imagegenius/immich:2.7.5-cuda

Those two tag shapes are not the ones the release list uses. The releases are tagged `v2.7.5-ig458` and `noml-v2.7.5-ig370`, with a leading v, a build counter, and in the second case the variant name in front. So there are two naming schemes in the same repository, and neither is a prefix of the other.

The newest release is titled GitHub Releases Archived, dated 2026-05-18, and the last push was 2026-10-02. Tagging has moved to the container registry, which is what the badge row implies with its link to packages.

The compose example binds both servers to 0.0.0.0 and mounts no volumes

The example compose file is the first thing a reader copies, so its defaults matter.

Two of its values are worth pausing on. `SERVER_HOST=0.0.0.0` and `MACHINE_LEARNING_HOST=0.0.0.0` are both set, which are the app server and the machine learning server, bound to every interface rather than to loopback. Both are marked optional in the example, so a reader who deletes the optional lines gets a safer default by accident rather than by intent.

The second thing is what is missing. The example has no `ports:` mapping and no `volumes:` section at all, while the parameter table immediately below it documents a port mapping for the web interface and three volumes: one for the app config and the machine learning model cache, one for the photo library, and one for external libraries.

So a literal copy of the shipped YAML produces a container that binds broadly, publishes nothing, and persists nothing. No photo library means no photos after a restart, and the config volume is where the model cache lives, quoted at about 1.5GB with defaults.

The example also uses the literal placeholder `192.168.1.x` as the value for both the database and the Redis hostname, so it is a template rather than something that runs, which is normal and worth stating before a reader assumes the rest of it is finished.

The upgrade says recreate with the same run parameters, and no run command is shown

The updating section is four commands and one instruction:

bash
docker pull ghcr.io/imagegenius/immich:latest
docker stop immich && docker rm immich
# recreate with the same docker run parameters
docker image prune  # optional: remove dangling images

The instruction in the middle is the one that matters, and the page does not support it. There is no complete `docker run` line anywhere in the README. The parameters are given as a table of fragments: a port mapping, a series of environment variables, and three volume paths, and the Compose example that does exist has no volumes and no ports. So a reader who set up with docker run has to reassemble their own command from table rows, and a reader who set up with Compose is told instead to run `docker compose pull && docker compose up -d`, which is the safe path.

The prune step is marked optional, which is correct, since dangling images accumulate but do not break anything.

What the page does not mention is the database. The requirements put PostgreSQL outside the container, so an upgrade that recreates the app container does not touch the database at all, and there is no instruction anywhere about migrating a database across Immich versions. For an image that tracks upstream releases closely, that is the gap a careful reader should worry about, and the README is silent on it.

Two ways to supply Redis, and they disagree on the hostname

The requirements list two external dependencies, and one of them has two documented paths that do not agree.

PostgreSQL is version 14 to 17 with the VectorChord extension, and the page points at a prebuilt image from the Immich project itself to skip extension setup. SSL for the database goes through `DB_URL`. Redis, or Valkey, can be external or supplied by a Docker mod.

The mod path is two settings: set `DOCKER_MODS` to the universal Redis mod published by the same account, and set `REDIS_HOSTNAME` to `localhost`. The compose example sets the same variable to `192.168.1.x`.

Both are correct for their own case, since the mod runs beside the container and an external Redis does not, but they are given in the same document without a note that the value depends on which path you chose. A reader who copies the mod settings and changes the mod image to a remote host ends up with a Redis hostname that resolves to their own machine.

The consequence of neither path is that the example has no database or cache service defined at all. The compose file starts with the immich service and nothing else, so Postgres and Redis are entirely the reader's problem, which is a legitimate design for a single-container image and a surprise for somebody who expected one container to mean one thing to deploy.

Machine learning is two parameters wide, and one of them is the only concurrency control

Strip away the packaging and the ML surface is remarkably small.

There is a worker count, defaulting to one, and a worker timeout, defaulting to 120. Both appear in the parameter table and neither appears in the compose example, so the only place the values are written down is the table. The machine learning server has its own host and port, defaulting to all interfaces and 3003, both marked optional in the example.

A single worker with a two-minute timeout is the entire concurrency story for a photo library that has to run face detection and object tagging over an import. Whether that is comfortable depends entirely on the library size and the hardware, and the page offers no guidance: no sizing advice, no queue behaviour, and no statement about what happens to a job that exceeds the timeout.

The two other ML facts on the page are the variant that turns it off, `noml`, described as a smaller image with machine learning disabled, and the config volume, which holds the model cache at about 1.5GB with the defaults. So opting out of ML saves image size and 1.5GB of cache, and that is the whole trade as stated.

For an arm64 host this matters more than the numbers suggest, since arm64 builds are CPU-only for ML, which makes that single worker the throughput ceiling for the whole install.

Device access is documented as broad grants, which is the right way to document it

The hardware acceleration section is short and specific, and it does not hide the permissions it asks for.

For Intel, the device node for rendering has to be mounted into the container, and for OpenVINO the page adds a device cgroup rule granting character device 189 read, write and mknod, plus a mount of the USB bus. For NVIDIA it asks you to install the container toolkit first, then run with the NVIDIA runtime and all visible devices, or the equivalent GPU flag.

Both grants are broad by design. A character device major rule is the standard way to give a container access to a GPU device node, and asking for all visible devices is the normal form of that flag rather than a per-device selection. The point in favour of this documentation is that it is written down at all, on the page, with the exact flags, instead of leaving a reader to discover that image recognition silently does not run.

The same section is where the amd64-only variants meet their limits. The Intel path and the NVIDIA path both assume a host whose devices you can pass through, and neither is published for arm64, so a reader on Apple silicon or an arm server is left with the CPU worker and no documented acceleration route at all.

The multi-user detail is one line and easy to miss: external libraries mount at `/libraries`, or at `/libraries/<user>` when there is more than one user, and registration happens twice, once in the admin settings and once in the account settings.

Four upstream projects, a multi-stage Dockerfile, and tests written in Go

The build section explains the shape, and the repository tree confirms it.

This is built with GitHub Actions, on the workflow shape from a community containers repository, and the container starts from a third-party LinuxServer Ubuntu base image. On top of that, Immich's own upstream media dependency scripts run inside the Dockerfile. So the image is a composition of at least three projects, and this repository is the part that pins them together.

The Dockerfile is a multi-stage build with named stages, starting from arguments for two tool images, then a source stage that downloads an Immich release tarball for a given version, then a media dependencies stage that adds the PostgreSQL apt repository by fetching its signing key and dearmoring it, and then per-variant stages. It also sets a library path that includes a Windows Subsystem for Linux directory, which is inherited from the base image rather than chosen here.

The tooling in the root is the other half of the story. There is a Dockerfile, a build definition for buildx, a Go module and checksum file, a directory for image root files, a tests directory, plus linting and automation configuration: a Dockerfile linter, a Git hook runner, a tool version directory, a Renovate configuration, a shellcheck configuration, a formatter configuration and an editor config.

The Go module is the part that tells you how the images are verified. It declares a Go version, pulls in a container test framework and a container build library, and the directory it lives in is a test directory. So the images are tested by starting containers, and the same Go tooling helps build them.

Editorial conclusion

Take docker-immich if you want Immich as one container, you already run or can run PostgreSQL 14 to 17 with the vector extension, and your host is either amd64 or an arm64 machine that will run machine learning on the CPU. Leave it if you need CUDA on arm64 hardware, because the accelerated variants are published for amd64 only, or if you want the database included, because it never is. Three things to check before you copy the example: add the port mapping, which the compose snippet omits even though the parameter table documents it, add the three volumes, especially the config volume that holds the model cache, and decide whether you want the server bound to all interfaces, since the shipped default is 0.0.0.0 for both the app and the machine learning server.

Frequently asked questions

What is imagegenius/docker-immich?

A single-container Docker image of Immich, the self-hosted photo and video backup application, published under ghcr.io/imagegenius in four variants. PostgreSQL 14 to 17 and Redis or Valkey stay outside the container, either external or added through a Docker mod.

Which docker-immich image should I use?

The plain latest tag for Ubuntu with CPU machine learning, noml to disable machine learning for a smaller image, cuda for NVIDIA and openvino for Intel. The latest and noml tags are built for amd64 and arm64; cuda and openvino are amd64 only, so an arm64 host with an NVIDIA GPU has no accelerated tag.

How do I update the docker-immich container?

Pull the new image, stop and remove the container, then recreate it with the same run parameters, and optionally prune dangling images. With Compose the equivalent is `docker compose pull && docker compose up -d`. The README contains no complete docker run line, so the run parameters have to come from its parameter table.

Does the docker-immich image include a database?

No. The compose example points the database and Redis hostnames at an external address, and the requirements ask for PostgreSQL 14 to 17 with VectorChord, plus Redis or Valkey supplied externally or through a Docker mod. Nothing in the README covers migrating that database between Immich versions.

Which volumes does the docker-immich image need?

Three. `/config` holds the app config and the machine learning model cache, quoted at about 1.5GB with the defaults, `/photos` holds the photo library, and `/libraries` holds external libraries, which are registered once in the admin settings and once in the account settings. The example compose file on the page includes none of them.

Official sources

  1. imagegenius/docker-immich on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/imagegenius-docker-immich.svg)](https://hysenlabs.com/projects/imagegenius-docker-immich)