Velnor Documentation

Getting started

Getting started

This is the shortest path from a Debian host to a GitHub Actions job executed by Velnor.

Velnor is research software, not a production-readiness guarantee. Use a dedicated host and a repository whose jobs you are prepared to run on it.

1. Prepare a Debian host

Use a supported Debian system with systemd, outbound HTTPS access to GitHub, and sufficient disk, CPU, and memory for the selected jobs. Install the host tools required by the package and backend:

sudo apt-get update
sudo apt-get install -y ca-certificates curl git util-linux systemd

Choose one execution backend before starting Velnor. There is no fallback.

For Docker, install and start the Debian package, then verify the daemon and socket:

sudo apt-get install -y docker.io
sudo systemctl enable --now docker
sudo docker info
sudo test -S /var/run/docker.sock

For MicroVM, no separate Firecracker download is supported by this tree. The Velnor .deb ships the pinned Firecracker, jailer, kernel, root filesystem, and guest agent. The host must expose KVM; verify the packaged artifacts after installation:

test -c /dev/kvm
sudo test -x /usr/share/velnor/microvm/firecracker
sudo test -x /usr/share/velnor/microvm/jailer
sudo test -s /usr/share/velnor/microvm/vmlinux
sudo test -s /usr/share/velnor/microvm/rootfs.ext4

2. Install the real release artifact

Velnor currently builds .deb files and publishes them as GitHub Release assets at github.com/tailrocks/velnor/releases. This repository does not contain APT signing-key bootstrap or APT repository setup metadata. Therefore this is the only acquisition path documented here: download the exact velnor-runner-VERSION-ARCH.deb and matching .sha256 asset from that release, then verify it. Do not use an unverified binary.

sha256sum --check velnor-runner-VERSION-ARCH.deb.sha256
sudo install -d -m 0750 /run/velnor
sudo /usr/bin/flock --exclusive --nonblock --no-fork \
  /run/velnor/package-transaction.lock \
  apt-get install ./velnor-runner-VERSION-ARCH.deb

Replace VERSION and ARCH with the downloaded asset names. Releases also publish SHA256SUMS; use it when present to verify the complete asset set. Direct dpkg -i and unlocked package transactions are rejected. Package installation does not enable or start services.

3. Configure scope, backend, and credentials

Edit the shipped configuration:

sudoedit /etc/velnor/velnor.env
sudoedit /etc/velnor/execution.toml

Minimum settings in velnor.env:

VELNOR_URL=https://github.com/OWNER/REPO
VELNOR_NAME=velnor
VELNOR_LABELS=velnor,velnor-target-mvp
VELNOR_SLOTS=1
VELNOR_WORK_DIR=/var/lib/velnor/work
VELNOR_TRUST_SCOPE=trusted
VELNOR_CAPABILITY_VALIDATION=strict

Set exactly one backend in execution.toml:

[execution]
backend = "docker"

Use microvm instead only when the host satisfies the KVM and artifact requirements.

Keep the operator personal access token (PAT) separate from ordinary configuration:

sudo install -m 0600 /dev/null /etc/velnor/secrets.env
sudoedit /etc/velnor/secrets.env

Put this in the file:

GITHUB_TOKEN=YOUR_OPERATOR_PAT

The token must authorize runner registration for the configured repository, organization, or enterprise and any selected runner group. Never put it in a unit argument or workflow file.

4. Configure organization or enterprise scope (if applicable)

Repository scope needs only VELNOR_URL set to the repository URL. For an organization or enterprise URL, GitHub requires an explicit runner group; Velnor refuses the implicit Default group. Set the stable group name and, when known, its numeric GitHub group ID:

VELNOR_POOL_NAME=velnor-trusted
VELNOR_POOL_ID=GROUP_ID
VELNOR_ROUTING_POLICY_FILE=/etc/velnor/ORG-routing-policy.json

The policy file must be operator-provided JSON containing non-empty group, selected_repositories, labels, and trust_scope. Its values must exactly match GitHub’s live group/repository/label/trust evidence. Live membership is evidence, not the allowlist. The daemon resolves VELNOR_POOL_NAME through GitHub before requesting each per-slot JIT configuration; no pre-registration command is needed.

5. Start and check health

Start the guardian first, then the daemon and periodic doctor:

sudo systemctl enable --now velnor-guardian.service
sudo systemctl enable --now velnor-daemon.service
sudo systemctl enable --now velnor-doctor.timer

Check process state and Velnor health:

systemctl is-active velnor-guardian.service velnor-daemon.service
velnorctl status --json
velnorctl get runners --output wide
velnorctl get slots --output wide
velnorctl preflight --config-dir /etc/velnor --work-dir /var/lib/velnor/work

Healthy is more than an active PID: the daemon must have a writable state store, valid routing, a ready backend, and available capacity. Confirm the runner is online in GitHub before testing a workflow. If configuration changes, use sudo systemctl restart velnor-daemon.service.

6. Target Velnor from a workflow

Add a minimal job to a test workflow in the configured repository:

name: Velnor smoke test

on: workflow_dispatch

jobs:
  smoke:
    runs-on: [self-hosted, velnor, velnor-target-mvp]
    steps:
      - run: |
          echo "runner=$RUNNER_NAME"
          echo "workspace=$GITHUB_WORKSPACE"
          uname -a

The labels must match the configured runner. GitHub selects eligible runners; Velnor does not assign jobs from the REST queued-job listing. Trigger the workflow manually.

7. Verify the first job end to end

Watch GitHub until the job leaves queued, then inspect Velnor while it runs:

velnorctl get jobs --output wide
velnorctl get runs --output wide
velnorctl events --limit 100
velnorctl telemetry --limit 100

After completion, verify all three sides:

  1. GitHub shows the job completed with the expected runner name and labels.
  2. Velnor shows the job/run and corresponding events or logs.
  3. The workflow output contains the smoke-test lines and the job is not merely reported as successful by a local process.

For service-level evidence, use:

sudo journalctl -u velnor-daemon.service -u velnor-guardian.service -n 200 --no-pager

If the first job does not run

Diagnose in order:

  1. GitHub workflow: confirm the job uses the exact Velnor labels and the configured repository.
  2. Eligibility: confirm the runner is online and the backend/slot is ready.
  3. Connectivity: inspect systemctl status and journalctl; authentication, broker, and run-service failures are not idle polls.
  4. Delivery: confirm Velnor events show broker polling and job receipt.
  5. Admission: unsupported actions, trust scope, capabilities, or routing can reject a job before checkout or credentials.
  6. Execution: run velnorctl preflight and inspect backend-specific errors.
  7. Reporting: compare local events/logs with GitHub job state and completion.
velnorctl logs job-1 --tail 200

Replace job-1 with the exact job UID shown by velnorctl get jobs --output wide. velnorctl logs accepts one concrete job or run subject.

For the complete lifecycle and recovery behavior, continue to the operator guide, observability guide, and architecture.