GitHub Actions or GitLab CI deploys over SSH

You deploy with a CI job over SSH to servers you list by IP. The webhook adapter keeps that job: Hetscale tells it where the new server is, the job deploys, the load balancer decides when the node may serve. The GitHub Actions page has the relay and both workflows, built from the Hetscale Deploy action.

Prerequisite work
deploy to the IP Hetscale sends
Time to set up
1–2 h
Adapter
Webhook
Fit
8/10

Prerequisites, time and fit are this case's row in the onboarding cases table. Hetscale's own setup is about 15 minutes in every case; the rest is work on your side.

Steps

  1. 01
    Receive node.created

    Hetscale sends a signed node.created event with the node id, its IPs, the group and the current release when a server is booted and reachable. Deliveries carry a delivery_id; a retry repeats the same delivery_id and body, so a duplicate is safe once your receiver stores the ids it has seen.

  2. 02
    Run your deploy against that IP

    Start your workflow with the node id: the Hetscale Deploy action reads the server’s address and release from the inventory, so the dispatch is never trusted for them. GitHub’s workflow_dispatch still needs a small relay in front of it, and the GitHub Actions page of the docs has one. Your SSH key stays in your CI; Hetscale never holds it.

  3. 03
    Report ready or failed

    Report ready when the deploy is done: only then does Hetscale add the node to your load balancer, and traffic opens when its health check passes. A failed report stops the node at once.

  4. 04
    Hold the deploy lock during your own rollouts

    The action’s steps do it: lock, record the release, read the servers (which first waits for servers that started on the earlier release), your deploy, report the servers deployed, unlock. A failed server is still replaced meanwhile.

  5. 05
    Observe, rehearse, go Live

    Read-only trial first; after release v1, pick the project’s SSH keys for new servers if your job logs in as root; then one Rehearsal, which exercises the webhook end to end; then Live with minimum 2.

FAQ for this case

What if my pipeline never reports back?

The node never joins your load balancer. After the deadline (default 15 minutes) it is destroyed and logged, and three consecutive failures pause the group. The Rehearsal shows this before you go Live.

We have no load balancer yet.

Then this is the “CI/SSH deploy, no load balancer” row of the fit table: add the Hetzner load balancer first (TLS to it, DNS to it) and teach the pipeline the IP. Two to three hours, fit 6.

See what Hetscale would have done with your real data — connect read-only, get your report in minutes.

Connect read-only