# Building a Self-Hosted Photo Library That Survives Real Life

Cloud photo services are convenient, but they also create long-term concerns around subscription costs, privacy, and platform lock-in. I wanted a library that kept original files under my control while still providing the features my family expects: automatic mobile uploads, timeline browsing, shared albums, face recognition, and fast search. The final setup runs on a small home server using Immich, with photos stored on mirrored disks and the application database kept on SSD storage.

## Storage and Deployment

The server runs Docker Compose on Debian, with separate volumes for uploaded originals, thumbnails, PostgreSQL data, and machine-learning models. Keeping generated thumbnails apart from original media makes recovery simpler because only the originals and database are essential backups. I also mount the photo directory into the application container without exposing it over the public internet.

```yaml
services:
  immich-server:
    image: ghcr.io/immich-app/immich-server:release
    volumes:
      - /srv/photos/originals:/usr/src/app/upload
    env_file: .env
    restart: unless-stopped
```

## Uploads and Remote Access

Each phone uses the mobile app to upload new photos whenever it is connected to Wi-Fi and charging. Remote access is provided through a private VPN rather than a directly forwarded router port. A reverse proxy terminates HTTPS on the internal network, while firewall rules restrict the photo service, database, and administrative interfaces to trusted subnets.

## Backups Are Part of the Design

Disk mirroring protects against a single drive failure, but it does not protect against accidental deletion, corruption, theft, or ransomware. Every night, the server creates a database dump and sends it with the original media to an encrypted external backup destination. A second offline drive is updated monthly and stored away from the server. I test recovery quarterly by restoring a small database snapshot and opening a random sample of original files.

## Operational Lessons

Machine-learning jobs consume more memory and CPU than ordinary browsing, so I schedule large indexing tasks overnight and cap container resources. Database and application versions are upgraded together only after reading release notes and creating a fresh backup. This setup requires more maintenance than a hosted service, but ownership remains clear: the original files are ordinary files on disk, backups are portable, and the library can be rebuilt without depending on a single vendor.