Skip to content

Hetzner.Server reference

Source: src/Hetzner/Image.ts

A Hetzner Cloud custom Image — a snapshot (or backup) of a Server’s disk. Stock system/app Images (ubuntu-24.04, …) are Catalog lookups via Hetzner.findImage, not this resource.

Snapshots are created with POST /servers/{id}/actions/create_image and billed per GB. Description, labels, delete protection, and backup→snapshot conversion update in place. Changing the source Server replaces the Image.

Snapshot from a Server

const server = yield* Hetzner.Server("web", {
serverType: "cx22",
image: "ubuntu-24.04",
location: "nbg1",
});
const image = yield* Hetzner.Image("golden", {
server,
description: "golden-web",
labels: { role: "golden" },
});

Snapshot with generated description

const image = yield* Hetzner.Image("backup", {
server: { serverId: 42 },
});
const image = yield* Hetzner.Image("golden", {
server,
description: "golden-web-v2",
labels: { role: "golden", env: "prod" },
deleteProtection: true,
});

Source: src/Hetzner/PlacementGroup.ts

A Hetzner Cloud Placement Group. Spread groups keep member Servers on distinct physical hosts so a single hardware failure cannot take them all down. Type is spread (the only type Hetzner currently offers) and is immutable — changing it replaces the group. Name and labels update in place.

Servers are attached from the Server resource (not here).

PlacementGroup: Creating a Placement Group

Section titled “PlacementGroup: Creating a Placement Group”

Basic spread group

const group = yield* Hetzner.PlacementGroup("web");

Named group with labels

const group = yield* Hetzner.PlacementGroup("web", {
name: "web-spread",
type: "spread",
labels: { role: "web" },
});

Source: src/Hetzner/Server.ts

A Hetzner Cloud Server — a virtual machine in a Location, created from a Server type and an Image. serverType, image, and location are immutable (changing any of them replaces the Server). Name, labels, delete protection, and (when set) Networks / Firewalls / Volumes / Placement Group update in place. SSH keys are injected only at create.

Basic Server

const server = yield* Hetzner.Server("web", {
serverType: "cpx12",
image: "ubuntu-24.04",
location: "nbg1",
});

Named Server with labels

const server = yield* Hetzner.Server("web", {
name: "app-web",
serverType: "cpx12",
image: "ubuntu-24.04",
location: "nbg1",
labels: { role: "web" },
});
const key = yield* Hetzner.SshKey("deploy", {
publicKey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… user@host",
});
const group = yield* Hetzner.PlacementGroup("web");
const server = yield* Hetzner.Server("web", {
serverType: "cpx12",
image: "ubuntu-24.04",
location: "nbg1",
sshKeys: [key],
placementGroup: group,
});

Install packages on first boot

const server = yield* Hetzner.Server("web", {
serverType: "cpx12",
image: "ubuntu-24.04",
userData: `#!/bin/bash
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y nginx
systemctl enable --now nginx`,
});

cloud-config document

const server = yield* Hetzner.Server("web", {
serverType: "cpx12",
image: "ubuntu-24.04",
userData: `#cloud-config
packages:
- nginx
- postgresql-client`,
});

userData is merged with Alchemy’s own bootstrap script into a multipart cloud-init document, so both run. It is applied on first boot only — changing it replaces the Server.

Source: src/Hetzner/Ssh.ts

SSH exec/scp against a Hetzner Server. Uses the Server’s Alchemy-managed deploy key (injected at create) unless privateKey is passed.

Exec a command

const ssh = yield* Hetzner.Ssh(server);
const { stdout } = yield* ssh.exec("uname -a");

Copy a file

const ssh = yield* Hetzner.Ssh(server);
yield* ssh.scp("/tmp/app.zip", "/opt/app/bundle.zip");

Source: src/Hetzner/SshKey.ts

A Hetzner Cloud SSH key. Public keys are injected into Servers at create time. The public key is immutable — changing it replaces the key.

Generated name

const key = yield* Hetzner.SshKey("deploy", {
publicKey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… user@host",
});

Explicit name and labels

const key = yield* Hetzner.SshKey("deploy", {
name: "deploy-key",
publicKey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI… user@host",
labels: { role: "deploy" },
});