💻 Coding
Earthly Earthfile Multi-Stage from a Service Brief (Version-Locked Images, No Invented Bases)
Write a multi-stage Earthfile from a service brief. Lock base images and versions in Inputs. Do not invent tags or registries.
0Reviews
Prompt
Act as an Earthly Earthfile author who only uses a pasted service brief. You write a multi-stage Earthfile with VERSION, deps, build, and a runtime image. You do not invent base image names, tags, or registries. This is not a Dockerfile-only dump, not a Buildah script, and not a docker-compose file. You work only from Inputs. Do not invent stats, citations, quotes, URLs, names, IDs, or records that are not in Inputs. Inputs: - Service brief (language, entrypoint, ports I allow): [Brief] - Base images I lock with exact tags: [Images] - Earthly VERSION I lock (or UNKNOWN): [Earthly] - Build targets I allow: [Targets] - Words I must not use: [Banned] - What I must never invent (tags, registries, ports): [Never] - Output format: [Format] - Language for comments: [Lang] - Package versions I lock (or NONE): [Packages] Generate: 1. Honesty ledger: Brief nouns, Images, Earthly, Targets, Packages, Lang. Forbidden: invented tags, invented registries, extra ports. 2. Image lock table: each Images line quoted. If a stage needs an image not listed, write NOT IN INPUTS rather than picking alpine:latest. 3. Earthfile body: VERSION from Earthly or VERSION UNKNOWN. Targets only. Copy only paths named in Brief. 4. Runtime: EXPOSE only ports in Brief. USER only if Brief names a user. HEALTHCHECK only if Brief names one. 5. Refuse list: Dockerfile FROM without Earthly targets, docker-compose services, Buildah bud, invented SHA256 digests. 6. Packages: quote Packages or write NONE. Do not add a pinned apk add line that is not locked. 7. Never: do not write :latest. Do not invent ghcr.io or ecr URLs. 8. Compliance pass: quote Banned and Never hits. Cut them. Format as Format. Constraints: - Earthfile from Brief and Images only. Not a Dockerfile-only dump and not compose. - Never invent base image names, tags, or registries. - Only Targets named in Inputs. - No emojis.
Instructions
Replace every [bracket] with your details before running. Works on ChatGPT, Claude, and Gemini.
Examples
Example Input
Brief: Go HTTP service; module path example.com/mailer; entrypoint cmd/mailer; listen 8080 as pasted; copy go.mod go.sum and cmd/mailer only; no CGO; no user name pasted; no HEALTHCHECK pasted. Images: golang:1.23.2-bookworm (deps+build); gcr.io/distroless/base-debian12:nonroot (runtime). Do not invent alpine. Earthly: 0.8 Targets: +deps +build +docker Banned: latest, alpine, ubuntu, scratch (unless locked), apt-get upgrade Never: invent image tags, invent a registry host, invent port 443, invent a digest Format: ledger + lock-table + Earthfile + refuse + gaps Lang: English comments Packages: NONE (do not apk add curl)
Example Output
1. Ledger. Go HTTP. Module example.com/mailer. Entrypoint cmd/mailer. Port 8080 as pasted. Copies: go.mod, go.sum, cmd/mailer. CGO off. User NOT IN INPUTS. HEALTHCHECK NOT IN INPUTS. Images: golang:1.23.2-bookworm; gcr.io/distroless/base-debian12:nonroot. Earthly 0.8. Targets +deps +build +docker. Packages NONE. Lang English. Forbidden: latest, alpine, ubuntu, scratch, apt-get upgrade, invented tags, invented registry, port 443, digest, curl.
2. Lock table. deps/build <- golang:1.23.2-bookworm. runtime <- gcr.io/distroless/base-debian12:nonroot. alpine:latest NOT IN INPUTS. digest NOT IN INPUTS.
3. Earthfile sketch.
VERSION 0.8
deps:
FROM golang:1.23.2-bookworm
WORKDIR /src
COPY go.mod go.sum .
RUN go mod download
# Packages NONE. No apk add.
build:
FROM +deps
COPY cmd/mailer cmd/mailer
ENV CGO_ENABLED=0
RUN go build -o /out/mailer ./cmd/mailer
SAVE ARTIFACT /out/mailer
docker:
FROM gcr.io/distroless/base-debian12:nonroot
COPY +build/mailer /mailer
EXPOSE 8080
# USER not named in Brief. Do not invent nonroot numeric if not pasted as a USER line.
# HEALTHCHECK NOT IN INPUTS.
ENTRYPOINT ["/mailer"]
SAVE IMAGE mailer:local
4. Runtime. EXPOSE 8080 only. Port 443 refused. HEALTHCHECK omitted.
5. Refuse. Dockerfile-only FROM chain without targets: refused (this job is Earthfile). docker-compose.yml: refused. buildah bud: refused. sha256:abcd: refused.
6. Packages. NONE. curl not added.
7. Never. No :latest. No invented ghcr.io. No alpine.
8. Compliance. Banned hits none. Format ledger+lock-table+Earthfile+refuse+gaps. Gaps: SAVE IMAGE registry, USER numeric, HEALTHCHECK path, go toolchain extra flags, ARG list.
Missing-data policy: if a field was blank, write NOT IN INPUTS rather than guessing. Lock any tool version named in Inputs; if unnamed, write unknown. No invented testimonials, star ratings, or press logos. If legal, clinical, insurance, HR, education-plan, or veterinary content appears, add a one-line not-advice and de-identify banner. Quote banned-word hits and cut them. End with a gaps list of five bullets the user still owes you. Character and byte caps in the job are hard; print counts when relevant. Refuse to backfill DOIs, exam dumps, PHI, PII, or compensation promises not in Inputs.