How I Set Up a VPS on Hetzner Cloud to Host Self-Hosted Apps with Docker + Portainer

Cloud & Self-Hosted Posted on Jun 03, 2025
Over the past few years, I’ve gradually moved many of my tools and services away from SaaS subscriptions and into self-hosted environments. Whether it’s knowledge bases, helpdesk software, automation tools, or even app prototypes β€” I now run most of them on my own VPS. This post walks you through how I set up a clean, secure, and scalable VPS on Hetzner Cloud, ready to host Dockerized applications and manage them easily via Portainer.

πŸ“¦ Why Hetzner?

Hetzner is one of the best-kept secrets for developers and entrepreneurs who need affordable, powerful cloud servers. Their pricing is excellent, the performance is solid, and their dashboard is clean and simple. I use it to spin up lightweight production environments, staging servers, and internal tools.

πŸ› οΈ What We’ll Set Up

  • A clean Ubuntu server on Hetzner
  • Secure server configuration: SSH, firewall, non-root user
  • Docker + Docker Compose installation
  • Portainer for easy container management via GUI
  • Nginx Proxy Manager for HTTPS and domain-based routing
  • Future-ready setup for multiple apps

1. πŸ”§ Provisioning a New VPS on Hetzner

  1. Create an Account: console.hetzner.cloud
  2. Create a New Project and add an SSH key.
  3. Create a Server:
    • Image: Ubuntu 24.04
    • Type: CX22 or higher (CX31 for heavier apps)
    • Location: closest to your users
  4. Choose SSH key login only. Avoid password-based logins.

2. πŸ” Initial Security Setup

SSH into your server as root:

ssh root@your.server.ip

Now secure the basics:

πŸ§‘β€πŸ’» Create a non-root user

adduser tariq
usermod -aG sudo tariq'

πŸ” Harden SSH

Edit the config:

sudo nano /etc/ssh/sshd_config

Make sure the following are set:

PermitRootLogin no
PasswordAuthentication no

Then reload SSH:

sudo systemctl reload sshd

πŸ”₯ Set up basic firewall

sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status


3. 🐳 Install Docker + Docker Compose

sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Enable Docker:

sudo systemctl enable docker
sudo usermod -aG docker tariq

Logout and log back in to apply group changes.

4. πŸ“¦ Install Portainer (Optional but Recommended)

docker volume create portainer_data

docker run -d \
  -p 9000:9000 -p 9443:9443 \
  --name=portainer \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

Then visit: https://your.server.ip:9443 to finish setup.

5. 🌐 Set Up Domain + HTTPS with Nginx Proxy Manager

docker volume create npm_data
docker volume create npm_letsencrypt

docker run -d \
  --name npm \
  -p 80:80 -p 81:81 -p 443:443 \
  -v npm_data:/data \
  -v npm_letsencrypt:/etc/letsencrypt \
  --restart always \
  jc21/nginx-proxy-manager:latest

Access NPM admin at http://your.server.ip:81. Default login:

  • Email: admin@example.com
  • Password: changeme

You can now add your domains, configure HTTPS, and reverse proxy traffic to your apps running in Docker.

🧱 Folder Structure and GitOps (Optional)

I recommend organizing your apps like this:

/opt/apps/
  β”œβ”€β”€ app1/
  β”‚   └── docker-compose.yml
  β”œβ”€β”€ app2/
  β”‚   └── docker-compose.yml

Version-control this folder using Git (private repo), and maintain infrastructure as code.

πŸ”„ Next Steps

Once the server is up and secure with Docker, Portainer, and NPM, you’re ready to deploy your stack:

  • 🧾 Zammad for helpdesk
  • 🧠 Outline for internal docs
  • πŸ€– n8n for automation
  • 🧰 Custom Rails or Node apps


πŸ’‘ Final Thoughts

Running your own infrastructure isn’t as intimidating as it seems β€” and the flexibility, cost savings, and control are totally worth it. Whether you’re a startup founder, indie hacker, or just like to tinker, a Hetzner VPS with Docker is a powerful foundation for anything you want to self-host.

Let me know what you’re self-hosting β€” and feel free to reach out if you’re curious about how I run mine behind the scenes.

Leave a comment:

Comments (0)