Title: Cloud machines · Codemany docs
URL: https://codemany.com/docs/machines/cloud
Description: Let Codemany create a runner machine on Google Cloud, Hetzner or DigitalOcean: how to add one, how seats and the provider's bill work, idle stop and spending caps, how it stays closed to the internet, and how to remove it.
All pages as Markdown: https://codemany.com/llms.txt

---

[Machines](https://codemany.com/docs#machines)

# Cloud machines

Codemany can create a runner machine on a cloud provider for you and add it to your fleet, with no SSH by hand. It runs your jobs from GitHub, joins the fleet and takes one machine seat. Nothing is opened to the internet.

## Providers

[**Google Cloud**Sign in with Google, then name a project. Idle stop on by default.](https://codemany.com/docs/machines/cloud/google-cloud) [**Hetzner**A project API token with Read & Write. Prices in EUR.](https://codemany.com/docs/machines/cloud/hetzner) [**DigitalOcean**A personal access token with ten custom scopes.](https://codemany.com/docs/machines/cloud/digitalocean) [**AWS**Coming in the next release: a dedicated IAM user's access key.](https://codemany.com/docs/machines/cloud/aws) [**Azure**Coming in the next release: sign in with Microsoft.](https://codemany.com/docs/machines/cloud/azure)

## Add a cloud machine

1. Open the dialog
   In the Mac app, open **Machines** and choose **Add a Cloud Machine…**. In the dashboard, open **Machines** and choose **Add a cloud machine** (the dashboard needs the admin token for it: `codemany admin-token`). Both open the same dialog.
2. Pick a provider and connect its account
   Each provider's page says exactly what to create. A pasted token is checked with one read call before it is kept.
3. Choose a region and a size
   Prices are the provider's own list, for a machine running all month, shown before you confirm. Sizes that hold at least one runner are listed cheapest first, and the cheapest x86 one is preselected. The size marked Recommended is the cheapest x86 one with 4 vCPUs and 16 GB (two runners), or one that can give each job a fresh VM when it costs at most a quarter more.
4. Name it and choose what it serves
   One of this machine's repositories or organizations, optional extra runner labels, idle stop and a monthly spending cap.
5. Create
   The button names the monthly price. If every machine seat is in use, the dialog names the price of one more and adds it only when you agree.

A size runs one job per 2 vCPUs and 4 GB of memory, with 4 GB kept for the system: 4 vCPUs and 16 GB run 2 jobs at a time.

## What happens when you create one

1. The app makes an SSH key and a host key for the machine, and asks the provider for it, with Ubuntu 24.04.
2. On first boot, cloud-init installs Codemany from the apt repository after checking the signing key's fingerprint, and firewalls the dashboard to the machine itself.
3. Codemany connects over SSH, takes the machine's seat, sets it up (dashboard on localhost only, each runner as its own user), starts the service and pairs it with your fleet through the SSH link.
4. The machine shows under Machines › Cloud machines: **Creating**, then **Installing Codemany and joining the fleet**, then **Running** or **Stopped (no jobs)**.

Manage a cloud machine from the machine that created it. Other members see it, but only its creator holds the SSH link to open it.

## Billing and seats

A cloud machine has two bills:

- **The provider's**, for the machine itself, on your own account at Google Cloud, Hetzner or DigitalOcean. Codemany never sees or handles it.
- **Codemany's**: the machine takes one machine seat of its repository owner's subscription, like any other machine. **$20/month includes 2 machines**, and **each extra machine is $10/month**.

With every seat in use, the dialog names the price of one more seat and adds it only when you agree. It is billed on the subscription from then on, and removed again when you remove the machine. Only the subscription's payer or an admin can add a seat. See [Licensing and seats](https://codemany.com/docs/account/billing).

## Idle stop and spending caps

- **Idle stop.** Codemany stops the machine after 15 minutes with no queued or running job for its labels, and starts it again when one queues. It watches the jobs it already polls, so it makes no extra GitHub requests; the machine must serve one of this machine's repositories. It is on by default only where a stopped machine is cheaper: on Google Cloud, a stopped machine bills only its disk.
- **Spending cap.** A monthly cap per machine warns at 80% and stops the machine at 100%, until next month. The Machines page shows each machine's spend this month against its cap.

**Hetzner and DigitalOcean bill a stopped machine in full.** Idle stop and a cap can't lower that bill, so the dialog doesn't offer a cap there: remove the machine to stop paying for it.

A machine that failed while being created may still bill. It stays listed, held to its cap, until you remove it.

## Security

- **Only SSH is open.** Port 22 with key-only login, using a key made for that machine. The dashboard's ports (TCP 8825 to 8835, UDP 8825) are dropped on every interface but loopback, on every boot. Setup happens over SSH and is never served.
- **A pinned host key.** The app makes the machine's host key and pins it on every connection, the first one included: no trust on first use.
- **No port on your machine.** Codemany reaches the cloud machine's dashboard through the SSH link, inside its own process. Nothing listens locally that another user or a CI job could use.
- **Jobs kept apart.** Each runner runs as its own user, and jobs can't reach the cloud's metadata service over HTTP. The machine's setup data carries no secret but its host key; the GitHub token goes over SSH.
- **Credentials stay with you.** Provider tokens and Google sign-ins are kept in the Mac Keychain or the Linux keyring, never in a file, and never sent to Codemany's servers. A Linux machine whose vault is a file refuses to store them.
- **Only its own machines.** Whatever the credentials can see, Codemany only starts, stops, deletes or reads machines carrying its tag (the label `codemany=managed`; on DigitalOcean the tag `codemany-managed`).

The full threat model is in the [security model](https://codemany.com/docs/security#cloud-machines).

## Remove a cloud machine

Choose **Remove…** next to the machine. The confirmation names what stops: "Delete *name* on *provider*? Its disk and everything on it are deleted, and its monthly cost stops." Then **Delete machine**:

1. The machine is deleted at the provider first.
2. Its runners are removed from GitHub.
3. Its machine seat is freed, and a seat added for it is removed from the subscription.
4. It leaves the fleet, and its SSH key is forgotten.

A machine still being created can't be removed; one that failed can. If a step fails part way, removing again resumes where it stopped.

## Providers compared

|  | Google Cloud | Hetzner | DigitalOcean |
| --- | --- | --- | --- |
| Arm sizes | T2A | CAX | none |
| A fresh VM per job | N2 sizes | no (Cloud servers) | no |
| A stopped machine bills | the disk only | in full | in full |
| Idle stop by default | on | off | off |
| Spending cap | yes | no | no |
| Prices in | USD, list prices | EUR, VAT included where charged | USD |
| Access Codemany gets | Compute Engine, read-only billing prices, optionally a read-only project list | the whole project | ten custom scopes |

## Set one up by hand instead

You can also create a VM yourself on any provider, install Codemany and reach it over an SSH tunnel: see [A cloud VM](https://codemany.com/docs/machines/linux-server#cloud) in the Linux server guide. Codemany doesn't stop or remove a machine it didn't create.

[Previous Linux server](https://codemany.com/docs/machines/linux-server)[Next Google Cloud](https://codemany.com/docs/machines/cloud/google-cloud)
