Skip to content

Self-Hosting Starter Guide

Self-hosting is running your own services on hardware you control instead of depending on someone else's platform. It's more work than just signing up for a SaaS product, but you own your data, you don't have to worry about a company changing their pricing or disappearing, and there's no profit motive to do weird things with your stuff.

This is where to start if you want in but don't know where to begin.

What You Actually Need

You don't need a rack full of servers. A single machine with Docker is enough to run most things people want to self-host. Options in rough order of entry cost:

  • Old laptop or desktop — works fine for home use, just leave it on
  • Raspberry Pi or similar SBC — low power, always-on, limited compute
  • Mini PC (Intel NUC, Beelink, etc.) — better than SBC, still low power, actually useful
  • Old server hardware — more capable, louder, more power draw
  • VPS — if you want public internet access and don't want to deal with networking

For a first setup, a mini PC or a spare desktop you already have is the right call.

The Core Stack

Three tools cover almost everything:

Docker — runs your services as containers. One command to start a service, one command to update it.

Docker Compose — defines multi-service setups in a YAML file. Most self-hosted apps publish a compose.yml you can use directly.

A reverse proxy (Nginx Proxy Manager, Caddy, or Traefik) — routes traffic to your services by hostname or path, handles SSL certificates.

# Install Docker (Linux)
curl -fsSL https://get.docker.com | sh

# Add your user to the docker group (so you don't need sudo every time)
sudo usermod -aG docker $USER
# Log out and back in after this

# Verify
docker --version
docker compose version

Starting a Service

Most self-hosted apps have a Docker Compose file in their documentation. The pattern is the same for almost everything:

  1. Create a directory for the service
  2. Put the compose.yml in it
  3. Run docker compose up -d

Example — Uptime Kuma (monitoring):

# uptime-kuma/compose.yml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    ports:
      - "3001:3001"
    volumes:
      - ./data:/app/data
    restart: unless-stopped
mkdir uptime-kuma && cd uptime-kuma
# paste the compose.yml
docker compose up -d
# open http://your-server-ip:3001

What to Self-Host First

Start with things that are low-stakes and high-value:

  • Uptime Kuma — monitors your other services, alerts when things go down. Easy to set up, immediately useful.
  • Portainer — web UI for managing Docker. Makes it easier to see what's running and pull updates.
  • Vaultwarden — self-hosted Bitwarden-compatible password manager. Your passwords on your hardware.
  • Nextcloud — file sync and storage. Replaces Dropbox/Google Drive.
  • Jellyfin — media server for your own video library.

Don't try to spin everything up at once. Get one service working, understand how it runs, then add the next one.

Networking Basics

By default, services are only accessible on your home network. You have options for accessing them remotely:

  • Tailscale — install on your server and your other devices, everything is accessible over a private encrypted network. Zero port forwarding required. This is what I use.
  • Cloudflare Tunnel — exposes services publicly through Cloudflare's network without opening ports. Good if you want things internet-accessible without exposing your home IP.
  • Port forwarding — traditional method, opens a port on your router to the server. Works but exposes your home IP.

Tailscale is the easiest and safest starting point for personal use.

Gotchas & Notes

  • Persistent storage: Always map volumes for your service's data directory. If you run a container without a volume and it gets recreated, your data is gone.
  • Restart policies: Use restart: unless-stopped on services you want to survive reboots. always also works but will restart even if you manually stopped the container.
  • Updates: Pull the new image and recreate the container. docker compose pull && docker compose up -d is the standard pattern. Check the app's changelog first for anything that requires migration steps.
  • Backups: Self-hosting means you're responsible for your own backups. Back up the data directories for your services regularly. The compose.yml files should be in version control or backed up separately.
  • Don't expose everything to the internet. If you don't need public access to a service, don't create it. Tailscale for private access is safer than punching holes in your firewall.

See Also

  • [[docker-vs-vms-homelab]]
  • [[debugging-broken-docker-containers]]
  • [[linux-server-hardening-checklist]]