Hetzner Cloud Provider

Deploy preview environments to Hetzner Cloud via SSH.

How it works

Prerequisites

  1. A Hetzner Cloud account and project.
  2. An SSH key pair — the public key registered in Hetzner, the private key stored in Previewops secrets.

Step 1 — Create a Hetzner API token

  1. Go to your Hetzner Cloud project → Security → API Tokens → Generate API Token.
  2. Select Read & Write permission.
  3. Store the token as HETZNER_API_TOKEN in Previewops secrets.

Step 2 — Register an SSH key in Hetzner

If you need a new key pair:

ssh-keygen -t ed25519 -C "previewops" -f ~/.ssh/previewops-hetzner
  1. Go to your project → Security → SSH Keys → Add SSH Key.
  2. Paste the contents of ~/.ssh/previewops-hetzner.pub.
  3. Give it a name (e.g. previewops) — this becomes sshKeyName in providerConfig.

Store the private key as HETZNER_SSH_KEY in Previewops secrets:

cat ~/.ssh/previewops-hetzner

Step 3 — Store secrets in Previewops

Secret Value
HETZNER_API_TOKEN API token from step 1
HETZNER_SSH_KEY PEM-encoded private key from step 2

Step 4 — Configure the repo

provider: hetzner
providerConfig:
  sshKeyName: previewops   # required — name of SSH key registered in Hetzner (step 2)
  serverType: cx22          # optional (default: cx22)
                            # see: hcloud server-type list
  location: nbg1            # optional (default: nbg1)
                            # options: nbg1, fsn1, hel1, ash, hil, sin
  image: ubuntu-24.04       # optional (default: ubuntu-24.04)

Step 5 — Verify

Comment /validate-previewops on any open PR. The bot calls the Hetzner API and confirms the token and SSH key name are valid.

Notes

Troubleshooting

Error Fix
HETZNER_API_TOKEN env var is required Set the token in secrets
HETZNER_SSH_KEY env var is required Set the private key in secrets
hetzner providerConfig.sshKeyName is required Add sshKeyName to providerConfig
SSH key not found from Hetzner API The name in providerConfig doesn't match the name registered in Hetzner
SSH connection refused Server hasn't finished cloud-init yet — the provider retries automatically