Skip to content

Hetzner ​

Hetzner Cloud provides cost-effective virtual machines and storage in European and US data centres. It's an excellent choice for VM-based deployments where you need more control than managed platforms offer.

Authentication ​

Set your Hetzner Cloud API token as an environment variable:

bash
export HCLOUD_TOKEN="your-token"

Generate a token at console.hetzner.cloud under your project's Security → API Tokens.

Virtual machines ​

Hetzner VMs (called "servers") offer excellent price-to-performance ratio for self-managed deployments.

Configuration ​

json
{
  "apps": [
    {
      "name": "api",
      "type": "golang",
      "path": "./apps/api",
      "infrastructure": {
        "provider": "hetzner",
        "type": "vm",
        "config": {
          "size": "cx22",
          "location": "nbg1",
          "image": "ubuntu-22.04"
        }
      }
    }
  ]
}

Server types ​

Hetzner offers shared (CX) and dedicated (CCX/CPX) CPU options:

Shared vCPU (CX series) ​

TypevCPUsMemoryStorageMonthly cost
cx2224GB40GB~€4
cx3248GB80GB~€7
cx42816GB160GB~€14
cx521632GB320GB~€29

Dedicated vCPU (CCX series) ​

TypevCPUsMemoryStorageMonthly cost
ccx1328GB80GB~€13
ccx23416GB160GB~€25
ccx33832GB240GB~€50
ccx431664GB360GB~€100

ARM64 (CAX series) ​

TypevCPUsMemoryStorageMonthly cost
cax1124GB40GB~€4
cax2148GB80GB~€6
cax31816GB160GB~€12
cax411632GB320GB~€24

ARM servers offer excellent value for compatible workloads.

Locations ​

CodeLocationRegion
nbg1NurembergGermany
fsn1FalkensteinGermany
hel1HelsinkiFinland
ashAshburnUSA East
hilHillsboroUSA West

Images ​

ImageDescription
ubuntu-22.04Ubuntu 22.04 LTS
ubuntu-24.04Ubuntu 24.04 LTS
debian-12Debian 12 (Bookworm)
rocky-9Rocky Linux 9
fedora-40Fedora 40

SSH configuration ​

WebKit configures SSH access to Hetzner VMs. Ensure your SSH public key is available:

json
{
  "infrastructure": {
    "provider": "hetzner",
    "type": "vm",
    "config": {
      "ssh_keys": ["your-key-name"]
    }
  }
}

SSH keys are managed at the Hetzner project level.

Volumes ​

Hetzner Volumes provide additional block storage for your VMs.

Configuration ​

json
{
  "resources": [
    {
      "name": "data",
      "type": "volume",
      "provider": "hetzner",
      "config": {
        "size": 100,
        "location": "nbg1",
        "format": "ext4"
      }
    }
  ]
}

Volume sizes ​

Volumes range from 10GB to 10TB. Pricing is ~€0.05/GB/month.

SizeMonthly cost
10GB~€0.50
50GB~€2.50
100GB~€5
500GB~€25
1TB~€50

Mount points ​

Volumes are automatically attached to the associated VM. Configure the mount point:

json
{
  "config": {
    "mount_point": "/data"
  }
}

WebKit configures the VM to mount the volume at boot.

Outputs ​

OutputDescription
data.idVolume ID
data.sizeVolume size in GB
data.mount_pointMount path on VM

Networking ​

Private networks ​

Enable private networking between VMs:

json
{
  "infrastructure": {
    "provider": "hetzner",
    "type": "vm",
    "config": {
      "network": {
        "enabled": true,
        "ip_range": "10.0.0.0/24"
      }
    }
  }
}

VMs in the same network can communicate over private IPs.

Firewalls ​

Configure firewall rules:

json
{
  "config": {
    "firewall": {
      "rules": [
        {
          "direction": "in",
          "protocol": "tcp",
          "port": "22",
          "source_ips": ["0.0.0.0/0"]
        },
        {
          "direction": "in",
          "protocol": "tcp",
          "port": "80",
          "source_ips": ["0.0.0.0/0"]
        },
        {
          "direction": "in",
          "protocol": "tcp",
          "port": "443",
          "source_ips": ["0.0.0.0/0"]
        }
      ]
    }
  }
}

Deployment ​

Unlike managed platforms, Hetzner VMs require deployment configuration. WebKit generates:

  • Ansible playbooks for initial setup
  • GitHub Actions workflows for deployment
  • Docker configuration for containerised apps

Ansible provisioning ​

WebKit generates Ansible playbooks to configure your VM:

  • Install Docker and required packages
  • Configure firewall rules
  • Set up SSL certificates (Let's Encrypt)
  • Deploy your application

Run provisioning:

bash
webkit infra apply  # Creates VM
# Ansible runs automatically via GitHub Actions

Manual deployment ​

For manual deployments, SSH into your VM:

bash
ssh root@your-vm-ip
cd /opt/app
docker compose pull
docker compose up -d

Example: Self-hosted application ​

A Go API deployed on Hetzner with attached storage:

json
{
  "project": {
    "name": "my-api",
    "title": "My API",
    "repo": "github.com/myorg/my-api"
  },
  "apps": [
    {
      "name": "api",
      "type": "golang",
      "path": "./apps/api",
      "build": {
        "dockerfile": true,
        "port": 8080
      },
      "infrastructure": {
        "provider": "hetzner",
        "type": "vm",
        "config": {
          "size": "cx22",
          "location": "nbg1",
          "image": "ubuntu-22.04"
        }
      },
      "domains": {
        "primary": "api.example.com"
      }
    }
  ],
  "resources": [
    {
      "name": "uploads",
      "type": "volume",
      "provider": "hetzner",
      "config": {
        "size": 50,
        "location": "nbg1",
        "mount_point": "/data/uploads"
      }
    }
  ]
}

Comparison with DigitalOcean ​

FeatureHetznerDigitalOcean
Managed appsNoYes (App Platform)
VM pricingLowerHigher
Managed DBNoYes
European locationsExcellentGood
US locations2Many
ARM serversYesNo
Setup complexityHigherLower

Choose Hetzner when:

  • Cost is a priority
  • You need ARM servers
  • You're comfortable with VM management
  • Your users are primarily in Europe

Choose DigitalOcean when:

  • You want managed services
  • Simplicity is important
  • You need managed databases
  • Your users are globally distributed

Further reading ​

Released under the MIT Licence.