docker-compose image vs build: Provenance, Not Existence
In docker-compose, both image: and build: end up running an image; the fork is where it comes from. And build.context is mandatory, because COPY resolves relative to it.
Both image: and build: end up running an image; Docker never runs raw source. The fork is where the image comes from:
| Directive | Image source | Local build step? |
|---|---|---|
image: | pulled ready-made from a registry | ❌ |
build.context: | compiled locally from Dockerfile + files | ✅ (first run / --build) |
build.context is mandatory for a build: you cannot “just point at a Dockerfile.” The context is the file tree handed to the daemon; COPY x resolves relative to the context, so no context means nothing to copy from. (dockerfile: only names the recipe; context: is still required.) Use both together to name a locally-built image.
From this session: the ClickHouse services use build: {context: ./clickhouse-portforward} because no prebuilt image bundles gcloud + kubectl + auth-plugin + entrypoint; the Cloud SQL services use image: (the public gce-proxy), so no build.
image:pulls ready-made,build:compiles locally. Both end up running an image; the difference is only provenance.
References
- Docker Compose build reference: https://docs.docker.com/reference/compose-file/build/
- Docker Compose context guide: https://www.baeldung.com/ops/docker-compose-context-guide
Related: back to the remote DB overview; then COPY bakes in, volumes mount live.