nginx-proxy / docker-gen

Generate files from docker container meta-data
MIT License
4.43k stars 603 forks source link

Writing file uses new inode, breaking Docker mounts #629

Open KetchupBomb opened 3 months ago

KetchupBomb commented 3 months ago

It appears that docker-gen creates a new temporary file that is then moved to [dest], based at least on differing inodes.

Consider the following REPL:

$ docker run -it --rm -v /var/run/docker.sock:/tmp/docker.sock:ro --entrypoint ash nginxproxy/docker-gen
$ echo '{{- . -}}' > template.tmpl

$ docker-gen template.tmpl rendered.txt
2024/05/28 07:49:25 Generated 'rendered.txt' from 111 containers
$ stat rendered.txt 
  File: rendered.txt
  Size: 1444            Blocks: 8          IO Block: 4096   regular file
Device: 7bh/123d        Inode: 32639413    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-28 07:49:25.310417663 +0000
Modify: 2024-05-28 07:49:25.310417663 +0000
Change: 2024-05-28 07:49:25.310417663 +0000

$ docker-gen template.tmpl rendered.txt
2024/05/28 07:49:29 Generated 'rendered.txt' from 111 containers
$ stat rendered.txt 
  File: rendered.txt
  Size: 1444            Blocks: 8          IO Block: 4096   regular file
Device: 7bh/123d        Inode: 32639416    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2024-05-28 07:49:29.858497954 +0000
Modify: 2024-05-28 07:49:29.858497954 +0000
Change: 2024-05-28 07:49:29.858497954 +0000

(The inode changes from 32639413 to 32639416.)

This can cause processes with open file descriptors to continue reading the old inode. Of particular interest are Docker mounts.

I have been trying to leverage docker-gen to render config files, and I then share those config files to other contains, ideally mounting just the rendered config files as them directly into the receiving containers filesystem as :ro. (Trying to be secure 🤷‍♂️)

But due to the above behavior, the receiving container never sees the new rendered config -- it continues reading the old inode and therefore old data.

This isn't necessarily a bug with docker-gen -- I fixed it for now by not mounting the file directly, but rather mounting the file's directory which alleviates the issue -- but truncating the existing inode and writing directly would have helped me out recently. Thanks for considering this issue.