A background agent Docker build: 'open Dockerfile: no such file or directory'

·3 mins

A background Docker build failed immediately with:

ERROR: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory

The agent had supplied the project directory through the terminal tool’s workdir argument. The retry put cd inside the command itself. For an agent runner whose background path handling is uncertain, bind the directory in the command or make the Dockerfile and build context absolute.

The failed call already supplied workdir

In the historical runner, the background invocation had this shape, with project and image names generalized:

{
  "background": true,
  "workdir": "/srv/app",
  "command": "docker build --progress=plain -t local/app:dev -f Dockerfile ."
}

Docker could not open Dockerfile. The retry started with an explicit cd to the project before running the build. That corrected the launch form; whether the rest of that session succeeded is outside this lesson.

The error alone does not identify the actual launch directory. The record supports a runner-specific path-handling failure, not a rule that background processes generally discard their parent’s directory. Ordinary shell backgrounding with & inherits the shell’s working directory. An agent tool can launch its jobs through a different execution path.

A later check on the runner used to prepare this post found that background jobs preserved the preceding foreground directory, and an explicit background workdir was honored. The historical failure is therefore not a current universal behavior claim.

Bind both Docker paths deliberately

For an existing project at /srv/app, put the directory change and build in the same command:

cd /srv/app &&
  docker build --progress=plain -t local/app:dev -f Dockerfile .

The && prevents the build from running if the directory change fails. Alternatively, remove the directory dependency from both path arguments:

docker build --progress=plain -t local/app:dev \
  -f /srv/app/Dockerfile /srv/app

Making only -f absolute still leaves . as an accidental build context. Likewise, when using Compose, check its file selection and relative-path behavior rather than assuming a successful Docker build proves the next command has the right context.

Probe the actual execution mode

Before a multi-minute job, use a harmless foreground command to change to a known scratch directory:

cd "${TMPDIR:?Set TMPDIR to your scratch directory}" && pwd

Then submit pwd as a separate background tool call without workdir, and read that job’s captured output. Repeat with workdir set to the project root. Those two checks distinguish remembered foreground state from an explicit launch directory without building an image or starting services.

For a real build, print pwd and check test -f Dockerfile inside the same command that launches it. A foreground check in an earlier call cannot establish the background job’s directory.

Separate service startup from readiness checks

The same historical session hit another runner boundary. A foreground command combining docker compose up -d with a health-check loop was rejected with:

This foreground command appears to start a long-lived server/watch process.

The runner directed the agent to launch it with background=true, verify readiness, and run tests separately. That refusal came from the runner, even though Compose’s -d requests detached containers.

Keep service startup in its own call, following the runner’s execution rules. Check readiness in a separate bounded command, and fail explicitly if the deadline expires. Starting a service and proving it healthy are separate results.

Before your next background build, compare its reported directory with the intended build context using the harmless probe above.