Title: GitHub Actions runner image layout in a VM per job
URL: https://codemany.com/features/vm-per-job
Description: Codemany can give each Linux job its own KVM virtual machine, laid out like GitHub's runner image, with Docker and sudo. The VM is thrown away after.
All pages as Markdown: https://codemany.com/llms.txt

---

[Home](https://codemany.com/) › [Features](https://codemany.com/features)

# A fresh Linux VM for every job

On Linux, Codemany can run each job in its own KVM virtual machine, laid out like the GitHub Actions runner image. The VM has Docker and sudo, and it is thrown away when the job ends.

VM mode is opt-in. Setup picks host mode, which is faster. You turn VM mode on with one command.

## Why a VM per job

In host mode, the default, jobs run right on the machine. That is fast, and caches stay warm. But a job can read your files. It gets no sudo. Docker works only if Docker is installed.

A VM per job changes that. Each job boots its own clean VM. When the job ends, the VM is thrown away. Nothing carries over to the next job, cloud credentials included.

## Laid out like GitHub's runner image

Each VM is built from Ubuntu 24.04. It puts things where GitHub's runner images do:

- The tool cache is at `/opt/hostedtoolcache`.
- The workspace is at `/home/runner/work`.
- Jobs run as a `runner` user.

Scripts that expect those paths find them. Moving off `ubuntu-latest` GitHub Actions jobs is one line: `runs-on: [self-hosted, Linux, codemany]`.

It is not a copy of GitHub's full image, though. The image has git, curl, build-essential, Python 3 and Docker. Add more packages when you build it, with `--packages a,b`.

## Docker and sudo inside the job

Every VM has Docker and passwordless sudo, like GitHub's hosted runners. So `docker build`, `docker compose` and `sudo apt-get install` just work. Runners in VM mode always carry the `docker` label.

Docker vs VM: a container shares the machine's kernel. A VM has its own. That is why a VM keeps a job further away from your machine. For Docker inside a job, see [Docker in Docker on GitHub Actions](https://codemany.com/articles/github-actions-docker-in-docker).

## How to turn it on

1. Check for KVM
   Run `ls /dev/kvm`. If it is missing, VM mode can't run here.
2. Install the helper
   This is a one-time step that needs sudo.
3. Build the image
   Build the VM image once.
4. Turn on VM mode
   Switch the machine to `vm`, then check it.

```
ls /dev/kvm
sudo codemany system-setup --user "$USER" --user-isolation
codemany isolation vm-image
codemany isolation vm
codemany isolation status
```

To go back, run `codemany isolation host`. Changing modes restarts the background service and stops running jobs. More in the [Linux runner guide](https://codemany.com/docs/guides/linux-runner).

## Host mode vs VM mode

|  | Host (default) | VM (opt-in) |
| --- | --- | --- |
| Speed | Fastest, warm caches | Slower: each job boots a VM |
| sudo | No | Yes, passwordless |
| Docker | Only if installed | Always |
| Your files | Jobs can read them | Kept out of the VM |
| Needs KVM | No | Yes |

Not sure which to pick? Read [Runner security](https://codemany.com/docs/guides/runner-security).

## What you need

- A 64-bit Linux machine with systemd and KVM. See [Linux runners](https://codemany.com/features/linux-runners).
- On a cloud machine, nested virtualization. On Google Cloud, that means an N2-family size.
- Room for the VMs. Each one gets its own memory and disk, so fewer jobs fit at once.

Get Codemany for Linux on the [Linux page](https://codemany.com/linux).

## Questions

### Is VM mode on by default?

No. Setup picks host mode. Turn VM mode on with `codemany isolation vm`.

### Where do tools and the workspace live?

In `/opt/hostedtoolcache` and `/home/runner/work`, like GitHub's image.

### Does it need KVM?

Yes. The Linux machine needs KVM for a VM per job. On a cloud machine, that means nested virtualization.

## Related

Read next: [Linux runners](https://codemany.com/features/linux-runners), the [Linux runner guide](https://codemany.com/docs/guides/linux-runner), [Runner security](https://codemany.com/docs/guides/runner-security), [Docker in Docker](https://codemany.com/articles/github-actions-docker-in-docker) and [Codemany for Linux](https://codemany.com/linux).

Codemany is $20 a month for 2 machines. Try it free for 14 days, with no card.

[Start a 14-day trial](https://codemany.com/docs/get-started)
