Deploy a self-hosted CI runner
Deploy a self-hosted CI runner
Stand up a GitHub Actions or GitLab CI runner on a Quake AI instance for automated builds, tests, and deployments. CI jobs are memory-intensive; configure swap on small tiers before you register the runner.
Monthly cost estimate
Pricing calculator ↗Sized as a custom package on shared vCPU.
Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.
What each resource is for
s1a.small
s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps
Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.
Included in baseline
s1a.small
2 shared vCPU, 2 GiB RAM, 0.5 Gbps
Compute + RAM rate basis
2 vCPU + 2 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.
Package promotional discount
Flat −$5.00/mo on the custom package (same promotion as named plans).
Included at no charge
These line items are zero on Quake AI. Many other providers meter them separately.
Data transfer (inbound and outbound)
Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.
AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.
Learn morePrivate networking
Private networks, subnets, Neutron routers, and security groups are included with the plan.
VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.
Control-plane API requests
OpenStack API calls for provisioning and management are included.
Some managed services on other clouds meter API calls or charge for premium control-plane features.
Pricing data last validated: . For current rates, check quake.ai/pricing.
Prerequisites#
- An SSH key pair uploaded to your account
- A running instance with swap configured, or follow Launch your first server and the swap step in Deploy a containerized web application
- A GitHub or GitLab account with admin access to the repository or project where you want to register the runner
Option A: GitHub Actions runner#
Step 1. Configure swap#
If you have not already, add swap (essential for CI workloads):
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstabStep 2. Download and configure the runner#
Go to your GitHub repository > Settings > Actions > Runners > New self-hosted runner. GitHub shows architecture-specific commands. For Linux x64:
mkdir -p ~/actions-runner && cd ~/actions-runner
# Resolve the latest runner version from the GitHub API, then download it.
RUNNER_VERSION=$(curl -fsSL https://api.github.com/repos/actions/runner/releases/latest \
| grep -oP '"tag_name":\s*"v\K[^"]+')
curl -o actions-runner-linux-x64.tar.gz -L \
"https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz"
tar xzf actions-runner-linux-x64.tar.gz
rm actions-runner-linux-x64.tar.gzRegister the runner with the token from your repository settings. This configuration step is required before Step 3: it generates the svc.sh service script the next step uses, so do not skip it:
./config.sh \
--url https://github.com/YOUR_ORG/YOUR_REPO \
--token YOUR_REGISTRATION_TOKEN \
--name rumble-dev-runner \
--labels quake-ai,developer-plan \
--work _workStep 3. Install as a service#
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh statusThe runner is now registered and waiting for jobs.
Step 4. Target the runner in workflows#
In your .github/workflows/*.yml, use the runs-on label to target this runner:
jobs:
test:
runs-on: [self-hosted, quake-ai]
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm testOption B: GitLab Runner#
Step 1. Configure swap#
Same as GitHub Actions: see Step 1 above.
Step 2. Install GitLab Runner#
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | \
sudo bash
sudo apt install -y gitlab-runnerStep 3. Register the runner#
Go to your GitLab project > Settings > CI/CD > Runners > New project runner to get a registration token. Then register:
sudo gitlab-runner register \
--url https://gitlab.com/ \
--token YOUR_REGISTRATION_TOKEN \
--executor shell \
--description "rumble-dev-runner" \
--tag-list "quake-ai,developer-plan"Step 4. Verify the runner#
Check the runner status:
sudo gitlab-runner status
sudo gitlab-runner listTarget the runner in .gitlab-ci.yml:
test:
tags:
- quake-ai
script:
- npm ci
- npm testMemory management for CI#
On the Developer Plan, CI jobs compete for the same 1 GB of RAM. Follow these practices:
- Run one job at a time: set
--concurrency 1for GitLab Runner, or only register one GitHub runner. - Avoid Docker-in-Docker: the
shellexecutor uses less memory than launching containers per job. - Limit Node.js memory if running JavaScript builds:
export NODE_OPTIONS="--max-old-space-size=384"- Monitor during builds: SSH in and run
htoporfree -hwhile a job runs to see peak usage. - Use lightweight jobs: linting, unit tests, and small compiles work well. Large Docker image builds or complete test suites may need OpenClaw Starter or Basic.
When to upgrade#
The Developer Plan runner is good for:
- Small projects with lightweight CI (lint, test, deploy scripts)
- Personal projects where build speed is not critical
- Trying out self-hosted runners before committing to larger infrastructure
Upgrade to OpenClaw Starter (4 GiB RAM, 4 shared vCPUs) or Basic (16 GiB RAM, 4 dedicated vCPUs) when you need:
- Docker-based CI with image builds
- Parallel job execution
- Large dependency trees or monorepo builds
- Consistent, fast build times
Next steps#
- How to deploy an application to a Quake AI VM from CI: push builds from GitHub Actions or GitLab CI to this runner
- How to deploy to a Quake AI Kubernetes cluster from CI: same pattern for Magnum clusters
- How to integrate OpenTofu with CI/CD: provision infrastructure in the pipeline before app deploy
- Deploy a containerized web application: add Docker-based builds
- Automate your infrastructure with OpenTofu: automate runner provisioning
- Resource tiers: compare plan capabilities
Clean up#
Deregister the runner from your repository settings, stop the systemd service (sudo ./svc.sh stop for GitHub Actions or sudo gitlab-runner unregister for GitLab), and delete the instance when finished.
See also#
- How to store application secrets and inject them at runtime: keep registry tokens and deploy keys out of workflow YAML
- Instances concepts
- Security groups concepts
Quick answers
- Why does `openstack image save` write a 0-byte file for my boot-from-volume instance?CLI
- Why does `openstack server create` fail with "Only volume-backed servers are allowed for flavors with zero disk"?CLIAPITerraform
- Why does my project still have a 10 GiB Cinder volume after I deleted my instance?CLIAPI