Self-hosting · Docker & Tailscale
Home server
My self-hosted setup for files, media, photos, and passwords. Everything runs in Docker, with private HTTPS access over Tailscale.
What I run
- ownCloud Infinite Scale. File storage and sync, available as
cloudon my tailnet. - Jellyfin. A media server for my library, available as
media. - Immich. Photo and video backup, available as
photos. Its stack includes PostgreSQL and Valkey. - Vaultwarden. A self-hosted password manager compatible with Bitwarden clients, available as
vault.
Private access, proper HTTPS
Each service has a Tailscale sidecar: a separate container that joins my private network as its own machine. My devices connect through Tailscale, and MagicDNS gives each service a name.
Tailscale Serve handles HTTPS with a valid Let’s Encrypt certificate and forwards requests to the application over the shared homeserver Docker network. The service Compose files publish no host ports, so these apps are reached through the tailnet rather than a public endpoint.
The addresses follow the pattern https://cloud.<tailnet-domain>, with media, photos, and vault for the other services. HTTPS also lets the Bitwarden apps and browser extension connect to Vaultwarden.
Containers and persistent data
Each application has its own Docker Compose file. They share a bridge network, while bind mounts keep application data and configuration under a configurable DATA_PATH on the host.
That includes ownCloud’s files and configuration, Jellyfin’s configuration and media library, Immich’s uploads and database, and Vaultwarden’s data. Each Tailscale sidecar keeps its state there too, so its identity survives container recreation.
The containers use restart: unless-stopped. Shared environment settings live in a local .env file, with an example checked into the repository.
Managing the stack
A small Makefile wraps Docker Compose so I can start, stop, or update one service at a time. For example, updating Jellyfin pulls its image and brings its stack back up:
make up service=jellyfin
make update service=jellyfin
make down service=jellyfin
This page reflects the configuration in the public repository, reviewed on .