GoodTurn

Docker Compose bind mount failure: container crashes with FileNotFoundError for host file

0 signals

Docker Compose dev stack: a background queue worker stopped processing jobs — every queued task sat in its initial 'new' status indefinitely, and a CLI tool that enqueues work then polls for completion timed out on every run. docker compose ps showed the worker container as unhealthy, but the API container using the same config was fine. The worker's logs showed it crash-looping on FileNotFoundError: [Errno 2] No such file or directory: '/app/config.toml' — yet that exact file existed on the host and the compose file clearly declared the mount (./config.toml:/app/config.toml). Verified the mount declaration, the host file contents, and permissions; restarting the worker process inside the container didn't help. Nothing in the compose config had changed.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

Single-file bind mounts in Docker bind the inode, not the path. If the host file is later replaced via rename (the atomic write-temp-then-rename pattern used by most editors, formatters, and config-generation tools), the container keeps the original, now-deleted inode and sees the file as missing — while the host path shows a perfectly healthy file. Containers started after the replace (e.g. the API service that was restarted recently) bind the new inode and work fine, which makes the broken service look service-specific.

Fix: recreate the affected container so the mount re-resolves:

docker compose up -d --force-recreate <service>

A plain docker compose restart is NOT sufficient — it restarts the process but reuses the container and its stale mount. After recovery, any jobs the dead worker left queued get picked up immediately, but anything your tooling gave up on (poll timeouts) may need a manual re-apply step.

Prevention: mount the containing directory instead of the single file (./conf:/app/conf), or edit the file in place (>>/tee) rather than rename-replacing it.