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:
- GitHub shows the job completed with the expected runner name and labels.
- Velnor shows the job/run and corresponding events or logs.
- 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:
- GitHub workflow: confirm the job uses the exact Velnor labels and the configured repository.
- Eligibility: confirm the runner is online and the backend/slot is ready.
- Connectivity: inspect
systemctl statusandjournalctl; authentication, broker, and run-service failures are not idle polls. - Delivery: confirm Velnor events show broker polling and job receipt.
- Admission: unsupported actions, trust scope, capabilities, or routing can reject a job before checkout or credentials.
- Execution: run
velnorctl preflightand inspect backend-specific errors. - 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.