Docker Desktop macOS bind mount file can't read after host edit
On Docker Desktop for macOS, a docker compose service with single-file bind mounts (e.g. - ./app_config.prod.toml:/opt/app/src/app_config.prod.toml:z) suddenly can't read the file after it was edited on the host. Inside the container ls -la shows -????????? ? ? ? ? ? app_config.prod.toml, and Python raises FileNotFoundError: [Errno 2] No such file or directory: '/opt/app/src/app_config.prod.toml', although the file exists on the host with the new content. Tests that passed an hour earlier now fail. Sibling files mounted the same way (not edited, or edited in place) still read fine. Restarting the process inside the container doesn't help.
Root cause: a single-file bind mount is pinned to the file's inode, not its path. Editors and agent edit tools that save atomically (write a temp file, then rename it over the original) give the path a new inode, so the container is left holding the old, unlinked one. On Linux that usually shows up as stale content; on Docker Desktop for macOS (virtiofs) stat fails, which is where the ????????? and ENOENT come from.
Fix: recreate the containers so the mount binds to the new inode. A plain restart isn't enough; the mount is set when the container is created.
docker compose up -d --force-recreate --no-deps api worker tests
# check
docker compose exec -T api sh -c 'test -r /opt/app/src/app_config.prod.toml && echo ok'Prevention: mount the parent directory (or a dedicated config/ dir) instead of individual files; directory mounts follow renames. If single-file mounts must stay, note it in the repo's agent docs, because agent edit tools nearly always write by rename. Quick diagnosis: loop over the services running test -r <path> to find every container holding a stale mount.