<?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: Pepper</title>
    <description>The latest articles on DEV Community by Pepper (@captainshardmind).</description>
    <link>https://dev.to/captainshardmind</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%2F4197096%2F72c9f6f3-2c56-4a2d-8781-8257190136b6.png</url>
      <title>DEV Community: Pepper</title>
      <link>https://dev.to/captainshardmind</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/captainshardmind"/>
    <language>en</language>
    <item>
      <title>My sanoid snapshot policy (and why I trust it)</title>
      <dc:creator>Pepper</dc:creator>
      <pubDate>Thu, 05 Nov 2026 23:52:14 +0000</pubDate>
      <link>https://dev.to/captainshardmind/my-sanoid-snapshot-policy-and-why-i-trust-it-45m6</link>
      <guid>https://dev.to/captainshardmind/my-sanoid-snapshot-policy-and-why-i-trust-it-45m6</guid>
      <description>&lt;p&gt;I run two Ubuntu Server boxes, Ragnarok and Raptor, both old NVRs I put Ubuntu on. Apps live in Docker, managed with Komodo. The safety net under that is ZFS, and the part that actually makes me sleep is sanoid plus syncoid.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I set
&lt;/h2&gt;

&lt;p&gt;On both boxes, sanoid takes snapshots every 15 minutes. Syncoid replicates hourly in both directions, so each box holds a copy of the other one's important data. Nothing fancy in a web UI: cron, sanoid config, and the dataset paths I care about.&lt;/p&gt;

&lt;p&gt;I keep Docker app data on those ZFS datasets. That means a bad compose change, a deleted volume path, or me typing the wrong &lt;code&gt;rm&lt;/code&gt; is usually a rollback, not a rebuild from memory. That's also why I'm comfortable letting photo or media apps touch files on the pool: a bad reorganize is a snapshot away from undo.&lt;/p&gt;

&lt;h2&gt;
  
  
  What snapshots are not
&lt;/h2&gt;

&lt;p&gt;A ZFS snapshot of a running Postgres (or any database writing hard) is not the same thing as a proper dump. I still treat app-level backups as real for databases. Snapshots cover the "I just broke the files" case. They don't replace a dump you can restore into a clean instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the second box matters
&lt;/h2&gt;

&lt;p&gt;One box with local snapshots still dies with the box. The hourly syncoid copy is what makes a host failure survivable instead of theoretical. I also keep a reverse path so Raptor's important app data lands back on Ragnarok.&lt;/p&gt;

&lt;p&gt;The incident that made me document all of this wasn't a snapshot failure. After a routine Docker update and reboot on Ragnarok, every container lost the tailnet while the normal internet still worked. Docker had come up after Tailscale and reshuffled the firewall rules. Half the dashboard went red, and the only record of how it was wired was in my head. Snapshots wouldn't have fixed the firewall order, but that day is why I stopped treating "I'll remember" as a backup plan for anything, including which datasets sanoid covers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I stay on plain Ubuntu for this
&lt;/h2&gt;

&lt;p&gt;I tried Proxmox and left it. Sharing a drive across VMs and LXCs was special config where Ubuntu just mounts it, and cross-container networking fought me. For this lab, sanoid on bare Ubuntu plus Docker is fewer layers when something breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you're setting this up
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pick the datasets that hold real data first, not every disk.&lt;/li&gt;
&lt;li&gt;Turn on frequent local snapshots before you worry about fancy offsite.&lt;/li&gt;
&lt;li&gt;Replicate to a second box early.&lt;/li&gt;
&lt;li&gt;Do one restore to a spare path on purpose. Until you have, the policy is a rumor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I document the hosts, services, and what-breaks-what tables in plain Markdown so restore day is a checklist. Free sample sheets (no signup): &lt;a href="https://github.com/shardmind-pepper-box/homelab-recovery-kit-sample" rel="noopener noreferrer"&gt;https://github.com/shardmind-pepper-box/homelab-recovery-kit-sample&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Paid kit ($39): &lt;a href="https://shardpepper.gumroad.com/l/qghew?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=nov2026" rel="noopener noreferrer"&gt;https://shardpepper.gumroad.com/l/qghew?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=nov2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Through Mon Nov 30 at 11:59 PM Central, code NOV2026 takes 25% off both kits ($29.25 instead of $39). That's the only discount this month.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Disclosure: I made the kit and I get paid if you buy it. Everything above works without it.&lt;/p&gt;

</description>
      <category>homelab</category>
      <category>zfs</category>
      <category>selfhosted</category>
      <category>backups</category>
    </item>
  </channel>
</rss>
