6 ms·
Show HN: Managed GitHub Actions Runners for AWS
Hey HN! I'm Jacob, one of the founders of Depot (https://depot.dev https://depot.dev), a build service for Docker images, and I'm excited to show what we’ve been working on for the past few months: run GitHub Actions jobs in AWS, orchestrated by Depot!
Here's a video demo: https://www.youtube.com/watch?v=VX5Z-k1mGc8 https://www.youtube.com/watch?v=VX5Z-k1mGc8, and here’s our blog post: https://depot.dev/blog/depot-github-actions-runners https://depot.dev/blog/depot-github-actions-runners.
While GitHub Actions is one of the most prevalent CI providers, Actions is slow, for a few reasons: GitHub uses underpowered CPUs, network throughput for cache and the internet at large is capped at 1 Gbps, and total cache storage is limited to 10GB per repo. It is also rather expensive for runners with more than 2 CPUs, and larger runners frequently take a long time to start running jobs.
Depot-managed runners solve this! Rather than your CI jobs running on GitHub's slow compute, Depot routes those same jobs to fast EC2 instances. And not only is this faster, it’s also 1/2 the cost of GitHub Actions!
We do this by launching a dedicated instance for each job, registering that instance as a self-hosted Actions runner in your GitHub organization, then terminating the instance when the job is finished. Using AWS as the compute provider has a few advantages:
- CPUs are typically 30%+ more performant than alternatives (the m7a instance type).
- Each instance has high-throughput networking of up to 12.5 Gbps, hosted in us-east-1, so interacting with artifacts, cache, container registries, or the internet at large is quick.
- Each instance has a public IPv4 address, so it does not share rate limits with anyone else.
We integrated the runners with the distributed cache system (backed by S3 and Ceph) that we use for Docker build cache, so jobs automatically save / restore cache from this cache system, with speeds of up to 1 GB/s, and without the default 10 GB per repo limit.
Building this was a fun challenge; some matrix workflows start 40+ jobs at once, then requiring 40 EC2 instances to launch at once.
We’ve effectively gotten very good at starting EC2 instances with a "warm pool" system which allows us to prepare many EC2 instances to run a job, stop them, then resize and start them when an actual job request arrives, to keep job queue times around 5 seconds. We're using a homegrown orchestration system, as alternatives like autoscaling groups or Kubernetes weren't fast or secure enough.
There are three alternatives to our managed runners currently:
1. GitHub offers larger runners: these have more CPUs, but still have slow network and cache. Depot runners are also 1/2 the cost per minute of GitHub's runners.
2. You can self-host the Actions runner on your own compute: this requires ongoing maintenance, and it can be difficult to ensure that the runner image or container matches GitHub's.
3. There are other companies offering hosted GitHub Actions runners, though they frequently use cheaper compute hosting providers that are bottlenecked on network throughput or geography.
Any feedback is very welcome! You can sign up at https://depot.dev/sign-up https://depot.dev/sign-up for a free trial if you'd like to try it out on your own workflows. We aren't able to offer a trial without a signup gate, both because using it requires installing a GitHub app, and we're offering build compute, so we need some way to keep out the cryptominers :)
- cocoflunchy 3y agoHalf the price of github is not great right now, this space is heating up! Ubicloud is 10x cheaper and https://runs-on.com https://runs-on.com is in the same ballpark by using spot instances. (Currently switching to RunsOn)
- jacobwg 3y agoYeah, I think our goal is to be the fastest at building software, not necessarily the cheapest. Part of that involves AWS, to have access to more powerful and elastic infrastructure, but that comes at a premium. But besides just compute, I think the bigger long-term unlock for build performance is a new distributed compute engine, to free build workloads from single machines. We've started building this for our container build product, and plan to integrate Actions jobs as an input as well, starting with the cache integration we have today.
- SOLAR_FIELDS 3y agoOne of the most interesting value adds for me is not any of the things mentioned by OP. I would like to have a managed hosted runner solution where I can have a buildkit cache also in the same data center that I manage where I don’t have to pay ingress/egress to that cache but also I don’t have to manage my own runner infra. I have done the whole self hosted Karpenter + Actions Runner Controller thing to achieve this and it is a lot of work to set up and tune to get right. The problem is actually really that GitHub’s caching offering is very limited for anything except the most basic of use cases and also they don’t offer a way to colo your own cache with them so that you aren’t paying cloud fees back and forth. You have to use their machines, their storage and their protocol which is only really viable if your definition of caching is literally just “upload files here” and “check if the uploaded built file already exists”. Yes, I’m aware that buildkit offers “experimental” GHA caching support. But given how fat image layers are it’s basically unusable for anything beyond a toy project that builds a couple layers on top of an alpine image (as of the time of writing this post GHA limits cache size to 10gb per repo. Fine if you’re building npm or pypi packages or whatever, but hilariously inadequate for buildkit layer caching)
- 3y ago