Docker Compose "service failed to build" - Diagnose Compose Build Errors
Compose delegates building to the same engine as docker build, so a compose build failure is really a Dockerfile or context problem reported through compose.
What this error means
docker compose build or docker compose up --build stops on one service with a build error. The underlying cause is identical to a plain docker build failure for that service.
[+] Building 2.1s (6/9)
=> ERROR [api builder 4/6] COPY requirements.txt .
failed to solve: failed to compute cache key: "/requirements.txt": not foundDiagnose it: read the resolved config, not the file you wrote
Compose merges override files, interpolates variables, and applies defaults before it does anything. Most Compose failures in CI are visible in the resolved configuration and invisible in the source file, because the value you are debugging came from an unset variable that quietly became an empty string.
# the fully merged, interpolated configuration Compose will actually run
docker compose config
# fail loudly on unset variables instead of silently interpolating empty
docker compose --env-file .env config --quiet || echo "invalid"
# which override files were picked up
docker compose config --services
Common causes
Wrong build context or Dockerfile path
The build.context and build.dockerfile in your compose file determine which files are visible. A mismatched context is the most common cause of "not found" during compose build.
A dependency service is not built/ready
Services that depend on a base image built by another service can fail if build order or depends_on is wrong.
How to fix it
Verify context and Dockerfile
Make the build context explicit and confirm the paths your Dockerfile copies actually exist relative to that context.
services:
api:
build:
context: ./api
dockerfile: Dockerfile
# COPY paths in ./api/Dockerfile are relative to ./apiBuild with full logs
docker compose build --progress=plain --no-cache apiBind mounts behave differently on a runner
- A relative bind source is resolved against the compose file location, not the working directory of the shell that invoked it.
- The host path must exist before
up. Compose creates missing directories for named volumes but not for bind mounts, and the failure surfaces as a mount error rather than a missing-path error. - On a CI runner the workspace path differs from your machine, so any absolute host path in a compose file is a portability bug waiting for its first CI run.
- Prefer named volumes for anything that does not genuinely need to be read from the host. They remove the whole class of problem.
How to prevent it
- Keep each service’s build context minimal and explicit.
- Use
.dockerignoreper context. - Pin image versions used across services so cached layers are reused.