Platforms

Immich on Proxmox: VM, Docker & Storage Guide

Install Immich in a Proxmox Linux VM with Docker Compose. Choose CPU features, database and NAS storage, then verify uploads, updates and backup coverage.

On this page
Advertisement

Direct Answer

For a new Proxmox deployment, create a full Linux VM and run Immich's official Docker Compose stack inside it. Immich documents full virtual machines as a suitable environment and does not recommend Docker inside LXC. A native Immich helper-script container is a community distribution with its own update and recovery responsibilities. Immich requirements ↗

Keep PostgreSQL on local guest storage backed by suitable disks, preferably SSD. Treat NAS photos as a separate mount and backup responsibility. Proxmox's successful guest-backup message does not by itself prove that externally mounted photos were included. In particular, LXC bind-mount contents are excluded from vzdump. Proxmox container documentation ↗

This page was reviewed against stable Immich v3.2.2 ↗ on September 16, 2026. v3 machine learning on amd64 requires x86-64-v2 or later as seen inside the guest. The host's physical CPU capability alone is not enough if the VM exposes an older model. GPU passthrough is optional and hardware-specific; get the CPU-based installation working first.

Who this setup is for

Choose this route if you already operate Proxmox and want Immich isolated from the hypervisor with a recognizable Linux and Docker recovery path. It is especially useful when the application lives on local SSD-backed virtual storage while photos live on a separate NAS. It assumes you can install and maintain a Linux guest; it does not require a GPU or a community installer.

Before creating the VM, identify the guest's resource allocation, LAN address, database disk, photo destination and independent backup destination. The next steps turn those choices into a working stack. An existing native LXC with valuable data needs a separate migration plan; do not point a new Compose database at its old directory.

Choose VM, Docker-in-LXC or native LXC

LayoutSupport and isolation boundaryMain operational consequence
Linux VM + official ComposeRecommended Immich method inside a full VMGuest has its own kernel/runtime; follow normal Compose release updates
Docker inside LXCAdvanced/community approach; not recommended by ImmichContainer nesting, device access and UID mapping add failure layers
Native/helper-script Immich LXCCommunity packaging, separate from official ComposeHelper's service names, dependencies and upgrade path may differ
Privileged LXCBroader host privilege exposureDo not switch merely to hide an unexplained permission error
Unprivileged LXCHost and guest user IDs are mappedA host-readable directory may still be unreadable by the app user

A maintainer reiterated the Docker support boundary in Discussion #29317 ↗. That thread asks about moving a working Docker-in-LXC library to a helper container; it does not provide a verified migration recipe. If you already have data, establish backups and a restore test before changing deployment type.

Step 1: Create the Linux VM

Use Proxmox's Create VM workflow with a supported 64-bit Linux installer ISO. Allocate at least 2 cores and 6 GB RAM; 4 cores and 8 GB match Immich's recommendations. Plan virtual disk capacity for the guest, Docker images, PostgreSQL and any local media. There is no single documented disk size that fits every photo collection. Proxmox VM guide ↗, Immich sizing ↗

Choose a guest CPU model that exposes at least x86-64-v2 for v3 amd64 machine learning. Proxmox identifies kvm64 with the older x86-64-v1 level, whereas x86-64-v2-AES meets the newer level. host can expose host capabilities but changes portability across dissimilar hosts; choose it with your migration requirements in mind. Install Linux and establish a reachable guest IP before adding Immich. CPU models ↗

Verification: log into the guest console, confirm the configured resources and IP, and confirm the chosen CPU model rather than assuming Proxmox's current default matches an old VM. v2.7.5 is the last documented x86-64-v1 option but is unsupported; retaining it is not a recommended long-term v3 solution.

Step 2: Plan the storage layers

LayerExample planning choiceWhat to verify
Proxmox storageSSD-backed virtual diskThe VM disk and backup policy include the intended data
Guest PostgreSQL directoryLocal Linux filesystemSuitable ownership/permissions; not a guest NFS/SMB mount
Guest managed-media directoryLocal disk or deliberately mounted media storageAvailable before Immich starts and large enough for originals/derivatives
Existing NAS collectionDedicated guest mount, then additional Docker mountSame container-visible path after restart or recovery
External backup destinationIndependent copy of DB and mediaFiles can be recovered without the current guest

This is an operational map derived from the two products' storage models, not a universal mount configuration. Preserve the normal upload mount while adding a separate read-only external library. A mount visible in Proxmox is not automatically visible in Linux, and a Linux mount is not automatically visible inside Docker. External-library mount instructions ↗

For a NAS-backed media directory, make the share available inside the Linux guest before starting Docker. Confirm the intended remote files are present, not just an empty local mount-point directory. Check availability again after a guest restart. The required mount persistence and credentials depend on your distribution and NAS; no universal SMB/NFS command is safe for every setup.

Set DB_DATA_LOCATION to the guest-local PostgreSQL directory and UPLOAD_LOCATION to the chosen managed-media directory. Existing photos get a separate mount into the server container, then a library import path inside Immich. Record all three path layers so a restored VM can reconstruct them. Immich storage requirements ↗

Step 3: Install Docker and Immich inside the guest

Install Docker Engine and its Compose plugin using the distribution's official Docker instructions. Then follow the complete Compose tutorial: create the application directory, download both release files, set a new upload directory and local database directory, choose a password and version, and validate the configuration. Do not run those application commands on the Proxmox hypervisor. Official Immich install ↗

From the guest's Immich Compose directory, start the stack:

bash
docker compose up -d

Expected: application services are created and start in the guest. If the command fails, identify the Compose/runtime or storage error before changing Proxmox privileges. The command is the official installation command, with the execution location explicitly scoped to the VM.

Step 4: Verify the complete path

From that same guest directory:

bash
docker compose ps -a
docker compose logs --tail=100

The first command lists service state, including stopped containers; the second shows recent logs. Look for the server, ML, cache and database remaining running, and investigate repeated exits, mount-check errors or CPU failures. Docker ps ↗, Docker logs ↗

Open http://VM-IP:2283, create the first admin, upload a few test files and verify original download and video playback. If external storage is used, scan a small test folder and check its original from the web. These are acceptance checks built from the documented install/upload flow; this guide has not tested your physical host. Post-installation ↗

Advanced branch: LXC storage and permissions

Proxmox bind mounts connect host directories to LXC paths. Unprivileged containers map user IDs into a different host range; the common root mapping begins at host 100000, but actual application IDs and custom maps must be checked. A number copied from a forum may refer to a different service user. Unprivileged LXC documentation ↗

Trace a failing path in order: the host directory exists; the LXC mount points to it; the guest's actual application identity can traverse/read it; and, for Docker-in-LXC, the additional Docker mount exposes it at the expected destination. A native helper installation will not necessarily have an immich_server Docker container, so Docker diagnostics do not apply there.

Advanced branch: GPU and hardware acceleration

Hardware acceleration has two separate layers: Proxmox must expose a usable device to the guest, and Immich must be configured for the correct backend. VM PCI passthrough needs suitable IOMMU support and device grouping; a passed-through physical device is not simultaneously available for ordinary use by the host or another VM. Proxmox documents PCIe passthrough and machine-type constraints. Proxmox VM passthrough ↗

After the guest can use the device, follow Immich's backend-specific video transcoding ↗ instructions. NVIDIA additionally requires the appropriate driver and container toolkit inside the Linux environment running Docker. Machine-learning acceleration has its own configuration and verification ↗; enabling video acceleration alone does not enable ML acceleration.

Verify an actual transcode or ML job using the chosen backend's documented checks. If the guest cannot access the device, fix passthrough first. If the guest can but Docker cannot, check the runtime/device mapping. If Docker can but the job fails, inspect Immich's backend logs. Hardware-specific driver/VFIO commands are outside what one generic page can safely establish.

For the application-side steps after guest device access works, follow the hardware-acceleration guide, which separates video and machine-learning configuration.

Backup and upgrade

Keep both a database dump and media backup, plus the Compose configuration and guest/storage mapping. For LXC, Proxmox explicitly excludes bind-mount contents from vzdump; the backup flag for storage-backed volumes does not turn arbitrary host bind mounts into backed-up data. Independently protect NAS originals. Rehearse recovery with the mounts included. Proxmox container backup scope ↗, Immich backup

Use the Immich update guide inside a Compose VM. For v2→v3, check VectorChord and CPU exposure before updating. A helper-native LXC must follow its maintainer's supported path instead of borrowing Compose database commands.

Update the application inside the VM

  1. Record the current version and save the Compose file, .env and mount configuration with the backup set.
  2. Read every applicable release note through the target version. Compare its official Compose file with your customized copy, especially database-image changes.
  3. In the guest's application directory, follow the version-aware update procedure. Pull and recreate only after satisfying any migration instructions.
  4. Check service logs and repeat login, upload, original download and an external-library scan. Do not treat a running VM as proof the application update succeeded.

What a Proxmox snapshot does not establish

A VM snapshot is useful for managing guest state, but is not an independent database-and-photo recovery set. A snapshot-mode vzdump backup is also distinct from a local VM snapshot: it copies selected guest disks, while a NAS share mounted inside Linux remains a separate backup job. The QEMU guest agent's filesystem freeze can improve disk consistency; it does not replace an Immich database dump or coordinate photos outside those disks. Proxmox backup documentation ↗

Write down which virtual disks are included in the backup, which media paths are remote, and where the database dump is saved. Recover a small test set before relying on this arrangement for the only copy of your library.

If this does not work

FailureNext diagnostic layerVerification after correction
Cannot reach 2283Guest IP/network, then Docker services and firewallBrowser opens the VM endpoint
ML stops after v3Guest CPU model and ML/backend logsML service stays up and a real job completes
NAS visible on host onlyHost→guest→Docker path and identity chainSame known original is readable through Immich
Upload permission denied in LXCActual mapped user and dedicated-directory ACLSmall upload succeeds without broad privilege changes
Restart during upgradeLogs, allocated memory and database migration progressNo repeated exit; test originals and search
Guest restore has missing imagesExternal mounts and media backup coverageOriginal download and integrity checks pass

For broken originals or previews after a mount or restore change, use Immich image-loading troubleshooting. First identify whether the original is missing or only a derived thumbnail has failed.

FAQ

Should a working Docker-in-LXC installation move to a helper script?

The maintainer's answer in #29317 ↗ does not endorse that migration. Decide based on a tested recovery path and the support boundary, not the availability of a one-click installer.

Can I make the LXC backup flag include an arbitrary bind mount?

The flag applies to storage-backed mount-point volumes. Bind mounts remain a separate backup responsibility. Proxmox container documentation ↗

Is GPU passthrough required?

No. Establish a working CPU-based deployment first. Transcoding and machine learning use separate acceleration settings, and both depend on the device being usable inside the guest. Choose acceleration only after identifying a real workload need.

Can the database live beside photos on an SMB or NFS share?

Keep the PostgreSQL data directory on a supported local guest filesystem. A network share suitable for originals is not automatically suitable for live PostgreSQL state. The database and remote photos can still be backed up to an independent destination using the documented backup procedure.

Sources

Advertisement
Continue from here