PostgreSQL with pgvector and vectorchord extensions required by Immich for vector similarity search. Defaults to PostgreSQL 14 (:latest), PostgreSQL 18 available as :18.
| Port | 5432 |
| Registry | ghcr.io/daemonless/immich-postgres |
| Source | https://github.com/immich-app/immich |
| Website | https://immich.app/ |
| Tag | Description | Best For |
|---|---|---|
14 / 14-pkg / latest |
Upstream Binary. Built from official release. | Most users — recommended. |
18 / 18-pkg |
Upstream Binary. Built from official release. | Alternative build. |
Before deploying, ensure your host environment is ready. See the Quick Start Guide for host setup instructions.
services:
immich-postgres:
image: "ghcr.io/daemonless/immich-postgres:latest"
container_name: immich-postgres
environment:
- POSTGRES_USER=postgres # Database superuser (default: postgres)
- POSTGRES_PASSWORD=postgres # Database password (default: postgres)
- POSTGRES_DB=immich # Database name (default: immich)
- POSTGRES_INITDB_ARGS= # Additional initdb arguments
volumes:
- "/path/to/containers/immich-postgres:/var/lib/postgresql/data"
ports:
- "5432:5432"
annotations:
org.freebsd.jail.allow.sysvipc: "true"
# always (not unless-stopped) so FreeBSD's podman rc.d auto-starts it at boot
restart: alwaysSave as compose.yaml, then run podman-compose up -d.
.env:
# .env
DIRECTOR_PROJECT=immich-postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=immich
POSTGRES_INITDB_ARGS=
appjail-director.yml:
# appjail-director.yml
options:
- virtualnet: ':<random> default'
- nat:
services:
immich-postgres:
name: immich_postgres
options:
- container: 'boot args:--pull'
- expose: '5432:5432 proto:tcp'
- template: !ENV '${PWD}/immich-postgres.conf'
oci:
user: root
environment:
- POSTGRES_USER: !ENV '${POSTGRES_USER}'
- POSTGRES_PASSWORD: !ENV '${POSTGRES_PASSWORD}'
- POSTGRES_DB: !ENV '${POSTGRES_DB}'
- POSTGRES_INITDB_ARGS: !ENV '${POSTGRES_INITDB_ARGS}'
volumes:
- immich-postgres: /var/lib/postgresql/data
volumes:
immich-postgres:
device: '/path/to/containers/immich-postgres'Makejail:
# Makejail
ARG tag=latest
OPTION overwrite=force
OPTION from=ghcr.io/daemonless/immich-postgres:${tag}
SET allow.sysvipc=1
Save the files above, then run appjail-director up.
Note: Exposing ports in AppJail means that your service can be reached from remote hosts. If that is not your intention, do not expose the ports and communicate with the service using the IPv4 address assigned by the virtual network.
podman run -d --name immich-postgres \
-p 5432:5432 \
--annotation 'org.freebsd.jail.allow.sysvipc=true' \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=immich \
-e POSTGRES_INITDB_ARGS= \
-v /path/to/containers/immich-postgres:/var/lib/postgresql/data \
ghcr.io/daemonless/immich-postgres:latestSave as run.sh, then run sh run.sh.
appjail oci run -Pd \
-o overwrite=force \
-o container="args:--pull" \
-o virtualnet=":<random> default" \
-o nat \
-o expose="5432:5432 proto:tcp" \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=immich \
-e POSTGRES_INITDB_ARGS= \
-o fstab="/path/to/containers/immich-postgres /var/lib/postgresql/data <pseudofs>" \
ghcr.io/daemonless/immich-postgres:latest immich-postgresSave as run.sh, then run sh run.sh.
Note: Exposing ports in AppJail means that your service can be reached from remote hosts. If that is not your intention, do not expose the ports and communicate with the service using the IPv4 address assigned by the virtual network.
Warning
Bastille's OCI support is experimental. It requires buildah, shares the host network stack (inherit), and persists image-declared volumes under --data-path.
services:
immich-postgres:
image: "ghcr.io/daemonless/immich-postgres:latest"
container_name: immich-postgres
network_mode: host # jail shares host networking
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=immich
- POSTGRES_INITDB_ARGS=Save as podman-compose.yml, then run bastille up. Or via CLI:
bastille create -O \
--env POSTGRES_USER=postgres \
--env POSTGRES_PASSWORD=postgres \
--env POSTGRES_DB=immich \
--env POSTGRES_INITDB_ARGS= \
--data-path /path/to/containers/immich-postgres \
immich-postgres ghcr.io/daemonless/immich-postgres:latest inherit- name: Deploy immich-postgres
containers.podman.podman_container:
name: immich-postgres
image: "ghcr.io/daemonless/immich-postgres:latest"
state: started
restart_policy: always
env:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
POSTGRES_DB: "immich"
POSTGRES_INITDB_ARGS: ""
ports:
- "5432:5432"
volumes:
- "/path/to/containers/immich-postgres:/var/lib/postgresql/data"
annotation:
org.freebsd.jail.allow.sysvipc: "true"Save as immich-postgres-deploy.yaml, then run ansible-playbook immich-postgres-deploy.yaml.
| Variable | Default | Description |
|---|---|---|
POSTGRES_USER |
postgres |
Database superuser (default: postgres) |
POSTGRES_PASSWORD |
postgres |
Database password (default: postgres) |
POSTGRES_DB |
immich |
Database name (default: immich) |
POSTGRES_INITDB_ARGS |
`` | Additional initdb arguments |
| Path | Description |
|---|---|
/var/lib/postgresql/data |
Database data directory |
| Port | Protocol | Description |
|---|---|---|
5432 |
TCP | PostgreSQL Port |
This image is part of the Immich Stack.
PostgreSQL version: :latest and :14 use PostgreSQL 14. :18 uses PostgreSQL 18.
New installations should consider :18. If you are migrating an existing Immich instance,
stay on :14 — PostgreSQL major version upgrades require a full pg_dumpall and restore.
The default :latest tag will follow whatever version Immich recommends upstream.
PostgreSQL requires allow.sysvipc for shared memory. Create immich-postgres.conf alongside appjail-director.yml:
exec.start: "/bin/sh /etc/rc"
exec.stop: "/bin/sh /etc/rc.shutdown jail"
mount.devfs
persist
allow.sysvipc
Architectures: amd64
User: postgres (UID/GID via PUID/PGID, defaults to 1000:1000)
Base: FreeBSD 15.1
Need help? Join our Discord community.