In this post, I document the steps I followed to set up Immich – a self-hosted photo and video backup solution – on my local server using Docker and Caddy. I also configured it to be accessible over HTTPS with a custom subdomain.
🔧 Requirements
- Docker and Docker Compose installed
- A registered domain (e.g. wallaceat.me)
- Caddy running in a container for reverse proxy and HTTPS
📁 Directory Structure
/home/wallace/server/immich
├── docker-compose.yml
├── stack.env
└── ...
📝 docker-compose.yml
Here’s the Docker Compose file I used:
version: "3.8"
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:release
volumes:
- /mnt/immich:/usr/src/app/upload:rw
- /etc/localtime:/etc/localtime:ro
env_file:
- stack.env
ports:
- '2283:2283'
depends_on:
- redis
- database
restart: always
networks:
- immich-network
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:release
volumes:
- model-cache:/cache
env_file:
- stack.env
restart: always
networks:
- immich-network
redis:
image: redis:6.2-alpine
restart: always
networks:
- local
database:
image: tensorchord/pgvecto-rs:pg14-v0.2.0
environment:
POSTGRES_PASSWORD: your_password
POSTGRES_USER: your_user
POSTGRES_DB: your_db
volumes:
- /mnt/postgres:/var/lib/postgresql/data
restart: always
networks:
- local
volumes:
model-cache:
networks:
local
🌐 Caddy Configuration
My Caddy server is already running in a separate container and serves multiple services. Here’s the config snippet I added to the Caddyfile to expose Immich:
photos.wallaceat.me {
reverse_proxy immich_server:2283
}
If using an external Caddy container, ensure it’s in the same Docker network or resolve to the host’s IP and port.
🌍 Domain and HTTPS
I pointed the subdomain subdomain.wallaceat.me to my server’s IP using an A record on my DNS provider (Dynu). Caddy automatically issued a Let’s Encrypt certificate.
🛠 Common Issues
- Port conflicts: Ensure no other services are using port 80 or 443
- Redis timeout: Check if the Redis container is running and available on the Docker network
- Permissions: Mount points like /mnt/immich must be accessible by Docker
📌 Tips
- Automate DNS updates using Dynu’s dynamic IP update client if your IP is dynamic
- Consider automating deployment via GitHub Actions or Drone CI in the future
Leave a Reply