Run your own worker

Join a worker to Ciresk CI: your own machine, a Linux box at home, WSL2, or an instance in your cloud account.

A worker only calls out, over HTTPS, to the cell and its object store; nothing connects to it. Your worker runs the tasks, but the tree they run on, their logs, artifacts and cache entries still travel through presigned URLs into the cell's own object store in the EU. What a worker is and which tasks it may run is in Workers and trust.

Enrol and join

Two steps, the same everywhere:

  1. Create a one-time enrolment secret from any machine with a token that has ci:workers.admin:

    ciresk ci workers enrol --name office-box

    --expires-in 1h bounds the secret; --factory <id> names a pool instead of static. The secret is printed once and not stored by the CLI; a lost secret means a new enrol.

  2. Join on the worker host, as root:

    The worker host
    sudo ciresk-ci-worker join https://ci.eu.ciresk.com cwe_...

join writes /etc/ciresk-ci/worker.toml, registers the worker with its labels and exchanges the secret for a worker token (valid 24 hours and renewed by the worker, scoped to this worker only) in /var/lib/ciresk-ci/state.json (mode 0600); the secret is used once and not stored. The server URL is the cell, https://ci.eu.ciresk.com.

ciresk ci workers list

Your own machine

The shortest path to a fast ciresk ci check: your own Linux machine (or a PC under WSL2) runs the worker with warm workspaces, joined to Ciresk CI. No port, no public address, no VPN.

  1. Create an enrolment secret from any machine: ciresk ci workers enrol --name <host>.

  2. Install, join and start on the host:

    Linux and WSL2
    curl -fsSL https://get.ciresk.com/ci | sh -s -- --worker --enrol cwe_... --name <host>

    This installs ciresk into ~/.ciresk/bin, then runs the worker installer with sudo. The installer verifies the binary against the release's checksums.txt (and its minisign signature when minisign is installed), installs /usr/local/bin/ciresk-ci-worker, creates the ciresk-run account tasks run as and the ciresk-toolchains account toolchain installs run as, installs a pinned mise, writes the systemd unit, joins and starts the unit. It runs on Linux only, the host needs cc, make and git, and it is safe to run again (--version <tag> moves to a release). --slots, --labels, --idle-stop and --secrets are passed to the worker installer too.

  3. ciresk ci workers list shows it online; the next ciresk ci check from any repository of your organization may land on it.

On a host where you are already signed in (ciresk ci auth login), ciresk ci workers add does all of it, enrolment included.

Linux with systemd, by hand

  1. Download ciresk-ci-worker-linux-x86_64 or ciresk-ci-worker-linux-aarch64 and checksums.txt from https://get.ciresk.com/worker/<tag>/ (the current tag is in https://get.ciresk.com/ci/latest/VERSION), check the sha256, and install it at /usr/local/bin/ciresk-ci-worker.

  2. Install git and mise; create the unprivileged user tasks run as: useradd --system --create-home ciresk-run, and the one toolchain installs run as: useradd --system --no-create-home --home-dir /var/lib/ciresk-ci/mise --shell /usr/sbin/nologin ciresk-toolchains. A root worker downloads toolchains only to the hosts /etc/ciresk-ci/egress.yaml lists for product ci-worker; without that file every toolchain download is refused.

  3. Install the unit:

    /etc/systemd/system/ciresk-ci-worker.service
    [Unit]
    Description=Ciresk CI worker
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    ExecStart=/usr/local/bin/ciresk-ci-worker run
    Restart=always
    RestartSec=5
    KillMode=mixed
    TimeoutStopSec=150
    Environment=PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    Environment=RUSTUP_HOME=/var/lib/ciresk-ci/mise/rustup
    Environment=CARGO_HOME=/var/lib/ciresk-ci/mise/cargo
    
    [Install]
    WantedBy=multi-user.target
  4. ciresk-ci-worker join https://ci.eu.ciresk.com cwe_..., then systemctl enable --now ciresk-ci-worker.

  5. journalctl -fu ciresk-ci-worker shows registration and the first lease; curl 127.0.0.1:9471/healthz answers {"state": "online", ...}.

The service runs as root because it creates per-task scopes under another uid, manages cgroups and may stop the host; every task runs as run_user (ciresk-run) with CPU and memory caps, and state.json is the only root-held file.

A Linux box at home, over Tailscale

A machine behind a home router or an office firewall needs no public DNS, no port forwarding and no static address: the worker only calls out. Tailscale is how you reach the box to install and operate it, not something the worker needs.

  1. Install Tailscale on the box and on your laptop; sudo tailscale up on both. The box becomes <machine>.<tailnet>.ts.net.
  2. From the laptop, ssh <machine> (or tailscale ssh <machine>), then the install and join steps above.
  3. The box fetches its first lease within seconds; journalctl -fu ciresk-ci-worker shows it.
  4. ciresk ci workers list from the laptop lists the box with its name, state (online, draining, offline), version, slots in use and last heartbeat.

What that box gives you:

PropertyDetail
Warm workspacesWith warm_workspaces = true (the default) the first ciresk ci check from a repository creates its workspace under /var/lib/ciresk-ci/workspaces/warm/<repo_id>/; every later job updates it in place and keeps target/, node_modules/ and the other workspace.keep globs.
Who may use itOnly your organization's jobs, and by default only trusted_interactive and trusted_ci ones; untrusted work (fork PRs) does not land on it unless you label it disposable.
Auto-updateWith auto_update = true (the default) the worker downloads the version the server wants between two jobs, verifies the release directory's signature under the Ciresk release key compiled into it (no key to configure, nothing can replace it) and restarts; it never moves to an older release than the one it runs.
Idleidle_stop_secs = 0 (never) is the default for a static host; the box stays up and costs nothing to the cell when idle.
What reaches the boxThe task lease (command, hashed env values, presigned URLs for your organization's prefix); never another organization's data, never the cell's database.

Windows and WSL2

ShapeHow
WSL2 (Ubuntu or any systemd-enabled distribution)Set systemd=true in /etc/wsl.conf, then follow the Linux steps inside the distribution. Keep the workspaces on the Linux filesystem (/var/lib/ciresk-ci), never under /mnt/c. Cgroup CPU and memory caps apply inside the WSL VM.
Native WindowsNot available yet: worker releases are Linux only. Run the worker under WSL2.

A WSL2 worker is a static worker with isolation: process: the Windows host can read the Linux filesystem and there is no VM per job, so it serves your own organization's interactive and CI work and refuses untrusted tasks.

In your own AWS account

Any EC2 instance with a public address and no inbound rules works like an office box with the steps above: the worker calls out over 443 and needs no NAT gateway.

Updates

SettingBehavior
auto_update = true (default)Registration and every heartbeat return the version the server wants; the worker finishes its current task, downloads the signed binary from the release directory (release_url), verifies the signature under the compiled-in release key and the trusted comment ciresk-ci-worker v<version>, swaps the binary and restarts. A wanted version older than the running one is logged and never installed.
auto_update = falseThe worker logs the wanted version and keeps running; you replace the binary yourself.
CompatibilityServer and worker accept protocol versions N and N-1, so they upgrade in any order; a worker two versions behind is refused at registration with the upgrade hint.

Every setting of worker.toml is in Configuration.