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
runneruser.
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.
How to turn it on
Check for KVM
Run
ls /dev/kvm. If it is missing, VM mode can't run here.Install the helper
This is a one-time step that needs sudo.
Build the image
Build the VM image once.
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.
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.
What you need
- A 64-bit Linux machine with systemd and KVM. See 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.
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, the Linux runner guide, Runner security, Docker in Docker and Codemany for Linux.
Codemany is $20 a month for 2 machines. Try it free for 14 days, with no card.