Back to Blog
DevOps8 min readJuly 8, 2026
๐Ÿณ

Why sed -i Breaks Your Docker Bind Mount (and What to Use Instead)

We ran into a frustrating bug while updating a Caddyfile on a production server. We used sed -i to change a domain name inside the file โ€” a common, quick edit. Then we ran caddy reload. It came back saying "config is unchanged." The old domain was still being served.

We checked the file on disk. The new domain was there. Caddy was still routing to the old one. The container hadn't been restarted. What was going on?

The inode problem

Here's what sed -i actually does on Linux:

  1. Creates a new temporary file with the edited content
  2. Deletes (unlinks) the original file
  3. Renames the temporary file to the original filename

This is an atomic operation at the filesystem level โ€” safe from a data integrity perspective. But it has a subtle consequence: the resulting file has a new inode number.

Docker bind mounts work by associating a container path with a host inode at the time the container starts. When sed -i replaces that file with a new inode, the container's bind mount still points at the old inode. The file on disk looks correct to you, but the container never sees the change.

The trap

You edit the file, it looks right on disk, caddy reload succeeds silently, and nothing changes. The container is still reading the ghost of the old file via its open inode reference.

The correct fix: cat heredoc writes

Write into the existing inode rather than replacing it. The cat heredoc pattern does exactly this:

cat > /docker/Caddyfile <<'EOF'
yourapp.example.com {
    encode gzip

    handle /api/* {
        reverse_proxy app-server:5001
    }

    handle {
        root * /docker/doc-front
        try_files {path} /index.html
        file_server
    }
}
EOF

cat > file opens the existing file descriptor and overwrites its content in place. The inode is preserved. The container sees the change immediately โ€” no restart needed.

Rule of thumb

# โœ… Safe: in-place write (preserves inode)
cat > /docker/Caddyfile <<'EOF'
...config...
EOF

# โŒ Unsafe: replaces inode
sed -i 's/old/new/' /docker/Caddyfile

# โŒ Unsafe: creates new file at path
mv /tmp/new_caddy /docker/Caddyfile

For any file bind-mounted into a running container: use cat > file. Never use sed -i, mv, or editors that create temp files (vim default mode). Nano writes in-place and is safe.