Skip to content

Repository files navigation

Runxr

Runxr is a completely free, self-hosted CI/CD app. It runs on your own laptop or server: your GitHub token, build logs, queue, and database stay with you.

There is no Runxr subscription, no paid database, and no paid hosting requirement. You only need a free GitHub account, Node.js, Python, Git, and Docker for the secure default build runner.

What Runxr does

GitHub push → signed webhook → Runxr queue → isolated runner → live logs → result + optional alert
  1. You sign in with GitHub and choose a repository.
  2. Runxr installs a push webhook when a public URL is configured.
  3. A push creates a persistent build job.
  4. Your local runner clones the repository and executes runxr.yml in Docker.
  5. The dashboard shows the live log and final result. Failed jobs can be retried.

What is included

  • GitHub OAuth sign-in and repository connection
  • Signed GitHub push webhooks
  • SQLite-backed jobs, logs, teams, encrypted GitHub tokens, and audit history
  • Live logs, retry controls, build status, and notifications
  • Docker-first runner with CPU, memory, PID, and network limits
  • Teams and shared repository visibility
  • Free local setup, diagnostics, and in-app documentation

Free setup requirements

Install these free tools:

Cloudflare Tunnel can expose your local app for free while testing webhooks. Its free quick URL changes whenever the tunnel restarts. A stable custom URL needs a domain you control, but Runxr itself remains free either way.

First-time setup

1. Get the code

git clone https://github.com/furyengi/runxr.git
cd runxr
npm install

2. Run the guided setup

npm run setup
npm run doctor

npm run setup creates the private .env file and generates unique secrets. Do not commit .env or share its contents.

The questions mean:

Setting What to enter
Allowed GitHub owner Your GitHub username, for example furyengi. Leave blank only for local testing.
Public HTTPS URL Your tunnel or deployed address. Leave blank until you expose Runxr.
OAuth callback URL http://localhost:4000/auth/github/callback locally, or https://your-url/auth/github/callback when public.
Client ID / secret Values from the GitHub OAuth App you create next.

3. Create a GitHub OAuth App

In GitHub, open Settings → Developer settings → OAuth Apps → New OAuth App.

  • Application name: Runxr on my laptop
  • Homepage URL: http://localhost:4000 (or your public URL)
  • Authorization callback URL: exactly the callback URL from your .env

Create the app, generate a client secret, then run npm run setup again to save the Client ID and client secret. Each Runxr installation should use its own OAuth App and secrets.

4. Start the API

npm test
npm run dev

Open http://localhost:4000, select Connect GitHub, approve access, and you will arrive at the dashboard.

Start the secure runner

Open a second terminal from the Runxr project:

cd runxr-runner
python -m pip install -r runner/requirements.txt
docker build -t runxr-job-executor -f Dockerfile.job ..
python agent.py

The runner automatically reads the parent project’s .env. It uses Docker by default. Check it with:

npm run doctor

If Docker is unavailable, you may set RUNXR_EXECUTION_MODE=host only for repositories you fully trust. Host mode runs repository commands directly on the computer.

Connect a repository and build

  1. In the dashboard, select Browse repositories.
  2. Select Connect next to a repository you own or can administer.
  3. Add a runxr.yml file to that repository:
steps:
  - name: Install
    run: npm ci
  - name: Test
    run: npm test
  - name: Build
    run: npm run build
  1. Push the file after you finish the webhook setup below.

The runner executes steps in order. A non-zero command stops the job and marks it as failed.

Receive GitHub push events for free

GitHub must reach your Runxr API. For a free temporary URL, install cloudflared and run this in another terminal:

cloudflared tunnel --url http://localhost:4000

Copy the generated https://…trycloudflare.com URL, run npm run setup, and enter it as the public HTTPS URL. Use this callback URL in your GitHub OAuth App:

https://your-trycloudflare-url/auth/github/callback

Restart npm run dev, sign in again, then reconnect the repository in the dashboard. Runxr will attempt to create the push webhook automatically.

If you create it manually in GitHub instead, use:

  • Payload URL: https://your-public-url/webhook/github
  • Content type: application/json
  • Secret: the value of RUNXR_WEBHOOK_SECRET in .env
  • Events: Just the push event

Keep the API, runner, and tunnel processes running while you use Runxr. The free quick-tunnel address changes after a restart, so update .env, the OAuth callback, and the repository webhook when it changes.

Dashboard guide

  • Build jobs: status, live logs, and failed-job retry.
  • Connected repositories: add repositories allowed to create Runxr jobs.
  • Teams: create a local team, add GitHub usernames, and share a connected repository’s Runxr history.
  • Notifications: reports whether optional Slack/email adapters are configured.
  • Audit history: records sign-in, sign-out, repository connection, webhook-created jobs, and retries.
  • Docs: opens this guide from either the landing page or dashboard.

Optional free integrations

Runxr works without notifications. To enable them, add these private values to .env and restart the API:

RUNXR_SLACK_WEBHOOK_URL=
RUNXR_RESEND_API_KEY=
RUNXR_NOTIFICATION_EMAIL=

Slack and email providers determine whether their own free tiers are suitable for you. These integrations are optional; no Runxr feature requires a paid account.

Backups, upgrades, and safety

  • Back up data/runxr.sqlite while the API is stopped. It contains the local job history, encrypted GitHub tokens, team data, and audit trail.
  • Keep .env private. Rotate the GitHub OAuth secret and Runxr secrets if they are exposed.
  • Use Docker mode and keep RUNXR_JOB_NETWORK=none unless a trusted build genuinely needs network access.
  • Never connect or run untrusted repositories in host mode.
  • After updating the code, run npm install, npm test, and npm run doctor before restarting the API and runner.

Troubleshooting

Problem Fix
GitHub OAuth is not configured Run npm run setup and enter the OAuth Client ID and secret.
GitHub callback fails Ensure the OAuth App callback URL exactly matches RUNXR_GITHUB_CALLBACK_URL.
Push does not create a job Keep the tunnel/API running; reconnect the repository; verify its webhook URL and secret.
Runner cannot claim a job Ensure the runner reads the same .env and RUNXR_RUNNER_TOKEN matches.
Docker runner fails Start Docker Desktop and build the runxr-job-executor image.
Dashboard is empty Sign in, connect a repository, start the runner, and push a commit containing runxr.yml.

API reference

Endpoint Purpose
GET /health Service health check.
GET /auth/github Starts GitHub sign-in.
POST /auth/logout Signs out.
POST /webhook/github Receives signed push webhooks.
GET /jobs Lists your/team jobs.
POST /jobs/:id/retry Retries a failed job.
GET /logs/:id/stream Streams live logs.
GET /audit Lists your audit history.

Runner-only endpoints require X-Runxr-Runner-Token.

About

ci/cd runner

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages