Self-hosting means running your own applications on hardware you control instead of relying on third-party cloud services. It gives you full ownership of your data, eliminates subscription fees for many tools, and teaches you how the internet actually works. In 2026, the tooling has matured to the point where anyone comfortable with a terminal can get started in an afternoon. By the end of this guide, you will have a working server running multiple applications behind a reverse proxy with automatic SSL certificates.
Step 1: Choose Your Hardware
You have two main options: a virtual private server (VPS) rented from a hosting provider, or physical hardware you own. Each has trade-offs, and many self-hosters eventually use both.
A VPS is the easiest starting point. You get a Linux machine with a public IP address, no hardware to maintain, and predictable monthly costs. Providers like Hetzner, Contabo, and DigitalOcean offer capable machines starting at $4-8 per month. For this guide, a VPS with 2 CPU cores, 4GB of RAM, and 80GB of storage is more than enough. If you prefer local hardware, a used Lenovo ThinkCentre or Dell OptiPlex mini PC costs $60-120 on eBay, draws 10-25 watts, and paired with an external SSD makes a capable home server for years.
Recommended starter hardware options:
- VPS: Hetzner CX22 (2 vCPU, 4GB RAM, 40GB SSD) — $4.35/month
- VPS: DigitalOcean Basic Droplet (2 vCPU, 4GB RAM, 80GB SSD) — $24/month
- Local: Lenovo ThinkCentre M720q (used, i5-8400T, 16GB RAM) — ~$90 on eBay
- Local: Raspberry Pi 5 (8GB RAM, with NVMe HAT) — ~$110 new
Step 2: Install the Operating System
If you chose a VPS, your provider will let you select an OS image during setup. Choose Ubuntu 24.04 LTS or Debian 12 — both are stable, well-documented, and supported by virtually every self-hosted application. This guide uses Ubuntu 24.04 for all examples. If you are using local hardware, download the Ubuntu Server 24.04 ISO from ubuntu.com, flash it to a USB drive using Balena Etcher or Rufus, and boot from it. Accept the defaults for partitioning and enable the OpenSSH server when prompted.
Once your server is running, SSH into it from your local machine. On macOS or Linux, open a terminal and run ssh username@your-server-ip. On Windows, use Windows Terminal or PuTTY. You should see a command prompt. Everything from here forward happens in this terminal session.
Step 3: Install Docker and Docker Compose
Docker is the foundation of modern self-hosting. It packages applications and their dependencies into isolated containers, which means you can run dozens of apps on a single server without them interfering with each other. Docker Compose lets you define multi-container setups in a simple YAML file. Install Docker using the official convenience script — this is the fastest method and works on Ubuntu, Debian, and most other Linux distributions.
Docker installation commands:
- curl -fsSL https://get.docker.com | sudo sh
- sudo usermod -aG docker $USER
- Log out and log back in (or run: newgrp docker)
- Verify with: docker run hello-world
Step 4: Deploy Your First App
Let us start with something immediately useful: Nextcloud, a self-hosted alternative to Google Drive and Dropbox. It gives you file sync, calendar, contacts, and more. Create a directory with mkdir -p ~/apps/nextcloud and add a docker-compose.yml file that defines two containers: the Nextcloud application itself and a MariaDB database. Map port 8080 on the host to port 80 inside the container and set strong, unique passwords for the MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD environment variables.
Start the stack by running docker compose up -d from the nextcloud directory. Docker will pull the images (this takes a minute on the first run) and start both containers in the background. Visit http://your-server-ip:8080 in a browser and you should see the Nextcloud setup wizard. Create an admin account, confirm the database settings, and you have a working cloud drive.
This same pattern — create a directory, write a docker-compose.yml, run docker compose up -d — works for virtually every self-hosted application. Gitea for code hosting, Vaultwarden for password management, Plausible for analytics, Uptime Kuma for monitoring. The ecosystem is enormous and growing.
Step 5: Set Up a Reverse Proxy
Right now your app is accessible on port 8080 over plain HTTP. That is fine for testing but not for production use. A reverse proxy sits in front of all your apps, routes traffic based on domain names, and handles SSL certificates automatically.
Caddy is the simplest reverse proxy for self-hosters. Unlike Nginx or Traefik, Caddy obtains and renews SSL certificates from Let's Encrypt automatically with zero configuration. Install Caddy as a Docker container alongside your apps and create a Caddyfile that maps your domain to the internal container port. For example, if you own mydomain.com and want Nextcloud at cloud.mydomain.com, your Caddyfile needs just three lines: the domain name, the reverse_proxy directive pointing to the Nextcloud container, and nothing else. Caddy handles the rest.
Point your domain's DNS A record to your server's public IP address. If you are using a VPS, this is straightforward. If you are hosting locally, you will need either a static IP from your ISP, a dynamic DNS service like DuckDNS, or a Cloudflare Tunnel that avoids exposing your home IP entirely.
Step 6: Secure Your Server
Security is not optional, even for a personal server. The internet is full of automated scanners that will find and probe your machine within hours of it going online. The good news is that basic hardening takes 15 minutes and stops the vast majority of attacks.
Essential security hardening steps:
- Disable root SSH login: edit /etc/ssh/sshd_config and set PermitRootLogin no
- Use SSH key authentication instead of passwords: ssh-copy-id user@server
- Enable the firewall: sudo ufw allow OpenSSH && sudo ufw allow 80 && sudo ufw allow 443 && sudo ufw enable
- Enable automatic security updates: sudo apt install unattended-upgrades && sudo dpkg-reconfigure unattended-upgrades
- Install fail2ban to block brute-force attempts: sudo apt install fail2ban
Step 7: Backups — The Part Everyone Skips
Self-hosting without backups is a disaster waiting to happen. Drives fail, containers get misconfigured, and mistakes happen. The 3-2-1 rule is the gold standard: keep three copies of your data, on two different types of media, with one copy offsite.
For Docker-based setups, the simplest approach is to back up the Docker volumes directory and your compose files. A cron job running a script that stops containers, copies the data to a second drive or remote location, and restarts containers is enough for most people. For a more sophisticated setup, tools like Restic or BorgBackup offer incremental, encrypted backups to local drives, S3-compatible storage, or remote servers. Whatever method you choose, test your backups regularly — spin up a test server once a quarter, restore your backup, and verify everything works. A backup you have never restored from is not a backup.
Where to Go From Here
You now have a working self-hosted setup: a server running Docker, at least one app behind a reverse proxy with SSL, basic security hardening, and a backup strategy. That is a solid foundation. The r/selfhosted subreddit and the Awesome-Selfhosted list on GitHub are excellent resources for discovering new apps and troubleshooting issues.
Start small, learn as you go, and resist the urge to self-host everything at once. Each new app you add will teach you something about networking, Linux, or system administration that makes the next one easier. Six months from now, you will wonder why you ever paid for half the cloud services you used to depend on.