ksKieran Schoaf.Résumé ↗
← All selected work

PROJECT 03 / HOMELAB / SELF-HOSTED INFRASTRUCTURE

My memories.
My infrastructure.

A self-hosted photo library on Unraid, with remote access through Cloudflare Tunnel and persistent data separated from the application lifecycle.

ImmichUnraidDocker ComposePostgreSQLCloudflare Tunnel
11,000+Photos & videos
00Inbound ports for Immich
DockerApplication services
PersistentDatabase & media storage
REMOTE ACCESS / WITHOUT PORT FORWARDING
01HTTPS request

Remote client

02Cloudflare edge

Public hostname & TLS

03Tunnel

Outbound from home

04Immich

Unraid / Docker

The home-side tunnel connector initiates the outbound connection. Requests reach Immich through that established tunnel.

01 / THE PROBLEM

Control the library. Keep it reachable.

I wanted control over where my photos and videos live without giving up access away from home. Self-hosting the application solved the storage question, but remote access and data persistence needed their own design.

This project brings those pieces together: an Immich stack on Unraid, remote access through an outbound Cloudflare Tunnel, and persistent storage for the data that needs to outlast the application containers.

02 / WHAT I BUILT

An application stack with a durable core.

Immich runs as a multi-container Docker Compose deployment. Application and machine-learning services work with Redis and PostgreSQL, while the database and media library are mapped to persistent storage on the Unraid array.

Remote access through Cloudflare Tunnel

A cloudflared container initiates an outbound connection from the home server to Cloudflare. Requests to the public hostname arrive at the edge and travel through the tunnel to Immich. No inbound router port forwarding is configured for this service.

Persistent data, replaceable containers

The PostgreSQL database and photo library live outside the containers’ writable filesystems. Replacing the application layer does not require replacing the underlying data.

03 / ENGINEERING DECISIONS

Design around the data.

The Compose configuration ties together container networks, volume mounts, environment variables, and service dependencies. The application needs a reachable database, while the machine-learning workload has its own resource requirements.

Cloudflare handles the public hostname’s TLS termination and certificates at its edge. The tunnel maps that hostname to the internal Immich service. This introduces a dependency on Cloudflare’s infrastructure as part of the remote-access path.

04 / THE OUTCOME

A rebuild tested the design.

The library manages approximately 11,000 photos and videos, with mobile backups, photo recognition, and search. The original deployment has been running since 2025.

When the application layer failed badly enough to need a rebuild, the PostgreSQL data on the Unraid array remained intact. After the replacement application reconnected to the existing database, the metadata, albums, and user data were still there.

VALIDATED DURING A REAL REBUILD

The application was replaceable. The database and library survived independently of it.

05 / WHAT STAYED WITH ME

Persistence is an architecture decision.

Separating application containers from their data is easy to describe and more meaningful when a rebuild puts it to the test. This project made storage boundaries, service dependencies, and the remote-access path part of the design from the start.

KEEP EXPLORING

More connections.
More possibilities.

Have a question about the project?

Let’s talk ↗