📸 Breaking up with Google: Installing Immich and ImmichFrame with Docker Compose
Continuing the Breaking Up with Google series, this guide shows you how to self-host your photos with Immich and display them using ImmichFrame — all managed through Docker Compose. No more relying on Google Photos: your media stays private and under your control.
We’ll walk through setting up the server, database, Redis, machine learning container, and the ImmichFrame dashboard, all using the following Docker Compose file. This does assume you have already set up traefik on the host and are using a network called "proxy". You'll need HTTPS for immichframe to talk to your nest hubs later.
🐳 Step 1: Your Docker Compose File
Here’s the full docker-compose.yml for Immich and ImmichFrame:
name: immich
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
- ${UPLOAD_LOCATION}:/data
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
ports:
- '2283:2283'
networks:
- proxy
depends_on:
- redis
- database
restart: always
healthcheck:
disable: false
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.middlewares.immich-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.immich-secure.entrypoints=https"
- "traefik.http.routers.immich-secure.rule=Host(`<immich>`)"
- "traefik.http.routers.immich-secure.service=immich"
- "traefik.http.routers.immich-secure.tls=true"
- "traefik.http.routers.immich.entrypoints=http"
- "traefik.http.routers.immich.middlewares=immich-https-redirect"
- "traefik.http.routers.immich.rule=Host(`<immich>`)"
- "traefik.http.services.immich.loadbalancer.server.port=2283"
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- model-cache:/cache
env_file:
- .env
restart: always
healthcheck:
disable: false
networks:
- proxy
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm@sha256:fea8b3e67b15729d4bb70589eb03367bab9ad1ee89c876f54327fc7c6e618571
healthcheck:
test: redis-cli ping || exit 1
restart: always
networks:
- proxy
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
shm_size: 128mb
restart: always
networks:
- proxy
immichframe:
container_name: immichframe
image: ghcr.io/immichframe/immichframe:latest
restart: on-failure
volumes:
- /opt/images/immich/immichframe-config:/app/Config
ports:
- "8080:8080"
networks:
- proxy
environment:
TZ: "Europe/London"
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.middlewares.immichframe-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.immichframe-secure.entrypoints=https"
- "traefik.http.routers.immichframe-secure.rule=Host(`<immichframe>`)"
- "traefik.http.routers.immichframe-secure.service=immichframe"
- "traefik.http.routers.immichframe-secure.tls=true"
- "traefik.http.routers.immichframe.entrypoints=http"
- "traefik.http.routers.immichframe.middlewares=immichframe-https-redirect"
- "traefik.http.routers.immichframe.rule=Host(`<immichframe>`)"
- "traefik.http.services.immichframe.loadbalancer.server.port=8080"
volumes:
model-cache:
networks:
proxy:
external: true🔧 Step 2: Deploy Immich and ImmichFrame
- Save this
docker-compose.ymlto a folder, e.g.,/opt/immich - Create a
.envfile with the following variables:
UPLOAD_LOCATION=/opt/images/immich/uploads
DB_PASSWORD=your_db_password
DB_USERNAME=immich
DB_DATABASE_NAME=immich_db
DB_DATA_LOCATION=/opt/images/immich/db
IMMICH_VERSION=release- Create a file called
Settings.yamlin your Immichframe configuration directory (mine is: /opt/images/immich/immichframe-config) and paste the following inside it.
General:
PhotoDateFormat: 'dd/MM/yyyy' # string
ImageLocationFormat: 'City,State,Country'
# Imperial or metric system (Fahrenheit or Celsius)
UnitSystem: 'metric' # 'imperial' | 'metric'
# 2 digit ISO code, sets the language of the weather description.
Language: 'en' # string
# Image interval in seconds. How long an image is displayed in the frame.
Interval: 45
# Duration in seconds.
TransitionDuration: 2 # float
# Displays the current time.
ShowClock: true # boolean
# Time format
ClockFormat: 'hh:mm' # string
# Date format for the clock
ClockDateFormat: 'eee, MMM d' # string
# Allow two portrait images to be displayed next to each other
Layout: 'splitview' # single | splitview
# multiple accounts permitted
Accounts:
- # The URL of your Immich server e.g. `http://photos.yourdomain.com` / `http://192.168.0.100:2283`.
ImmichServerUrl: 'http://immich-server:2283' # string, required, no default
# Read more about how to obtain an Immich API key: https://immich.app/docs/features/command-line-interface#obtain-the-api-key
ApiKey: 'KatpLGHvFLorrYsTNp3yQNvl4YuY37alla1rN61d8' # string, required, no default
## UUID of album(s) - e.g. ['00000000-0000-0000-0000-000000000001']
#Albums: # string[]
# - 73aef035-490f-4a8f-9162-08aceba6ba35
## UUID of excluded album(s)
#ExcludedAlbums: # string[]
# - UUID
## UUID of People
People: # string[]
## - UUID- Start the containers:
docker-compose up -d
- Confirm they’re running:
docker ps
You should see all five containers: immich_server, immich_machine_learning, immich_redis, immich_postgres, and immichframe.
🌐 Step 3: Access Immich and ImmichFrame
- Immich Dashboard:
https://<immich> - ImmichFrame Display:
https://<immichframe>.These assume your Traefik reverse proxy is running and configured to use the externalproxynetwork.
✅ Step 4: Optional Enhancements
- Enable GPU acceleration in the ML container (
immich-machine-learning) - Backup PostgreSQL and media volumes regularly
- Integrate ImmichFrame with Home Assistant for automated photo displays
- Adjust Traefik labels for custom domains or HTTPS certificates
🔒 Why Self-Hosting Matters
- Photos stay on your own server
- Full privacy and control
- Avoid Google Photos entirely
- Seamlessly integrate into your smart home setup
✨ Next in the Breaking Up with Google Series
Learn how to automate ImmichFrame on Nest Hubs using Home Assistant - turning your smart displays into a private, automated photo frame.
About the author
Tim Wilkes is a UK-based security architect with over 15 years of experience in electronics, Linux, and Unix systems administration. Since 2021, he's been designing secure systems for a telecom company while indulging his passions for programming, automation, and 3D printing. Tim shares his projects, tinkering adventures, and tech insights here - partly as a personal log, and partly in the hopes that others will find them useful.
Want to connect or follow along?
LinkedIn: [phpsytems]
Twitter / X: [@timmehwimmy]
Mastodon: [@timmehwimmy@infosec.exchange]
If you've found a post helpful, consider supporting the blog - it's a part-time passion that your support helps keep alive.
⚠️ Disclaimer
This post may contain affiliate links. If you choose to purchase through them, I may earn a small commission at no extra cost to you. I only recommend items and services I’ve personally read or used and found valuable.
As an Amazon Associate I earn from qualifying purchases.