<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: iatxako</title>
    <description>The latest articles on DEV Community by iatxako (@iatxako).</description>
    <link>https://dev.to/iatxako</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3963388%2F739d3c45-d9f6-4f31-9b29-114c2351b0ce.png</url>
      <title>DEV Community: iatxako</title>
      <link>https://dev.to/iatxako</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iatxako"/>
    <language>en</language>
    <item>
      <title>Your NAS Is Loud Because of Docker (and How to Fix It)</title>
      <dc:creator>iatxako</dc:creator>
      <pubDate>Tue, 02 Jun 2026 07:36:39 +0000</pubDate>
      <link>https://dev.to/iatxako/your-nas-is-loud-because-of-docker-and-how-to-fix-it-m94</link>
      <guid>https://dev.to/iatxako/your-nas-is-loud-because-of-docker-and-how-to-fix-it-m94</guid>
      <description>&lt;p&gt;You buy a NAS for silent, always-on storage. It sits in a corner, humming quietly, doing its thing.&lt;/p&gt;

&lt;p&gt;You installed Docker on it for the same reason I did: to save money. Every open-source service you'd otherwise pay a VPS for — your media server, your download automation, your file sync, your home automation bridge — all of it can run on the NAS for free. No monthly VPS bills, no cloud subscriptions, no $5/mo here and $10/mo there that add up to a second rent. Just one box, your box, doing everything.&lt;/p&gt;

&lt;p&gt;The problem is that Docker wasn't designed for spinning disks.&lt;/p&gt;

&lt;p&gt;And suddenly the HDDs never stop. Seeking, spinning, clicking, whirring — not occasionally, not every few minutes, but constantly. At 2am you can hear it from the next room. Through a closed door. It drives you insane because you bought this thing specifically so it would not make noise.&lt;/p&gt;

&lt;p&gt;I know, because I lived with it for months. Every night, the same clicking. Every morning, the same relief when the TV drowned it out. The NAS was supposed to be invisible, and instead it was the loudest thing in the house.&lt;/p&gt;

&lt;p&gt;Here's what causes it, and how I went from that to 99.9% less noise in one afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Actually Causing the Noise
&lt;/h2&gt;

&lt;p&gt;Mechanical HDDs make noise when the read/write head moves. The more random the I/O — small reads and writes scattered across the disk — the more seeking, the more noise. Sequential writes to a single file are quiet. Random I/O across thousands of small files is loud.&lt;/p&gt;

&lt;p&gt;Docker is pathological for HDDs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker overlay2
&lt;/h3&gt;

&lt;p&gt;Docker's default storage driver is overlay2. Every container runs on top of layered filesystems — the image layers are stacked, and a thin writable layer sits on top for each running container.&lt;/p&gt;

&lt;p&gt;Every file operation inside a container that touches a file from a lower layer triggers a &lt;strong&gt;copy-on-write&lt;/strong&gt;: the entire file gets copied up to the writable layer before the write happens. On an SSD this is fast and silent. On spinning HDDs with mechanical heads, every copy-on-write is a seek, a read, and a write — often scattered across the disk.&lt;/p&gt;

&lt;p&gt;And it's not just copy-on-write. Docker's overlay2 metadata lives in small files across a deep directory tree. Container startup reads dozens of these. Log rotation writes to them. Health checks touch them. Any container doing anything at all generates constant scattered I/O.&lt;/p&gt;

&lt;p&gt;Now multiply that by however many containers you're running. Every single one is generating random I/O all day, every day. The HDDs never get a break.&lt;/p&gt;

&lt;h3&gt;
  
  
  Everything Else Piling On
&lt;/h3&gt;

&lt;p&gt;Beyond Docker, a typical homelab NAS has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System monitoring tools running on cron (every 5-10 minutes, writing stats to disk)&lt;/li&gt;
&lt;li&gt;systemd journal flushing logs&lt;/li&gt;
&lt;li&gt;The NAS OS itself doing housekeeping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these alone would be noticeable. But on top of Docker's constant churn, the drives never spin down. Not for a second.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagnosing Which Process Is the Problem
&lt;/h2&gt;

&lt;p&gt;Before moving anything, confirm what's actually hitting the disk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Real-time I/O per process (needs sysstat)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iotop &lt;span class="nt"&gt;-o&lt;/span&gt;

&lt;span class="c"&gt;# Disk utilization over time&lt;/span&gt;
iostat &lt;span class="nt"&gt;-x&lt;/span&gt; 2 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On a typical Docker setup you'll see the Docker daemon at the top, with periodic spikes from cron jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: Move Docker Off the HDDs
&lt;/h2&gt;

&lt;p&gt;The HDDs are loud because they're doing work they shouldn't be doing. The solution is to give that work to something that doesn't make noise.&lt;/p&gt;

&lt;p&gt;An external SSD connected via USB is cheap, silent, and fast enough for everything Docker needs. USB 3.0 to a SATA SSD delivers 400+ MB/s — far more than any container workload requires.&lt;/p&gt;

&lt;p&gt;The goal: &lt;strong&gt;the HDDs only handle the NAS OS and your actual data (media, documents, backups)&lt;/strong&gt;. Everything Docker-related moves to the SSD.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to Migrate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Docker data-root&lt;/strong&gt; — the overlay2 layers, image cache, container writable layers. This is the biggest source of random I/O and the highest-impact thing to move.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/docker/daemon.json&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"data-root"&lt;/span&gt;: &lt;span class="s2"&gt;"/mnt/external-ssd/@docker"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bind-mount volumes&lt;/strong&gt; — the persistent data your containers read and write (databases, config files). If these live on the HDD, container writes hit the HDD. Move them to the SSD.&lt;/p&gt;

&lt;p&gt;For bind mounts, a symlink keeps things transparent — containers keep using the same paths, no reconfiguration needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /mnt/external-ssd/volumes /original/volumes/path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Stays on the HDDs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The NAS operating system&lt;/li&gt;
&lt;li&gt;System logs&lt;/li&gt;
&lt;li&gt;Your actual data files (documents, media, backups) — these have sequential I/O patterns that HDDs handle well and don't cause the constant seeking noise&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Note on Copying Files (UGOS Pro Caveat)
&lt;/h2&gt;

&lt;p&gt;If your NAS runs UGOS Pro (UGREEN's Debian-based OS), there's a critical gotcha: &lt;strong&gt;rsync will silently corrupt permissions&lt;/strong&gt; when copying from the NAS filesystem to an external drive. This is caused by proprietary kernel-level xattr hooks in UGOS Pro.&lt;/p&gt;

&lt;p&gt;The fix and the full technical explanation are in a separate post: &lt;a href="https://dev.to/iatxako/why-rsync-destroys-permissions-on-ugos-pro-and-the-only-fix-that-works-olh"&gt;Why rsync Destroys Permissions on UGOS Pro — and the Only Fix That Works&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Short version: use &lt;code&gt;tar --xattrs-exclude='ug.*'&lt;/code&gt; instead of rsync for any file copy on UGOS Pro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mount the SSD Correctly
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/fstab&lt;/span&gt;
&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-uuid&amp;gt; /mnt/external-ssd ext4 defaults,noatime,nofail 0 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two flags matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;noatime&lt;/code&gt; — disables access time updates on every file read. Eliminates a whole class of unnecessary writes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nofail&lt;/code&gt; — if the SSD disconnects and the NAS reboots, it boots normally instead of hanging at the fstab error.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Result: Silence
&lt;/h2&gt;

&lt;p&gt;After the migration, the difference is night and day. Before, the HDDs were seeking constantly — a low but relentless clicking that never stopped, day or night. It was the kind of noise you don't notice during the day but drives you crazy at 3am when the house is silent.&lt;/p&gt;

&lt;p&gt;Now? Nothing. The HDDs spin up occasionally — a system log flush, a cron job writing stats — but the &lt;strong&gt;constant background noise is gone&lt;/strong&gt;. The drives spend most of their time parked, doing what they were designed to do: sit there quietly and hold your data.&lt;/p&gt;

&lt;p&gt;I'd estimate &lt;strong&gt;99.9% reduction in audible HDD activity&lt;/strong&gt;. The clicking that used to drive me insane? Completely gone. The NAS is back to being the quiet box in the corner it was always supposed to be.&lt;/p&gt;

&lt;p&gt;You don't realize how much that noise was bothering you until it stops. Trust me.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If your NAS runs UGOS Pro, read the companion post before attempting the migration — the rsync issue will cost you time if you hit it blind: &lt;a href="https://dev.to/iatxako/why-rsync-destroys-permissions-on-ugos-pro-and-the-only-fix-that-works-olh"&gt;Why rsync Destroys Permissions on UGOS Pro&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>homelab</category>
      <category>nas</category>
    </item>
    <item>
      <title>Your NAS Is Loud Because of Docker (and How to Fix it)</title>
      <dc:creator>iatxako</dc:creator>
      <pubDate>Mon, 01 Jun 2026 21:19:53 +0000</pubDate>
      <link>https://dev.to/iatxako/your-nas-is-loud-because-of-docker-and-syncthing-and-how-to-fix-it-pg8</link>
      <guid>https://dev.to/iatxako/your-nas-is-loud-because-of-docker-and-syncthing-and-how-to-fix-it-pg8</guid>
      <description>&lt;p&gt;This article has moved to a new URL.&lt;/p&gt;

&lt;p&gt;Please visit the updated version: &lt;a href="https://dev.to/iatxako/your-nas-is-loud-because-of-docker-and-how-to-fix-it-m94"&gt;https://dev.to/iatxako/your-nas-is-loud-because-of-docker-and-how-to-fix-it-m94&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This redirect is here because the original slug contained a reference to Syncthing which is no longer relevant to the article.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>homelab</category>
      <category>nas</category>
    </item>
    <item>
      <title>Why rsync Destroys Permissions on UGOS Pro - and the Only Fix That Works</title>
      <dc:creator>iatxako</dc:creator>
      <pubDate>Mon, 01 Jun 2026 21:13:51 +0000</pubDate>
      <link>https://dev.to/iatxako/why-rsync-destroys-permissions-on-ugos-pro-and-the-only-fix-that-works-olh</link>
      <guid>https://dev.to/iatxako/why-rsync-destroys-permissions-on-ugos-pro-and-the-only-fix-that-works-olh</guid>
      <description>&lt;p&gt;Moving Docker from HDDs to an external SSD on an ARM64 NAS running UGOS Pro (Debian 12) looked simple. It took two failed approaches to find out the OS itself was the obstacle.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;A UGREEN NAS running UGOS Pro - a customized Debian 12 on ARM64 - hosting several Docker containers. All Docker data sitting on slow mechanical HDDs: both the &lt;code&gt;data-root&lt;/code&gt; (overlay2 layers) and bind-mount volumes. Goal: migrate everything to an external SSD connected via USB to eliminate HDD I/O noise from containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  First Attempt: rsync -aHX
&lt;/h2&gt;

&lt;p&gt;Standard approach for Docker migrations. Copy everything, stop Docker, delta-sync, update &lt;code&gt;daemon.json&lt;/code&gt;, restart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-aHX&lt;/span&gt; /volume1/@docker/ /mnt/external-ssd/@docker/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy succeeded. Docker started. Containers launched. Two minutes later - every container crashed with permission errors. All binaries inside the overlay2 layers had been reset to &lt;code&gt;600&lt;/code&gt;. Not executable. Just broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Attempt: rsync Without Xattrs
&lt;/h2&gt;

&lt;p&gt;Suspected xattr copy was the problem. Excluded them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-aH&lt;/span&gt; &lt;span class="nt"&gt;--no-xattrs&lt;/span&gt; /volume1/@docker/ /mnt/external-ssd/@docker/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same result. All files &lt;code&gt;600&lt;/code&gt; again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root Cause: UGOS Pro's Kernel VFS Hook
&lt;/h2&gt;

&lt;p&gt;UGOS Pro adds two proprietary extended attributes to every file on its native filesystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ug.archive_bit&lt;/code&gt; - tracks archive state for backup tooling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;system.ugacl_self&lt;/code&gt; - stores the NAS's custom ACL data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The custom ARM64 kernel includes VFS-level hooks tied to these xattrs. The hook behavior:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When &lt;code&gt;ug.archive_bit&lt;/code&gt; is written to any filesystem&lt;/strong&gt; - including ext4 on the SSD - the kernel resets that file's permissions to &lt;code&gt;600&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This fires in both rsync modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With &lt;code&gt;-X&lt;/code&gt;: rsync explicitly copies &lt;code&gt;ug.*&lt;/code&gt; xattrs to the destination ? hook fires&lt;/li&gt;
&lt;li&gt;Without xattrs: rsync calls &lt;code&gt;chmod()&lt;/code&gt; after writing files ? the kernel hook intercepts the chmod and applies &lt;code&gt;ug.*&lt;/code&gt; to the new file ? hook fires again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No rsync flag combination avoids this. The hook is below userspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: tar with --xattrs-exclude
&lt;/h2&gt;

&lt;p&gt;The solution is &lt;code&gt;tar&lt;/code&gt; with explicit xattr exclusion. Unlike rsync, tar applies the file mode &lt;strong&gt;atomically during extraction&lt;/strong&gt; - the kernel doesn't get a separate chmod syscall to intercept.&lt;/p&gt;

&lt;p&gt;Excluding &lt;code&gt;ug.*&lt;/code&gt; ensures they're never written to the destination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs-include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs-exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ug.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-cpf&lt;/span&gt; - &lt;span class="nt"&gt;-C&lt;/span&gt; /source/path directory-name &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs-include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs-exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ug.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-xpf&lt;/span&gt; - &lt;span class="nt"&gt;-C&lt;/span&gt; /destination/path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pipe avoids writing to disk twice. The &lt;code&gt;--xattrs-include='*.*'&lt;/code&gt; is required - without it, &lt;code&gt;--xattrs-exclude&lt;/code&gt; is silently ignored.&lt;/p&gt;

&lt;p&gt;Expected warning during extraction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tar&lt;/span&gt;: system.ugacl_self: Operation not supported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Harmless. The ext4 SSD doesn't support this xattr type, tar reports it and continues normally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migration Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prepare the SSD
&lt;/h3&gt;

&lt;p&gt;Add to &lt;code&gt;/etc/fstab&lt;/code&gt; for persistent mount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;=&amp;lt;&lt;span class="n"&gt;your&lt;/span&gt;-&lt;span class="n"&gt;uuid&lt;/span&gt;&amp;gt; /&lt;span class="n"&gt;mnt&lt;/span&gt;/&lt;span class="n"&gt;external&lt;/span&gt;-&lt;span class="n"&gt;ssd&lt;/span&gt; &lt;span class="n"&gt;ext4&lt;/span&gt; &lt;span class="n"&gt;defaults&lt;/span&gt;,&lt;span class="n"&gt;noatime&lt;/span&gt;,&lt;span class="n"&gt;nofail&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;nofail&lt;/code&gt; flag is critical - without it, a disconnected SSD during boot will hang the NAS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/external-ssd
&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 1: Migrate Docker data-root
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop Docker completely - both socket and service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop docker.socket docker.service

&lt;span class="c"&gt;# Copy with tar pipe&lt;/span&gt;
&lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.*'&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ug.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-cpf&lt;/span&gt; - &lt;span class="nt"&gt;-C&lt;/span&gt; /original/docker/path @docker &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.*'&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ug.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-xpf&lt;/span&gt; - &lt;span class="nt"&gt;-C&lt;/span&gt; /mnt/external-ssd

&lt;span class="c"&gt;# Update daemon.json&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"data-root": "/mnt/external-ssd/@docker"}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/docker/daemon.json

&lt;span class="c"&gt;# Restart and verify&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start docker
docker info | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'Docker Root Dir'&lt;/span&gt;
docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 2: Migrate bind-mount volumes
&lt;/h3&gt;

&lt;p&gt;The symlink approach avoids recreating any containers - Docker sees the same path, it just resolves to the SSD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop docker.socket docker.service

&lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.*'&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ug.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-cpf&lt;/span&gt; - &lt;span class="nt"&gt;-C&lt;/span&gt; /original/volumes/path &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| &lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--xattrs&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'*.*'&lt;/span&gt; &lt;span class="nt"&gt;--xattrs-exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ug.*'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-xpf&lt;/span&gt; - &lt;span class="nt"&gt;-C&lt;/span&gt; /mnt/external-ssd/volumes

&lt;span class="c"&gt;# Replace original directory with symlink&lt;/span&gt;
&lt;span class="nb"&gt;sudo mv&lt;/span&gt; /original/volumes/path /original/volumes/path.bak
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /mnt/external-ssd/volumes /original/volumes/path

&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start docker
docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /original/volumes/path
&lt;span class="nb"&gt;readlink&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /original/volumes/path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;All containers running from SSD. HDD I/O dropped significantly. Mechanical drives now only handle the OS, logs, and background system processes. The symlink approach meant zero container reconfiguration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rule for UGOS Pro
&lt;/h2&gt;

&lt;p&gt;Any time you copy files &lt;strong&gt;from&lt;/strong&gt; UGOS Pro's native filesystem to another filesystem (ext4, btrfs, tmpfs), use &lt;code&gt;tar --xattrs-exclude='ug.*'&lt;/code&gt;. rsync cannot be made safe for this operation regardless of flags.&lt;/p&gt;

&lt;p&gt;This applies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker data-root migrations&lt;/li&gt;
&lt;li&gt;Backup operations targeting external drives&lt;/li&gt;
&lt;li&gt;Any bulk copy from UGOS-managed paths to a non-UGOS filesystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The warning &lt;code&gt;system.ugacl_self: Operation not supported&lt;/code&gt; will appear during extraction - it's harmless.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tested on UGOS Pro with a custom ARM64 kernel. If you hit this on a different NAS OS with proprietary xattr hooks, the same pattern applies - find the vendor xattr prefix and exclude it from tar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>nas</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
