Earthly Review 2026: CI/CD Build Tool That Actually Works Everywhere
Honest review of Earthly after using it for Docker-based builds across GitHub Actions, GitLab CI, and local development. What it solves and where it falls short.
Earthly promises to solve the "it works on my machine" problem for CI/CD builds by making your build process a first-class, reproducible artifact. After using it on two production projects over 6 months, here's what I actually think.
What Earthly Is
Earthly is a build tool that combines Dockerfile-like syntax with Makefile-like targets. You write an Earthfile, and Earthly runs it in a container — giving you reproducibility across local dev and CI environments.
# Earthfile
VERSION 0.8
build:
FROM golang:1.22-alpine
WORKDIR /app
COPY go.mod go.sum .
RUN go mod download
COPY . .
RUN go build -o bin/server ./cmd/server
SAVE ARTIFACT bin/server /server AS LOCAL ./bin/server
docker:
FROM alpine:3.19
COPY +build/server /server
ENTRYPOINT ["/server"]
SAVE IMAGE myapp:latest
test:
FROM +build
RUN go test ./...
lint:
FROM golangci/golangci-lint:v1.57
WORKDIR /app
COPY . .
RUN golangci-lint run
all:
BUILD +test
BUILD +lint
BUILD +dockerRun locally:
earthly +allSame command in GitHub Actions, GitLab CI, or Jenkins. The build runs inside a container on every platform.
What's Actually Good
Local = CI Parity
This is the main value prop and it genuinely works. When a developer runs earthly +test locally, they get the exact same environment as CI. No more "CI uses Ubuntu 22 but my Mac runs on something different" debugging.
# .github/workflows/ci.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Earthly Build
uses: earthly/actions-setup@v1
- run: earthly +all
env:
EARTHLY_TOKEN: ${{ secrets.EARTHLY_TOKEN }}That's it. Same earthly +all command as local.
Caching Works Well
Earthly caches at the layer level (like Docker) but across targets. If go mod download didn't change, it's cached — even when you change application code.
deps:
FROM golang:1.22-alpine
WORKDIR /app
COPY go.mod go.sum .
RUN go mod download # cached as long as go.mod doesn't change
SAVE IMAGE
build:
FROM +deps # reuses cached deps layer
COPY . .
RUN go build -o bin/server ./cmd/serverWith remote caching (Earthly Cloud or self-hosted), this cache is shared across your whole team and CI runners:
earthly --remote-cache=registry.example.com/myapp/cache +buildMulti-Platform Builds
Earthly makes cross-platform builds (arm64/amd64) straightforward:
docker-multiplatform:
BUILD --platform=linux/amd64 --platform=linux/arm64 +dockerMonorepo Support
For monorepos, Earthly shines. You can reference targets across projects:
# services/api/Earthfile
VERSION 0.8
FROM DOCKERFILE .
build:
COPY +../../shared/proto/proto /proto
RUN protoc --go_out=. /proto/*.proto
RUN go build ./...What's Not Great
Learning Curve for Complex Builds
The Earthfile syntax is its own language. Teams used to pure Dockerfiles or shell scripts take time to adapt. Complex conditional logic is awkward.
Earthly Cloud Cost
The remote caching and satellite (faster builds) features require Earthly Cloud, which is paid. The free tier is generous for small teams, but it's an additional SaaS dependency.
You can self-host the cache with:
earthly --remote-cache=your-registry/cache:earth +targetBut it requires more setup than using Earthly Cloud.
Docker Daemon Required
Earthly requires Docker to be running. In some restricted CI environments (serverless, rootless), this is a problem. BuildKit-based alternatives like Dagger don't have this requirement.
Debugging Is Harder Than Docker
When a build fails inside Earthly, the error context can be less clear than a plain Dockerfile. You lose the interactive shell experience you'd get with docker build.
Earthly vs Alternatives
| Earthly | Dagger | Pure Docker/Makefile | GitHub Actions | |
|---|---|---|---|---|
| Reproducibility | Excellent | Excellent | Good | Poor (runner env varies) |
| Learning curve | Medium | Medium-High | Low | Low |
| Local dev support | Excellent | Excellent | Good | Poor |
| Language | Earthfile | Go/Python/TS SDK | Shell/Makefile | YAML |
| Caching | Excellent (layer-based) | Excellent | Manual | With setup |
| Docker required | Yes | No | Yes | Depends |
Real-World Performance
On a Go microservice with ~15k lines of code:
| Build step | Before Earthly | After Earthly (warm cache) |
|---|---|---|
go mod download | 45s per CI run | 2s (cached) |
go build | 60s | 15s (partial cache) |
golangci-lint | 90s | 8s (cached) |
| Total | ~3m 30s | ~35s |
Those numbers are realistic when the remote cache is warm. First run after a dependency change is slower.
My Verdict
Score: 7/10
Earthly genuinely solves the local/CI parity problem and the caching is excellent. If your team has complained about "works locally but fails in CI" more than twice, Earthly is worth evaluating.
The tradeoff is another tool to learn and maintain. For simple pipelines or teams that prefer YAML, GitHub Actions caching with Docker BuildKit achieves 80% of what Earthly does with less adoption friction.
Use Earthly if:
- You have complex multi-stage builds
- You want local dev to match CI exactly
- You're in a monorepo with multiple services
Skip Earthly if:
- Your builds are simple (Dockerfile + 3 steps)
- Your team has low appetite for new tooling
- You're in a rootless or restricted CI environment
Earthly docs | Dagger (alternative worth evaluating)
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Build a DevSecOps Pipeline from Scratch (2026 Project Walkthrough)
A complete end-to-end DevSecOps pipeline with SAST, container scanning, secrets detection, DAST, and supply chain security using open-source tools.
Build a Docker CI/CD Pipeline with GitHub Actions and AWS ECR (2026)
Step-by-step guide to building a production CI/CD pipeline that builds, scans, and pushes Docker images to AWS ECR using GitHub Actions.
Dagger vs Earthly vs GitHub Actions: Which CI Tool Actually Solves Your Problems?
GitHub Actions is everywhere but Dagger and Earthly are challenging it hard. Here's an honest comparison of all three — performance, portability, learning curve, and when to use each.