Skip to content

manascb1344/modal-github-runner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Modal GitHub Runner

Modal GitHub Actions License: MIT

A high-performance, ephemeral self-hosted GitHub Actions runner powered by Modal. Achieve zero idle costs and instant horizontal scaling with Just-In-Time (JIT) security.

🚀 Key Features

  • ⚡ Ephemeral: Every job runs in a fresh, hardware-isolated Modal Sandbox, ensuring a clean state and preventing side effects between runs.
  • 💰 Zero Idle Cost: No long-running servers or "warm" instances. You only pay for the exact seconds your runner is executing jobs.
  • 🛡️ JIT Security: Utilizes GitHub's Just-In-Time runner registration. Runners are created on-demand and automatically cleaned up by GitHub after a single use.
  • 📈 Horizontal Scaling: Modal's serverless infrastructure allows you to scale to hundreds of concurrent runners instantly. Each job gets its own dedicated resources without queueing delays.

🏗️ Architecture

The runner follows a reactive, event-driven flow:

sequenceDiagram
    participant GH as GitHub Actions
    participant WE as Modal Web Endpoint
    participant GA as GitHub API
    participant MS as Modal Sandbox
    
    GH->>WE: 1. workflow_job (queued) Webhook
    Note over WE: Verify Signature (HMAC-SHA256)
    WE->>GA: 2. Request JIT Config (generate-jitconfig)
    GA-->>WE: 3. Return JIT Config String
    WE->>MS: 4. modal.Sandbox.create(image, JIT_CONFIG)
    Note over MS: 5. Execute run.sh (as root in /tmp)
    MS->>GH: 6. Connect & Execute Job
    GH-->>MS: 7. Job Finished
    MS->>MS: 8. Exit & Terminate Sandbox
Loading
  1. Workflow Queued: A GitHub Action workflow is triggered and a job enters the queued state.
  2. Webhook Trigger: GitHub sends a workflow_job webhook to the Modal web endpoint.
  3. JIT Handshake: The Modal app validates the request and calls the GitHub API to generate a JIT (Just-In-Time) runner configuration.
  4. Sandbox Spawning: A Modal Sandbox is provisioned immediately with the pre-configured runner image.
  5. Execution & Cleanup: The runner connects to GitHub, executes the specific job, and the Sandbox is terminated immediately upon completion.

🏁 Quick Start

Setting up your own Modal runner takes only a few minutes.

Refer to the DEPLOY.md for step-by-step instructions on:

  • Setting up Modal secrets.
  • Deploying the webhook endpoint.
  • Configuring GitHub repository webhooks.

🛠️ Technical Details

  • Modal Sandbox: Built on top of Modal's serverless runtime, providing sub-second startup times and robust isolation using micro-VM technology.
  • JIT Configuration: Instead of persistent runner tokens, this project uses the generate-jitconfig endpoint. This ensures that even if a runner environment were compromised, the credentials are valid for only one specific job.
  • Custom Images: The runner environment is defined directly within app.py, allowing you to easily add dependencies (e.g., specific versions of Python, Node.js, or system libraries) that are pre-baked into the runner image.
  • Root Execution: Sandboxes run with RUNNER_ALLOW_RUNASROOT=1 in ephemeral /tmp directories, ensuring compatibility with all GitHub Actions features without permission hurdles.

📄 License

This project is licensed under the MIT License.


👤 Author

Manas C. Bavaskar

About

High-performance, ephemeral, and horizontally scalable self-hosted GitHub Actions runners powered by Modal. Pay only for the seconds you run.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages