Makefiles are not reproducible. Dockerfiles are not composable. Earthly combines both: Dockerfile-like syntax for containerized build steps, Makefile-like targets for composition. Every build runs the same everywhere.
The Problem
Your Makefile works on your machine:
test:
go test ./...
build:
go build -o app .But fails in CI because CI has Go 1.21 and you have 1.22. Or gcc is missing. Or the test database is not running.
Earthly runs every step in a container:
# Earthfile
VERSION 0.8
FROM golang:1.22
WORKDIR /app
deps:
COPY go.mod go.sum .
RUN go mod download
SAVE ARTIFACT go.mod
SAVE ARTIFACT go.sum
test:
FROM +deps
COPY . .
RUN go test ./...
build:
FROM +deps
COPY . .
RUN go build -o app .
SAVE ARTIFACT app AS LOCAL ./app
docker:
FROM alpine:3.19
COPY +build/app /usr/local/bin/app
ENTRYPOINT ["/usr/local/bin/app"]
SAVE IMAGE myorg/myapp:latestearthly +test # Runs tests in a container
earthly +build # Builds binary
earthly +docker # Creates Docker imageSame result on your laptop, in GitHub Actions, in GitLab CI, or on a colleague's machine.
Master this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →Key Concepts
Targets
Targets are like Makefile rules but run in containers:
lint:
FROM golangci/golangci-lint:latest
COPY . .
RUN golangci-lint run
test:
FROM +deps
COPY . .
RUN go test -race ./...
integration-test:
FROM +deps
COPY . .
WITH DOCKER --compose docker-compose.test.yml
RUN go test -tags=integration ./...
ENDArtifacts
Pass files between targets:
build-frontend:
FROM node:20
COPY frontend/ .
RUN npm ci && npm run build
SAVE ARTIFACT dist /frontend-dist
build-backend:
FROM golang:1.22
COPY backend/ .
RUN go build -o server .
SAVE ARTIFACT server /server
docker:
FROM alpine:3.19
COPY +build-frontend/frontend-dist /app/static
COPY +build-backend/server /app/server
ENTRYPOINT ["/app/server"]
SAVE IMAGE myorg/fullstack:latestMulti-Platform
build:
FROM golang:1.22
COPY . .
ARG TARGETARCH
RUN GOARCH=$TARGETARCH go build -o app .
SAVE ARTIFACT app
docker:
BUILD --platform=linux/amd64 --platform=linux/arm64 +buildCI Integration
Earthly works with any CI system — the CI just calls earthly:
# GitHub Actions
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: earthly/actions-setup@v1
- run: earthly +test
- run: earthly +docker --push# GitLab CI
build:
image: earthly/earthly:latest
script:
- earthly +test
- earthly +docker --pushThe CI config is trivial because all build logic lives in the Earthfile.
Get weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Caching
Earthly caches like Docker — each RUN creates a layer. Unchanged layers are reused:
deps:
COPY go.mod go.sum . # Only re-runs if go.mod/go.sum change
RUN go mod download # Cached when dependencies unchanged
build:
FROM +deps # Reuses cached deps
COPY . . # Only invalidated when source changes
RUN go build -o app .Earthly also supports remote cache sharing via registries:
earthly --remote-cache=ghcr.io/myorg/cache +buildEarthly vs Alternatives
| Tool | Reproducible | Composable | Container-native | Learning curve |
|---|---|---|---|---|
| Earthly | Yes | Yes | Yes | Low (Dockerfile-like) |
| Make | No | Yes | No | Low |
| Bazel | Yes | Yes | Partial | High |
| Dagger | Yes | Yes | Yes | Medium (SDK) |
| Docker | Yes | No (single Dockerfile) | Yes | Low |
Earthly hits the sweet spot: reproducible like Bazel, familiar like Docker, composable like Make.
---
Ready to go deeper? Master CI/CD and build automation with hands-on courses at CopyPasteLearn.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Dagger CI/CD Pipelines as Code
Dagger lets you write CI/CD pipelines in real programming languages instead of YAML. Learn how Dagger works, how it compares to GitHub Actions.
Woodpecker CI Self-Hosted Pipelines
Woodpecker CI is a lightweight, container-native CI/CD system you can self-host. Learn how Woodpecker compares to Drone, GitHub Actions, and GitLab CI.
Tekton Cloud Native CI/CD
Tekton runs CI/CD pipelines as Kubernetes custom resources. Learn how Tekton works, how to build pipelines with Tasks and Pipelines, and when to choose it.
Energy-Efficient AI Infrastructure
Build sustainable AI infrastructure with energy-efficient GPU scheduling, green computing practices, carbon-aware workloads, and cooling optimization.
Environment Variables Best Practices
Handle environment variables correctly. Dotenv files, Docker secrets, Kubernetes ConfigMaps, twelve-factor methodology, and security pitfalls.
External Secrets Operator Guide
External Secrets Operator syncs secrets from AWS Secrets Manager, HashiCorp Vault, and Azure Key Vault into Kubernetes Secrets. Learn how to stop committing.
Explore topics
Browse more articles on the topics covered here.