Skip to content
Muxen
Docs · Runners and jobs

Code and CI

Runners and jobs

Install self-hosted runners on your machines, see which ones are busy, and find out why a job isn’t starting.

Muxen installs GitHub Actions runners on your machines and shows them next to everything else running there. It downloads the runner, registers it with GitHub using your gh login, and starts it. You never copy a registration token.

Watch an organization or a repository

Runners register with an organization or a repository. Tell Muxen which ones you use in Settings › GitHub › Watching. It lists your organizations, so watching one is a click. Or from a terminal:

muxen watch acme      # an organization
muxen watch acme/api  # one repository
muxen unwatch acme

For what it watches, Muxen reads each runner’s live status from GitHub, and the queued and running jobs of the most recently pushed repositories. It asks every 20 seconds or so; unchanged answers don’t count against your rate limit.

An organization’s runners need the admin:org permission on your GitHub login. Settings › GitHub says when it’s missing and has a Grant access button. Or run gh auth refresh -h github.com -s admin:org. A repository’s runners need admin access to that repository.

Install runners

On a machine’s page, click Install runner. Pick:

  • Register with: one of the organizations or repositories you watch.
  • How many: up to 16 at once, and their Names if you want your own.
  • Extra labels, such as gpu. GitHub adds self-hosted, the OS and the architecture by itself.
  • Run as: how each runner stays running (below).

Muxen picks the right runner build for the machine, downloads it, registers it and starts it. The progress shows in Activity (⌘J).

Run as

ChoiceWhat it does
AutoThe best fit for the machine: a service where it can, else Docker, else a background process. The default.
ServiceStarts at boot: launchd on macOS, a Windows service, systemd on Linux. On Linux this needs passwordless sudo.
DockerA container per runner that restarts with Docker. No sudo. Jobs are kept apart from the machine.
BackgroundNo root needed, but it stops when the machine restarts.

Docker runners can’t use the machine’s Docker unless you share its socket (--docker-socket from the CLI). That’s root on the machine for every workflow that runs there, so only do it for workflows you trust.

Runner states

Each runner is working (running a job), idle, offline, or unknown. Where the state comes from matters:

  • GitHub: live, for runners in what you watch.
  • The last machine check: whether the runner’s process or service is running, for runners GitHub doesn’t tell Muxen about.

Right-click a runner to Stop, Start or Restart it, Show logs (its newest diagnostic log), open the job it’s running on GitHub, or Remove runner…, which deregisters it from GitHub. A runner that GitHub knows but no machine lists shows up on its own, so you can find and remove leftovers.

Jobs

The Jobs page (⌃2) shows self-hosted jobs that are Queued and Running, with how many runners are busy.

The Jobs page: queued jobs, some with no runner that fits, and running jobs with the runner each is on. The Jobs page: queued jobs, some with no runner that fits, and running jobs with the runner each is on.
A queued job no runner can take is flagged.

Right-click a job to show its runner or Cancel run…. GitHub cancels whole workflow runs, not single jobs, so that stops every job in the run.

When a job doesn’t start

A job waits for an online runner that has all of its labels. When none has, the Jobs page says how many jobs have “no runner that fits”. Usually the fix is one of these:

  1. A runner with the labels is offline. Start it, or check its machine: an offline machine explains every runner on it.
  2. No runner has one of the labels, say gpu. Install one with that label.
  3. The runner is registered to a different organization or repository than the workflow.

For a runner that won’t stay online, Show logs first. See Troubleshooting for unreachable machines.

From the command line

muxen runners [--machine beacon] [--state offline]
muxen jobs
muxen install beacon --count 2 --label gpu
muxen install beacon --scope acme/api --mode docker
muxen runner restart beacon/beacon-01
muxen runner logs beacon/beacon-01
muxen runner remove beacon/beacon-01 [--delete-files]
muxen cancel-run 123456789

Runner ids are <machine>/<runner>, such as beacon/beacon-01. A runner GitHub knows but no machine lists is github/<name>. Runners also live in config.toml under their machine, so Muxen knows what each machine should host.

For GitHub Enterprise Server, point Muxen at your server’s API: muxen settings --api-url https://HOST/api/v3.