service "worker" has neither an image nor a build context specified: invalid
compose project means that service in your Compose file has no
image: and no build: key, so Compose has nothing to create its
container from. Add one of the two to the named service.
Use image: to run an existing image, or build: pointing at the
folder that holds the service's Dockerfile. If you think the key is there, check that it
sits under the service the message names.
The error
PS> docker compose config --quiet
service "worker" has neither an image nor a build context specified: invalid compose project
The file that produced it:
name: fix8-cli-c6
services:
web:
image: alpine
command: ["sleep", "1"]
worker:
command: ["echo", "work"]
depends_on:
- web
Why it happens
Every container starts from an image. A Compose service says where that image comes from
in one of two ways: image: names one to pull or use from the local cache,
and build: tells Compose to build one from a folder. The file itself is
valid YAML; the missing image is a problem of the project as a whole, which can be built
from several files. In the test, a second file holding only
services: worker: image: alpine made the same broken file valid:
PS> docker compose -f compose.yaml -f compose.override-image.yaml config --quiet
That command printed nothing and exited with 0. So the message can also mean that an
override file meant to supply the image was not passed. A service copied from another
file without its image: line, or with build: commented out,
gives it too.
The fix
name: fix8-cli-c6
services:
web:
image: alpine
command: ["sleep", "1"]
worker:
image: alpine
command: ["echo", "work"]
depends_on:
- web
PS> docker compose -f compose.fixed.yaml config --quiet
PS> docker compose -f compose.fixed.yaml up
worker-1 | work
With image: alpine on worker, the project validates, both
containers start and the worker prints its line (the up output is trimmed to
that line). For a service built from your own code,
write build: ./worker (a folder with a Dockerfile). In a second test with
both image: fix8-cli-img:6 and build: ./worker, Compose first
tried to pull the name, printed pull access denied for fix8-cli-img, then
built the folder; afterwards docker images fix8-cli-img:6 listed the built
image under that name.
How it was reproduced
Docker Desktop on Windows 11, engine 29.9.2, Docker Compose v5.6.1, Windows PowerShell
5.1, the cached alpine:latest image. A two-service compose.yaml
whose second service had only command and depends_on gave the
message above on both config and up; adding
image: alpine fixed it. The project name fix8-cli-c6 is the
test's own.
Frequently asked
- What does has neither an image nor a build context specified mean?
- The named service in your Compose file has no image key and no build key, so Compose cannot tell what to start. Add image: with an image name or build: with the folder that holds its Dockerfile.
- Can a docker compose service have both image and build?
- Yes. In this test Compose v5.6.1 first tried to pull the image name, failed because no such repository existed, then built the build folder and tagged the result with the name given in image.
- Why does docker compose say invalid compose project and not the line number?
- The file passes the schema check. The missing image is found later, when Compose assembles the project from all its files, so there is no single line to point at.
More decoded errors in the Fixes category. When the
missing piece is a service name in depends_on, see
depends on undefined
service.