<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/atom.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:fh="http://purl.org/syndication/history/1.0">
  <title>Posts tagged: compose Archive</title>
  <id>https://pype.dev/tags/compose/archive/atom.xml</id>
  <updated>2025-08-02T13:01:58Z</updated>
  <subtitle>All posts with the tag &#34;compose&#34;</subtitle>
  <link href="https://pype.dev/tags/compose/" rel="alternate" type="text/html"></link>
  <link href="https://pype.dev/tags/compose/archive/atom.xml" rel="self" type="application/atom+xml"></link>
  <link href="https://pype.dev/tags/compose/atom.xml" rel="current" type="application/atom+xml"></link>
  <author>
    <name>Nic Payne</name>
  </author>
  <generator uri="https://github.com/WaylonWalker/markata-go">markata-go</generator>
  <fh:complete></fh:complete>
  <entry>
    <title>Docker Volume Mounts Link to an Inode</title>
    <id>https://pype.dev/docker-volume-mounts-link-to-an-inode/</id>
    <updated>2025-08-02T13:01:58Z</updated>
    <published>2025-08-02T13:01:58Z</published>
    <link href="https://pype.dev/docker-volume-mounts-link-to-an-inode/" rel="alternate" type="text/html"></link>
    <summary type="text">docker bind mounts are specified as filepaths - this is very intuitive. I want /path/to/directory on my host to be shared with /another/path/foo in a...</summary>
    <content type="html">&lt;p&gt;&lt;a href=&#34;/docker/&#34; class=&#34;glossary-term&#34; title=&#34;docker - container runtime&#34; data-hover-title=&#34;docker&#34;&gt;docker&lt;/a&gt; bind mounts are specified as filepaths - this is very intuitive. I want&#xA;/path/to/directory on my host to be shared with /another/path/foo in a&#xA;container. But what if /path/to/directory on the host is moved?&lt;/p&gt;&#xA;&lt;p&gt;This is a situation I have found myself in at home and it turns out that I&amp;rsquo;m&#xA;actually in almost zero trouble thankfully&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;TLDR - I have a bunch of compose stacks in&#xA;/home/projects/homelab-compose/&lt;host&gt;/&lt;application&gt; and I want to move them to&#xA;/home/projects/homelap-mono/compose/&lt;host&gt;/&lt;application&gt;&lt;/p&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t want to take down all my stacks to do this because I don&amp;rsquo;t yet have a&#xA;convenient way to do it - but can I just &lt;code&gt;mv .../homelab-compose .../homelab-mono/compose&lt;/code&gt; and be done with it?&lt;/p&gt;&#xA;&lt;p&gt;The issue is that some of my stacks use local volume mounts - ie. there is a&#xA;data volume on the host in&#xA;/home/projects/homelab-compose/&lt;host&gt;&lt;application&gt;/docker-data for some of the&#xA;applications&amp;hellip; can I just move everything and docker is nonethewiser?&lt;/p&gt;&#xA;&lt;p&gt;Turns out the answer is mostly &lt;code&gt;yes&lt;/code&gt; with some caveats to keep in mind..&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s start with why it works and then show an example&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;why&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Why&lt;/span&gt; &lt;a href=&#34;#why&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;This works because of how docker interprets the bind mount location initially&#xA;and with how &lt;code&gt;mv&lt;/code&gt; is different from &lt;code&gt;cp&lt;/code&gt;. When you speicify a volume mount for&#xA;docker, the engine determines which &lt;a href=&#34;/inode/&#34; class=&#34;wikilink&#34; data-title=&#34;inode&#34; data-description=&#34;Index Nodes (inode) is a data structure that stores information about a file or directory, such as its size, permissions, ownership, and disk block...&#34; data-date=&#34;2025-08-03&#34; data-preview=&#34;Index Nodes (inode) is a data structure that stores information about a file or directory, such as its size, permissions, ownership, and disk block...&#34;&gt;inode&lt;/a&gt; contains the metadata for the&#xA;filesystem object referenced by the original volume path &lt;code&gt;/path/to/directory&lt;/code&gt;.&#xA;I think about this like a string path is a pointer to a lower level identifier&#xA;closer to the filesystem - if that pointer changes it doesn&amp;rsquo;t affect the&#xA;pre-existing &lt;a href=&#34;/inode/&#34; class=&#34;glossary-term&#34; title=&#34;Index Nodes (inode) is a data structure that stores information about a file or directory, such as its size, permissions, ownership, and disk block...&#34; data-hover-title=&#34;inode&#34;&gt;inode&lt;/a&gt; or data. So docker uses the inode that &lt;code&gt;/path/to/directory&lt;/code&gt;&#xA;points to when the container starts up.&lt;/p&gt;&#xA;&lt;p&gt;The slight convenience in my case is that &lt;code&gt;mv&lt;/code&gt; maintains the existing inode and&#xA;so the new filepath is irrelevant to that existing container that was spun up&#xA;with a now-non-existent host filepath.&lt;/p&gt;&#xA;&lt;p&gt;So if you can imagine then - I spun up several containers in&#xA;&lt;code&gt;///homelab-compose/...&lt;/code&gt; with many stacks - and I want to just move all the&#xA;config files to new repo&amp;hellip; thankfully, I actually can &lt;em&gt;just &lt;code&gt;mv&lt;/code&gt;&lt;/em&gt; everything&#xA;and because the &lt;code&gt;inode&lt;/code&gt; locations dont&amp;rsquo; change, the stacks are fine!&lt;/p&gt;&#xA;&lt;div class=&#34;admonition warning&#34;&gt;&#xA;&lt;p class=&#34;admonition-title&#34;&gt;caveat&lt;/p&gt;&#xA;&lt;p&gt;Is the next issue apparent? What happens to those files whose volume mount configurations specify &amp;hellip;/homelab-compose/&amp;hellip;? Well, if the stacks are brought down and back up then docker will create that filepath on the host and a new inode reference will be had by all&amp;hellip; so that&amp;rsquo;s a problem easily mitigated by some string replacement!&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&#34;admonition note&#34;&gt;&#xA;&lt;p class=&#34;admonition-title&#34;&gt;another note&lt;/p&gt;&#xA;&lt;p&gt;Perhaps just don&amp;rsquo;t keep data next to your configuration either&amp;hellip; In most of my stacks I have a determined docker volume that&amp;rsquo;s backed up etc. on my hosts and that&amp;rsquo;s what I&amp;rsquo;m moving towards on my desktop, but as of right now I&amp;rsquo;ve put myself in an odd situation via not participating in a proper thinking exercise when standing up all these stacks on my desktop&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;example&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Example&lt;/span&gt; &lt;a href=&#34;#example&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Finally let&amp;rsquo;s just see it in action quickly&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;I have a directory &lt;code&gt;/tmp/foo/source&lt;/code&gt; with a compose file in it.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;❯ tree source       &#xA;source&#xA;└── docker-compose.yml&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;That file is simple:&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;nginx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;8070:80&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;/tmp/foo/source:/usr/share/nginx/html&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I can spin that container up, exec in, drop a file in &lt;code&gt;/usr/share/nginx/html&lt;/code&gt; and we&amp;rsquo;ll see it in &lt;code&gt;/tmp/foo/source&lt;/code&gt; as expected&amp;hellip;&lt;/p&gt;&#xA;&lt;pre class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nic in /tmp/foo   &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dev&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;❯ docker &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; source-app-1 touch /usr/share/nginx/html/file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nic in /tmp/foo   &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dev&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;❯ tree &lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt;                                                       &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;source&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── docker-compose.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── file.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; directory, &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let&amp;rsquo;s &lt;code&gt;mv&lt;/code&gt; the &lt;code&gt;source&lt;/code&gt; directory somewhere else and see what happens&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;nic in /tmp/foo   (dev)&#xA;❯ mv source target &#xA;&#xA;nic in /tmp/foo   (dev)&#xA;❯ tree target &#xA;target&#xA;└── source&#xA;    ├── docker-compose.yml&#xA;    └── file.txt&#xA;&#xA;2 directories, 2 files&#xA;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;OK everything is there - now let&amp;rsquo;s drop another file in the container - remember the compose file still has the host path as &lt;code&gt;/tmp/foo/source&lt;/code&gt;, not &lt;code&gt;/tmp/foo/target/source&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;nic in /tmp/foo   (dev)&#xA;❯ docker exec source-app-1 touch /usr/share/nginx/html/another-file.txt&#xA;&#xA;nic in /tmp/foo   (dev)&#xA;❯ tree target                                                          &#xA;target&#xA;└── source&#xA;    ├── another-file.txt  # BAM! New file still here...&#xA;    ├── docker-compose.yml&#xA;    └── file.txt&#xA;&#xA;2 directories, 3 files&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;few-things&#34;&gt;&lt;span class=&#34;heading-wear-glyph&#34;&gt;Few Things&lt;/span&gt; &lt;a href=&#34;#few-things&#34; class=&#34;heading-anchor&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;code&gt;cp&lt;/code&gt; as noted before, creates new &lt;code&gt;inodes&lt;/code&gt; and so if I were to have &lt;code&gt;cp -r&lt;/code&gt;&#xA;that &lt;code&gt;source&lt;/code&gt; directory to &lt;code&gt;target&lt;/code&gt; then the container would&amp;rsquo;ve dropped&#xA;er exec source-app-1 touch /usr/share/nginx/html/another-file.txc in /tmp/foo   (dev) 󰒄 󱔎 NO PYTHON ENVIORNMENT SET t&#xA;&lt;code&gt;another-file.txt&lt;/code&gt; to &lt;code&gt;/tmp/source&lt;/code&gt; and we&amp;rsquo;d be in a pretty confusing state&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Let me stress again the importance of managing your docker volumes in a sane&#xA;way&amp;hellip; I have on any of my hosts a &lt;code&gt;/path/to/docker/data&lt;/code&gt; which is backed up&#xA;in a way that makes sense for the host (usually zfs + sanoid, otherwise restic&#xA;backup TO a remote zfs dataset - see&#xA;&lt;a href=&#34;/using-restic-to-backup-my-home-directory/#Intro&#34; class=&#34;wikilink&#34; data-title=&#34;Using restic to backup my home directory&#34; data-description=&#34;I need to backup my personal $HOME to my NAS cause there&amp;#39;s a lot in there, and mostly my git projects with .env files all over. Plus some docker data&#34; data-date=&#34;2025-07-16&#34;&gt;Using restic to backup my home directory&lt;/a&gt;)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</content>
    <author>
      <name>Nic Payne</name>
      <uri>https://pype.dev</uri>
    </author>
  </entry>
</feed>