Benji Visser

Forja: An Ephemeral Docker Builder

If you've ever run docker buildx build --platform linux/amd64 on an M-series Mac, you've probably noticed it's painfully slow.

This is because your M-series Mac is using ARM and under the hood Docker uses QEMU to emulate the AMD64 architecture. As soon as your build touches compiler-related packages like rustc, clang, or gcc — which happens when you're building Python wheels with C extensions or installing native Node modules — things slow down dramatically.

You end up staring at the same Docker step for 20 minutes wondering what the f*ck is happening.

And there isn’t really a great way to make it faster. There are other emulators, Rosetta exists, and I've found its slightly faster then QEMU, but it still sucks.

Most people either accept the slowdown or switch to remote builders like Depot. Depot builds images on the hardware you're targeting and uses large machines, so it's fast.

But I didn’t love the markup on Depot, and I wanted to try vibe-coding something myself.

Enter Forja.

Forja means forge in Spanish. It forges your Docker images on large remote builders and runs entirely inside your own AWS account

Features

Forja builds your images on real hardware in your AWS account instead of relying on emulation. You can choose any EC2 instance size you want. It spins up c7a for AMD64 builds and c7g for ARM builds.

Every build runs on a fresh EC2 instance. When the build finishes, the machine terminates. There are no persistent builders, no servers to maintain, and no idle compute sitting around. If a build fails or the CLI exits early, the instance still cleans itself up. I've tuned startup using custom AMIs built with Packer so instances launch in about 5 seconds and are ready to accept builds in roughly 30 seconds.

The Forja cli will use mutual TLS (mTLS)** to communicate with a remote Forja builder. For every build, the CLI generates a temporary certificate authority and issues a client certificate for the CLI and a server certificate for the builder and stores it in S3. Both sides authenticate each other before any build data is transferred. This avoids SSH access, long-lived credentials, or exposed build endpoints, and the certificates disappear when the instance terminates.

Because build machines are ephemeral, their disks disappear when the instance shuts down. To keep builds fast, Forja stores BuildKit cache layers in S3. It's inexpensive and durable. Hell, people are building entire databases on it! It allows new builders to reuse cache layers from previous builds even though each machine starts clean.

Try It

If you're tired of painfully slow Docker builds on an M-series Mac, give Forja a try.

https://github.com/noqcks/forja

I'd love to hear what you think.