<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>xyny&apos;s writings</title><description>This collection of writings may or may not be a blog. Posts here may or may not be chronologically ordered or accurately listed. Content might or might not be kept up-to-date. Effort might or might not be spent.</description><link>https://xyny.art/</link><language>en-us</language><item><title>Building a custom NAS with Fedora CoreOS</title><link>https://xyny.art/blog/2026-building-nas/</link><guid isPermaLink="true">https://xyny.art/blog/2026-building-nas/</guid><description>for free! (with used disks and parts from a previous PC)</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1 id=&quot;building-a-custom-nashomeserver-with-fedora-coreos&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#building-a-custom-nashomeserver-with-fedora-coreos&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Building a custom NAS/homeserver with Fedora CoreOS&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;100% ORGANIC HUMAN-WRITTEN CONTENT&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is not a tutorial, but a description of how I set up my NAS, along with some commentary, tips, and tricks. Feel free to follow in my footsteps, though.&lt;/p&gt;&lt;!--For more related guidance from me, check out the [Web- and self-hosting cheatsheet](/blog/hosting-cheatsheet/).--&gt;
&lt;h4 id=&quot;table-of-contents&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#table-of-contents&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Table Of Contents:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-hardware&quot;&gt;1. Hardware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-os-installation&quot;&gt;2. OS installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-zfs&quot;&gt;3. ZFS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-data-migration&quot;&gt;4. Data migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-whats-a-computer&quot;&gt;5. What’s a computer?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-remote-access&quot;&gt;6. Remote access&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-podman-compose&quot;&gt;7. &lt;code&gt;podman compose&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-service-migration&quot;&gt;8. Service migration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#9-cool-additions&quot;&gt;9. Cool additions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#10-snapshots-backups-and-data-integrity&quot;&gt;10. Snapshots, backups, and data integrity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#11-conclusion&quot;&gt;11. Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;1-hardware&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#1-hardware&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;1. Hardware&lt;/h2&gt;
&lt;p&gt;After I started self-hosting using docker-compose on an off-the-shelf QNAP NAS, I’ve been just dreaming of building a custom NAS and running a custom Linux OS on it (not something like Truenas or Unraid, or QNAP QTS god forbid).&lt;/p&gt;
&lt;p&gt;Well, my dad recently got a new PC and I got his old one to use for this purpose, along with some used 6TB disks that were recently replaced with larger ones on our QNAP NAS.&lt;/p&gt;
&lt;p&gt;Here are the specs of the PC (it was built around 2019 to function as a pre-ChatGPT era local AI and 3D graphics workstation):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Intel Core i9 9900K (Coffee Lake)&lt;/li&gt;
&lt;li&gt;RAM: 4x16GB G.Skill 1066MHz DDR4 (F4-3200C16-16GVK)&lt;/li&gt;
&lt;li&gt;GPU: NVIDIA Titan RTX (24GB VRAM)
&lt;ul&gt;
&lt;li&gt;We took this out to sell, since it probably would be pretty useless for a NAS build, and we have a few other GPUs that are in use in our desktop PCs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Case: Fractal Design (maybe the R6)
&lt;ul&gt;
&lt;li&gt;As far as Fractal Design cases go, they are great! But this one is definitely a sleeper. There are no windowed side panels and tons of soundproofing to optionally cover the vents.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Motherboard: ASRock Z390 Taichi Ultimate
&lt;ul&gt;
&lt;li&gt;The motherboard is truly a beast. 8xSATA3 and 3 M.2 slots are more than I will need for a while, and a single 10Gbit ethernet port is a nice bonus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The drives I got are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;4x 6TB WD Black (WD6001FZWX)&lt;/li&gt;
&lt;li&gt;1x 6TB Seagate BarraCuda Pro (ST6000DM004)&lt;/li&gt;
&lt;li&gt;1x 1TB Samsung 970 EVO M.2 SSD&lt;/li&gt;
&lt;li&gt;1x 500GB Samsung 970 EVO M.2 SSD&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-os-installation&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#2-os-installation&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;2. OS installation&lt;/h2&gt;
&lt;p&gt;As the OS to install, I picked &lt;a href=&quot;https://github.com/ublue-os/ucore&quot;&gt;ucore&lt;/a&gt; (a custom image of Fedora CoreOS with useful features for homeserver usage). More specifically, I’m using the &lt;code&gt;ucore:stable&lt;/code&gt; variant.&lt;/p&gt;
&lt;p&gt;I picked this mostly because as a &lt;a href=&quot;https://blue-build.org/&quot;&gt;BlueBuild&lt;/a&gt; developer and a Fedora bootc desktop user, I am also pretty close to the &lt;a href=&quot;https://universal-blue.org/&quot;&gt;Universal Blue&lt;/a&gt; community, which maintains ucore. I believe image-based Linux distribution is the future and I want to use atomic distributions on all my machines, and while I could have built my own bootc image, this one already exists and does everything that I would do as well without me having to think about it separately. This model fits servers especially well, since most software I want to self-host on it I will be running with containers using &lt;code&gt;podman&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Installing CoreOS requires creating an &lt;em&gt;ignition file&lt;/em&gt;, which can be generated from a &lt;em&gt;butane configuration&lt;/em&gt;. I used the &lt;a href=&quot;https://github.com/ublue-os/ucore/blob/main/examples/ucore-autorebase.butane&quot;&gt;ucore example butane file&lt;/a&gt; with my own auth details, and an additional section to set the hostname:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;storage&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  files&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/etc/hostname&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      mode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0644&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      overwrite&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      contents&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        inline&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;eserv-home&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For building the ignition file from the butane file and serving it I used the following &lt;a href=&quot;https://just.systems/&quot;&gt;Justfile&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;serve-butane: build-butane&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    caddy file-server --root serve --listen :8080 &amp;#x26;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    tailscale funnel 8080&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;build-butane:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    mkdir -p serve&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    podman run --interactive --pull=newer --rm quay.io/coreos/butane:release \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;       --pretty --strict &amp;#x3C; config.bu &gt; serve/config.ign&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for installing I used the usual bare metal Fedora CoreOS .iso file and the following command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; coreos-installer&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/nvme1n1&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --ignition-url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; https://my-pc.tail12345.ts.net/config.ign&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(&lt;code&gt;/dev/nvme1n1&lt;/code&gt; is the 500GB M.2 SSD, which I picked to be the boot drive)&lt;/p&gt;
&lt;h2 id=&quot;3-zfs&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#3-zfs&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;3. ZFS&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;To get a basic understanding of ZFS, I read a ton of tutorials and watched some videos. You should too. Here are some links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ikrima.dev/dev-notes/homelab/zfs-cheatsheet/&quot;&gt;https://ikrima.dev/dev-notes/homelab/zfs-cheatsheet/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.victormendonca.com/2020/11/03/zfs-for-dummies/&quot;&gt;https://blog.victormendonca.com/2020/11/03/zfs-for-dummies/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://neil.computer/notes/how-to-setup-minimal-zfs-nas-without-truenas/&quot;&gt;https://neil.computer/notes/how-to-setup-minimal-zfs-nas-without-truenas/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jrs-s.net/2015/02/06/zfs-you-should-use-mirror-vdevs-not-raidz/&quot;&gt;https://jrs-s.net/2015/02/06/zfs-you-should-use-mirror-vdevs-not-raidz/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was initially planning to go for two mirror VDEVs, but since I got 5 disks, I picked a 5-disk-wide RAIDZ2 instead.&lt;/p&gt;
&lt;p&gt;First, following the instructions from &lt;a href=&quot;https://neil.computer/notes/how-to-setup-minimal-zfs-nas-without-truenas/&quot;&gt;How to Build a Minimal ZFS NAS without Synology, QNAP, TrueNAS&lt;/a&gt; I added the following lines to &lt;code&gt;/etc/zfs/vdev_id.conf&lt;/code&gt; to make sure my drives have static human-readable aliases:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;alias hdd0 /dev/disk/by-id/ata-WDC_WD6001FZWX-00A2VA0_WD-WXXXXXXXXXXX&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;alias hdd1 /dev/disk/by-id/ata-WDC_WD6001FZWX-00A2VA0_WD-WXXXXXXXXXXX&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;alias hdd2 /dev/disk/by-id/ata-WDC_WD6001FZWX-00A2VA0_WD-WXXXXXXXXXXX&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;alias hdd3 /dev/disk/by-id/ata-ST6000DM004-2EH11C_XXXXXXXX&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;alias hdd4 /dev/disk/by-id/ata-WDC_WD6001FZWX-00A2VA0_WD-WXXXXXXXXXXX&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And to set the aliases:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; udevadm&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; trigger&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I had to run the following command to get rid of existing filesystems, partitions, and md raid on the HDD disks:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sgdisk&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --zap-all&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/disk/by-vdev/hdd0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sgdisk&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --zap-all&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/disk/by-vdev/hdd1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sgdisk&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --zap-all&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/disk/by-vdev/hdd2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sgdisk&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --zap-all&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/disk/by-vdev/hdd3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sgdisk&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --zap-all&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/disk/by-vdev/hdd4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I could create the pool:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zpool&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -o&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ashift=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/tank&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; raidz2&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; hdd0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; hdd1&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; hdd2&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; hdd3&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; hdd4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ashift=12&lt;/code&gt; because my disks have a physical sector size of 4KiB and this is said online to increase performance (and cannot be changed after pool creation)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-m /var/tank&lt;/code&gt; because the default default mountpoint of &lt;code&gt;/tank&lt;/code&gt; is unwriteable on CoreOS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then I set some initial tuning parameters I found &lt;a href=&quot;https://www.high-availability.com/docs/ZFS-Tuning-Guide/&quot;&gt;recommended online&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; compression=lz4&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; recordsize=128KiB&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; atime=off&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; xattr=sa&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I created some initial datasets for the tank:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank/e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank/e/Garden&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank/e/Backup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank/e/DCIM&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank/media&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;e&lt;/code&gt; is my initial and my linux user account, and thus &lt;code&gt;tank/e&lt;/code&gt; is for my personal files (if the NAS gets more users, they would get their own dataset)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Garden&lt;/code&gt; is for my general files, projects, notes, etc.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Backup&lt;/code&gt; is a backup destination for my computers, phone, VPS, etc.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DCIM&lt;/code&gt; is a backup destination for all (digital camera) images I have ever taken in my entire life (almost)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;media&lt;/code&gt; is for (very much legal) streaming&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then to give the admin user &lt;code&gt;core&lt;/code&gt; permissions to the tank, I had to run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; allow&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; core&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create,destroy,mount,snapshot&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; chown&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -R&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; core:core&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/tank/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, I created a ZFS pool out of my single 1TB M.2 SSD, to use as a high-performance storage backend for the various services I intend to run (and related stuff like databases, config files, logs). This followed pretty much the same procedure as creating tank:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;alias ssd /dev/disk/by-id/nvme-Samsung_SSD_970_EVO_1TB_XXXXXXXXXXXXXXX&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tee&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -a&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /etc/zfs/vdev_id.conf&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; udevadm&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; trigger&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sgdisk&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --zap-all&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /dev/disk/by-vdev/ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zpool&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -o&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ashift=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/ssd&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; compression=lz4&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; recordsize=64KiB&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; atime=off&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; set&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; xattr=sa&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd/services&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; allow&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; core&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; create,destroy,mount,snapshot&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ssd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; chown&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -R&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; core:core&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/ssd/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;4-data-migration&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#4-data-migration&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;4. Data migration&lt;/h2&gt;
&lt;p&gt;Before migration, all of my data was on the QNAP NAS. I already had an SSH-enabled user account on it (called &lt;code&gt;immich&lt;/code&gt; because it was originally made to run just immich using docker-compose before I decided that running &lt;em&gt;everything&lt;/em&gt; directly using docker-compose instead of the GUI was way easier). I also had a 10Gbit ethernet link from the NAS to my desktop, and thought using that over &lt;code&gt;rsync&lt;/code&gt; would likely be the most efficient way to transfer files between the servers (by temporarily moving the other end of the link from the PC to the new server).&lt;/p&gt;
&lt;p&gt;I struggled to get a connection between the devices, though, since I &lt;em&gt;thought&lt;/em&gt; everything was set correctly and I had set a static IP for the new server using &lt;code&gt;nmcli&lt;/code&gt; and the link was up, but my pings were still failing. Eventually, after a while of online searching boogaloo (and AI rubber ducking) I found out that I had to set the static IP with &lt;code&gt;/16&lt;/code&gt; at the end to specify the correct network range (without specifying, it defaulted to &lt;code&gt;/32&lt;/code&gt; which doesn’t work). These are the commands that finally made it work:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; nmcli&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; connection&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; modify&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Wired connection 2&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ipv4.addresses&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 169.254.7.80/16&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ipv4.method&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; nmcli&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; connection&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; down&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Wired connection 2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; nmcli&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; connection&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; up&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Wired connection 2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ping&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 169.254.7.90&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; # works!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here is the command used for file transfers:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;rsync&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --progress&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -r&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; immich@169.254.7.90:/share/Share/source/dir/&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/tank/destination/dir/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a bit of research (while waiting for a single test directory to transfer), I actually found out that &lt;code&gt;rclone&lt;/code&gt; might be a more efficient option. I configured the QNAP as a remote using the interactive &lt;code&gt;rclone config&lt;/code&gt; command. Then I stopped the &lt;code&gt;rsync&lt;/code&gt; transfer and started an &lt;code&gt;rclone&lt;/code&gt; transfer with the following command:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;rclone&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sync&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; qnap:/share/Share/source/dir/&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/tank/destination/dir/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --transfers&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --checkers&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --fast-list&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  --progress&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --stats&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 10s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Can’t say much about whether it was actually faster or not since I did not measure rsync, but at least it &lt;em&gt;felt&lt;/em&gt; a bit faster. According to the terminal output, the speed was still just around 50-500MiB/s (depending on the source dataset and fluctuating constantly), but thankfully I only have to do this once.&lt;/p&gt;
&lt;p&gt;Moving the actual bulk of my personal data from one NAS to another (approx 8TiB) took around 8 hours. 1TiB/h (or rounded up around 300MiB/s on average), awesome!&lt;/p&gt;
&lt;h2 id=&quot;5-whats-a-computer&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#5-whats-a-computer&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;5. What’s a computer?&lt;/h2&gt;
&lt;p&gt;The cloud is just someone else’s computer. This computer is mine, my homeserver. Here’s some stuff I’m gonna run on it, to escape the cloud:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tailscale.com/&quot;&gt;Tailscale&lt;/a&gt;: awfully convenient remote access from anywhere using (almost) any device&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.navidrome.org/&quot;&gt;Navidrome&lt;/a&gt;: high-quality streaming for my high-quality music collection (Bandcamp FTW)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://immich.app/&quot;&gt;Immich&lt;/a&gt;: it’s like Google Photos without the overwhelming feeling that every photo I take can be viewed by the cops and Google employees for fun (or more likely, mined for personal data and AI training)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linkding.link/&quot;&gt;Linkding&lt;/a&gt;: easy bookmarking and website archival with a functional UI&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forgejo.org/&quot;&gt;Forgejo&lt;/a&gt;: fuck yeah GitHub but I own it, perfect for keeping the code of private projects safe, also comes with GitHub-compatible CI/CD&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jellyfin.org/&quot;&gt;Jellyfin&lt;/a&gt;: high-quality always available easy to use very legal streaming&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.paperless-ngx.com/&quot;&gt;Paperless-ngx&lt;/a&gt;: for storing and sorting my very important PDF documents&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://miniflux.app/&quot;&gt;Miniflux&lt;/a&gt;: it’s just a feed reader&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But since this is a NAS, undeniably the most important job I have for it is &lt;em&gt;remote file access&lt;/em&gt;. For this, there are a few different options, each with their own complicated characteristics and trade-offs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Server_Message_Block#Samba&quot;&gt;Samba&lt;/a&gt;: The Classic
&lt;ul&gt;
&lt;li&gt;Samba was originally reverse-engineered from proprietary implementations of the ancient SMB protocol, and nowadays CIFS/SMB mounts on pretty much any device, even using a fully FOSS stack. Recent versions of the protocol can perform well. It’s the only protocol I’ve every used to access files from a NAS, yet it somehow feels &lt;em&gt;wrong&lt;/em&gt;. Maybe that’s just because every single smart device I use runs a Linux kernel…&lt;/li&gt;
&lt;li&gt;Will probably end up running this if anyone other than me is ever given access to the NAS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Network_File_System&quot;&gt;NFS&lt;/a&gt;: The Linux-Native
&lt;ul&gt;
&lt;li&gt;Tightly integrated onto Linux using kernel modules and Linux-y ways to do things. Configuration seems daunting, especially the security aspect. Supposedly would offer me the best performance inside my wired home network.&lt;/li&gt;
&lt;li&gt;Will try to make it work over 10Gbit ethernet running directly between my desktop and the NAS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol&quot;&gt;SFTP&lt;/a&gt;: The Easiest
&lt;ul&gt;
&lt;li&gt;Very simple to set-up and secure, since it’s based on SSH. &lt;a href=&quot;https://obviy.us/blog/comparing-sshfs-rclone-mount/&quot;&gt;Easily mounted with &lt;code&gt;rclone&lt;/code&gt;&lt;/a&gt;, which should achieve pretty good performance as well.&lt;/li&gt;
&lt;li&gt;Will mount with this on my Linux computers first, because it’s very easy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/WebDAV&quot;&gt;WebDAV&lt;/a&gt;: The Unlikely Contender
&lt;ul&gt;
&lt;li&gt;An extension of HTTP for collaborative editing, that can effectively work as a remote file system protocol. Might be the best for clients outside my home network. Setup would be very easy with the fantastic &lt;a href=&quot;https://github.com/9001/copyparty/&quot;&gt;copyparty&lt;/a&gt; server. Never even considered using it for this purpose before seeing copyparty.&lt;/li&gt;
&lt;li&gt;Will be setting this up first as I’m probably going to be using it for mounting on my phone and as for a file browser browser interface.&lt;/li&gt;
&lt;li&gt;Update: Running copyparty as a container turned out to be impossible, since mounting nested ZFS datasets into the container crashed podman. I set up a systemd service that runs it using &lt;code&gt;uvx&lt;/code&gt; and that works great!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To settle on what protocols to use I will have to do some performance testing. This will probably involve setting up and running all protocols and servers side-by-side. I shall report on my findings at a later date.&lt;/p&gt;
&lt;h2 id=&quot;6-remote-access&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#6-remote-access&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;6. Remote access&lt;/h2&gt;
&lt;p&gt;For remote access to all services and remote data mounts on all my servers, I use &lt;a href=&quot;https://tailscale.com/&quot;&gt;Tailscale&lt;/a&gt;. It’s not perfect, but it’s very good and simple to use. Basically, with Tailscale installed and logged in on all my devices (including the TV), I can access them from anywhere through a reserved IP space (or the devices’ Tailscale DNS names). Traffic is (usually) not routed through their servers, though. Tailscale always tries to form a direct connection first, be it through the LAN or hole punching, or a public IP if a server is not covered by NAT. There are multiple solutions for this exact use case, but Tailscale just seems to be the most popular and most simple.&lt;/p&gt;
&lt;p&gt;For combining Tailscale, DNS and HTTPS I like to think I have sort of a &lt;em&gt;neat trick&lt;/em&gt; (though it was really copied from some other nerd’s blog, which I can’t seem to find right now…)&lt;/p&gt;
&lt;p&gt;The ‘trick’ is basically the following procedure:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Under a domain you own, create a DNS wildcard record pointing to the &lt;strong&gt;Tailscale IP of your server.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;I used the DNS name &lt;code&gt;*.home&lt;/code&gt; since this is my home server, and the domain is exclusively used for servers I own.&lt;/li&gt;
&lt;li&gt;You could also use a static public IP that points to the server, but I don’t want to do port forwarding or have my server out on the internet for anyone to access. Tailscale is great.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create a new Cloudflare API token based on the “Edit zone DNS” template, name it based on the name of your server, and save the token for later.
&lt;ul&gt;
&lt;li&gt;Yes, this assumes you use Cloudflare as DNS nameservers. You could probably do this with &lt;a href=&quot;https://github.com/CaddyBuilds/caddy-bunny&quot;&gt;Bunny&lt;/a&gt; and &lt;a href=&quot;https://github.com/CaddyBuilds/caddy-namecheap&quot;&gt;Namecheap&lt;/a&gt; as well. And with &lt;a href=&quot;https://letsencrypt.org/2026/02/18/dns-persist-01&quot;&gt;DNS-PERSIST-01&lt;/a&gt; and &lt;a href=&quot;https://github.com/caddyserver/caddy/issues/7495&quot;&gt;its Caddy implementation&lt;/a&gt; something similar should soon be possible with any provider. (ACME validation needs to be DNS-based if we don’t expose the server to the public internet where Let’s Encrypt could access it)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;On your server, set up &lt;a href=&quot;https://github.com/CaddyBuilds/caddy-cloudflare&quot;&gt;caddy-cloudflare&lt;/a&gt; and let it bind to ports &lt;code&gt;80&lt;/code&gt;, &lt;code&gt;443&lt;/code&gt; and &lt;code&gt;443/udp&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;To do this with unprivileged podman, you need to run &lt;code&gt;echo &quot;net.ipv4.ip_unprivileged_port_start=80&quot; | sudo tee /etc/sysctl.d/99-unprivileged-port.conf &amp;#x26;&amp;#x26; sudo sysctl --system&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Don’t forget to enable the http, https, and http3 services on your firewall! &lt;code&gt;sudo firewall-cmd --add-service http --add-service https --add-service http3&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;.env&lt;/code&gt; file with the contents &lt;code&gt;CLOUDFLARE_API_TOKEN=token-you-just-created&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;Caddyfile&lt;/code&gt; with the contents:
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 	email your.cloudflare@email.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 	acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; 	servers {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  		trusted_proxies cloudflare&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  		client_ip_headers Cf-Connecting-Ip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;Caddyfile&lt;/code&gt;, add a service that you want accessible over HTTPS on your custom domain as follows:
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cockpit.home.domain.com {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  reverse_proxy localhost:9090&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Start Caddy, wait a moment, and then go to &lt;code&gt;cockpit.home.domain.com&lt;/code&gt; (or whatever your equivalent is) on a machine logged in to your tailnet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Voilà! I think this is the simplest way to use HTTPS and a per-service custom domain all while connecting through Tailscale. You’re welcome.&lt;/p&gt;
&lt;h2 id=&quot;7-podman-compose&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#7-podman-compose&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;7. &lt;code&gt;podman compose&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I feel like a (too) little-known trick is that, even on a Fedora-based server and in a fully &lt;code&gt;podman&lt;/code&gt;-based setup, you can actually replace &lt;code&gt;docker compose&lt;/code&gt; with &lt;code&gt;podman compose&lt;/code&gt; and it will work perfectly as long as the &lt;code&gt;docker-compose&lt;/code&gt; binary is present as well. This works out of the box with the default version of ucore.&lt;/p&gt;
&lt;p&gt;Yes, &lt;a href=&quot;https://www.redhat.com/en/blog/quadlet-podman&quot;&gt;Podman Quadlets&lt;/a&gt; exists and are a perfectly, hmm, &lt;em&gt;workable&lt;/em&gt; alternative to compose, but they have a few crucial problems…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A multi-container self-hosted service requires creating one &lt;code&gt;.container&lt;/code&gt; file per container and linking them together with a &lt;code&gt;.pod&lt;/code&gt; file. Additionally, if they need internal networks, &lt;code&gt;.network&lt;/code&gt; files must be created to represent those resources, and the same applies to volumes. This can grow out of hand, especially with more complicated projects.&lt;/li&gt;
&lt;li&gt;Most self-hostable services provide a &lt;code&gt;docker-compose&lt;/code&gt; file. Most don’t provide a folder of Quadlets. I don’t want to write myself the files that run my services by manually translating undocumented &lt;code&gt;docker-compose.yml&lt;/code&gt; files to Quadlet files. Laziness is sometimes a virtue, I just want to copy-and-paste the goddamn compose file, change some mountpoints and environment variables, and be done with it.&lt;/li&gt;
&lt;li&gt;Quadlets need to be placed in &lt;code&gt;systemd&lt;/code&gt; folders alongside service units. I’d rather place them in a custom folder in my server users home directory, or in this case the &lt;code&gt;ssd&lt;/code&gt; ZFS pool, alongside the service-specific configuration files (such as &lt;code&gt;Caddyfile&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make up for the total lack of &lt;code&gt;systemd&lt;/code&gt; integration with &lt;code&gt;podman compose&lt;/code&gt;, I have written a script called &lt;code&gt;servicegen.nu&lt;/code&gt;. The script takes in a config with the following format:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# directory that contains all services in subfolders&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;composeBaseDirectory&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/base/dir/to/compose&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;compose&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;folder&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;caddy&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; # subfolder name, containing compose.yaml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    update&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; # whether to apply automatic updates&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    updateFrequency&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;daily&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; # how often to apply automatic updates (optional)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running the script, generates systemd &lt;code&gt;.service&lt;/code&gt; and &lt;code&gt;.timer&lt;/code&gt; files for running the service and updating it. Those unit files are then linked with &lt;code&gt;systemctl link&lt;/code&gt; and enabled.&lt;/p&gt;
&lt;p&gt;Here are some example units generated by the script:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# caddy.service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=caddy service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;After&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=network-online.target&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Wants&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=network-online.target&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Restart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=always&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WorkingDirectory&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/base/dir/to/compose/caddy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/podman compose up&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStop&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/podman compose down&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;TimeoutStartSec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WantedBy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=default.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# caddy-update.service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=caddy service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;After&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=network-online.target&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Wants&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=network-online.target&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=oneshot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WorkingDirectory&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/base/dir/to/compose/caddy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/podman compose pull&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/systemctl restart --user caddy.service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;TimeoutStartSec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WantedBy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=default.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# caddy-update.timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=caddy update timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Timer]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;OnCalendar&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=daily&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Persistent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Unit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=caddy-update.service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;AccuracySec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=1min&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WantedBy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=timers.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If anyone is interested in this script, feel free to &lt;a href=&quot;https://xyny.art/links&quot;&gt;hit me up&lt;/a&gt;. Your request might lead me to publishing it in some neat way. Currently I just copy-paste it between servers, lol.&lt;/p&gt;
&lt;h2 id=&quot;8-service-migration&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#8-service-migration&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;8. Service migration&lt;/h2&gt;
&lt;p&gt;To finally get some use out of my new NAS, I had to migrate the services &lt;a href=&quot;#5-whats-a-computer&quot;&gt;listed above&lt;/a&gt;, which I currently run on the QNAP with &lt;code&gt;docker-compose&lt;/code&gt;. Thankfully the process should mostly be pretty easy, since I can just copy the &lt;code&gt;compose.yaml&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; files over, while changing just the volume mount paths. The hard part is actually migrating the databases of the various services to make sure I don’t lose any user data.&lt;/p&gt;
&lt;h3 id=&quot;jellyfin&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#jellyfin&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Jellyfin&lt;/h3&gt;
&lt;p&gt;I migrated Jellyfin first, because I did not care about keeping the user data or the database in tact. According to google-fu, that could have been problematic anyways. It’s not even long since I last had to wipe the Jellyfin database completely since it just got borked somehow, lol. Thankfully I don’t care.&lt;/p&gt;
&lt;h3 id=&quot;navidrome&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#navidrome&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Navidrome&lt;/h3&gt;
&lt;p&gt;For Navidrome, I did not find any officially endorsed guides for server migration, so I just tried moving the data volume over to the new server. That of course did not work, so next I tried following the guide for &lt;a href=&quot;https://www.navidrome.org/docs/usage/admin/backup/&quot;&gt;creating and restoring a backup&lt;/a&gt;. That thankfully worked perfectly, and I learned a new command: &lt;code&gt;podman compose run &amp;#x3C;service&gt;&lt;/code&gt; for interactively running commands in compose service containers.&lt;/p&gt;
&lt;h3 id=&quot;linkding&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#linkding&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Linkding&lt;/h3&gt;
&lt;p&gt;From migrating Navidrome, I realized that migration is basically just backup+restore. To migrate Linkding, I followed the official &lt;a href=&quot;https://linkding.link/backups/&quot;&gt;backup guide&lt;/a&gt; and it worked great and was very fast and painless!&lt;/p&gt;
&lt;h3 id=&quot;immich&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#immich&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Immich&lt;/h3&gt;
&lt;p&gt;Migrating Immich through the &lt;a href=&quot;https://docs.immich.app/administration/backup-and-restore/&quot;&gt;Backup and Restore&lt;/a&gt; process was a bit slower, since it required some clicking around in the UI and moving the whole old &lt;code&gt;UPLOAD_LOCATION&lt;/code&gt; folder over (which also contained thumbnails and transcoded video). I also had problems mounting my new &lt;code&gt;UPLOAD_LOCATION&lt;/code&gt; with &lt;code&gt;:z&lt;/code&gt; for some reason, and had to resort to setting &lt;code&gt;security_opt: [label=disable]&lt;/code&gt;. Additionally, since I had previously used QNAP’s Qfile app for backing up photos from my phone, all my photos were in External Libraries in Immich. Since the paths of these libraries changed, Immich had to rescan my entire library. As a result, it lost the connection between the “new files” and “old files” and I lost my (one thankfully small) manually curated photo album and all old facial recognition data. Thankfully I had purposefully used Immich as mostly a read-only photo viewer before (due to stability concerns, since I started using it while it was not stable and did not even have a functional mobile app).&lt;/p&gt;
&lt;p&gt;Not the smoothest process, but I guess it worked out in the end.&lt;/p&gt;
&lt;h3 id=&quot;miniflux&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#miniflux&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Miniflux&lt;/h3&gt;
&lt;p&gt;Being rather minimal software, Miniflux does not have any built-in backup utilities and one needs to manually backup the Postgres database using applicable utilities instead. The &lt;a href=&quot;https://miniflux.app/faq.html#backup&quot;&gt;commands given in the FAQ&lt;/a&gt; did not even work for me, instead I had to run:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# running pg_dump inside the old db container (with the db running)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; compose&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;docker&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; exec&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -it&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; miniflux-db-1&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;pg_dump&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; miniflux&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -f&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/lib/postgresql/miniflux.dump&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -U&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; miniflux&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# running restore with psql inside the new db container (with the db running)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;podman&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; compose&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; run&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; db&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;podman&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; exec&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -it&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; miniflux-db-1&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;psql&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -U&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; miniflux&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; miniflux&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /var/lib/postgresql/miniflux.dump/miniflux.dump&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Unfortunately, this whole process did not even manage to migrate the feeds I subscribed to over to the new server. My user account was in tact along with some related settings though. I had to boot the old container back up and export the feeds as OPML from there. That was further complicated by the fact that something during the backup process something had made the database unhealthy (&lt;code&gt;PANIC:  could not locate a valid checkpoint record at B/42A80708&lt;/code&gt;), so I had to disable all healtchecks in the compose file before the containers could start up.&lt;/p&gt;
&lt;p&gt;Thankfully, the old instance still worked perfectly enough for exporting the OPML even with an unhealthy database. I guess I did not manage to properly migrate Miniflux, but at least we can always use OPML to move feed subscriptions around…&lt;/p&gt;
&lt;h3 id=&quot;paperless&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#paperless&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Paperless&lt;/h3&gt;
&lt;p&gt;The relevant &lt;a href=&quot;https://docs.paperless-ngx.com/administration/&quot;&gt;documentation&lt;/a&gt; cited using a “document exporter” and a “document importer”, but upon further reading it is clear that just moving the container data volumes over should be enough for migration. And it was! So painless.&lt;/p&gt;
&lt;h3 id=&quot;forgejo&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#forgejo&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Forgejo&lt;/h3&gt;
&lt;p&gt;All guides I found for migrating Forgejo did &lt;code&gt;forgejo dump&lt;/code&gt; and then some complicated procedures with the output, including manually restoring a Postgres db sometimes. My instance seemed to be using SQLite, though, and I was totally lost on what to do with the &lt;code&gt;.dump&lt;/code&gt; file, so I just tried &lt;code&gt;rclone&lt;/code&gt;ing the Forgejo container data volume from the QNAP to the new server, and that &lt;em&gt;just worked&lt;/em&gt;. Guess it wasn’t so complicated after all, lol.&lt;/p&gt;
&lt;h2 id=&quot;9-cool-additions&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#9-cool-additions&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;9. Cool additions&lt;/h2&gt;
&lt;p&gt;It’s impossible to set up a new server without trying out some new stuff on it.&lt;/p&gt;
&lt;h3 id=&quot;dashboard&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#dashboard&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Dashboard&lt;/h3&gt;
&lt;p&gt;I wanted a central interface that links to everything I’m running on this server, so I don’t forget about it lol. &lt;a href=&quot;https://github.com/glanceapp/glance&quot;&gt;Glance&lt;/a&gt; seemed like a good minimal solution, and I really configured it down to bare minimum:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A minimalistic light theme server dashboard, with server stats and links to all apps covered above.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; fetchpriority=&quot;auto&quot; width=&quot;1160&quot; height=&quot;1300&quot; src=&quot;https://xyny.art/_astro/eserv-home.BKbYZL2R_Z2wrCWQ.webp&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;arr&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#arr&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Arr&lt;/h3&gt;
&lt;p&gt;Yeah, that screenshot kind of gave it away. I set up the *arr stack. Previously I have been consuming media from various legal and illegal streaming sites, but nothing beats having everything local. I was previously skeptical of this stack, as searching torrent trackers and adding magnet links to qBittorrent is easy and fun, but oh did this make it ever so easier to go from “I wanna watch an obscure old movie tonight (shoutout Jodorowsky)” to watching it on the TV in a few hours.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;thought&lt;/em&gt; setup would be hard, since all the guides related to this software stack are complicated, and there are so so many components. But, with the help of some example compose files, &lt;a href=&quot;https://trash-guides.info/&quot;&gt;TRaSH-Guides&lt;/a&gt; and the &lt;a href=&quot;https://wiki.servarr.com/&quot;&gt;Servarr wiki&lt;/a&gt; it turned out to be pretty easy. Here’s my current compose file:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  radarr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;radarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/hotio/radarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;7878:7878&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PUID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PGID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;UMASK=002&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TZ=Europe/Helsinki&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;WEBUI_PORTS=7878/tcp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    volumes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_CONFIG_DIR}/radarr:/config:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_DATA_DIR}:/data:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  sonarr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;sonarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/hotio/sonarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8989:8989&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PUID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PGID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;UMASK=002&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TZ=Europe/Helsinki&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;WEBUI_PORTS=8989/tcp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    volumes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_CONFIG_DIR}/sonarr:/config:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_DATA_DIR}:/data:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  prowlarr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;prowlarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/hotio/prowlarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9696:9696&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PUID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PGID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;UMASK=002&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TZ=Europe/Helsinki&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;WEBUI_PORTS=9696/tcp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    volumes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_CONFIG_DIR}/prowlarr:/config:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  flaresolverr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/flaresolverr/flaresolverr:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;flaresolverr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;LOG_LEVEL=${LOG_LEVEL:-info}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;LOG_HTML=${LOG_HTML:-false}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TZ=Europe/Helsinki&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${PORT:-8191}:8191&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    restart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;unless-stopped&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  bazarr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;bazarr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    hostname&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;bazarr.internal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/hotio/bazarr:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    restart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;unless-stopped&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    logging&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      driver&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;json-file&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6767:6767&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PUID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PGID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TZ=Europe/Helsinki&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    volumes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_CONFIG_DIR}/bazarr:/config:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_DATA_DIR}/media:/data/media:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  qbittorrent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    container_name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;qbittorrent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/hotio/qbittorrent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    ports&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8080:8080&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    environment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PUID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;PGID=1000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;UMASK=002&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;TZ=Europe/Helsinki&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;WEBUI_PORTS=8080/tcp&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;LIBTORRENT=v1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;VPN_ENABLED=true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;VPN_CONF=wgcf-profile&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;VPN_PROVIDER=generic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;VPN_EXPOSE_PORTS_ON_LAN=8080/tcp&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    volumes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_CONFIG_DIR}/qbittorrent:/config:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;${HOST_DATA_DIR}/torrents:/data/torrents:z&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    cap_add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;NET_ADMIN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;arr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;networks&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  arr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    driver&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;bridge&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a VPN, Cloudflare Warp is the unbeatable price of free, and &lt;a href=&quot;https://github.com/ViRb3/wgcf&quot;&gt;wgcf&lt;/a&gt; makes it very easy to generate Wireguard configs without giving Cloudflare any PII. I just run &lt;code&gt;mise x aqua:ViRb3/wgcf -- wgcf register&lt;/code&gt; and &lt;code&gt;mise x aqua:ViRb3/wgcf -- wgcf generate&lt;/code&gt; in the correct directory and I’m done. (btw &lt;a href=&quot;https://mise.jdx.dev/&quot;&gt;mise&lt;/a&gt; is another useful program that lives on all my computers, server or otherwise, it’s perfect for installing or using one-off many different programs without dirtying your host system)&lt;/p&gt;
&lt;h2 id=&quot;10-snapshots-backups-and-data-integrity&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#10-snapshots-backups-and-data-integrity&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;10. Snapshots, backups, and data integrity&lt;/h2&gt;
&lt;p&gt;Last, but not least. Actually this is arguably, the most important piece of the puzzle.&lt;/p&gt;
&lt;h3 id=&quot;scrub&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#scrub&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Scrub&lt;/h3&gt;
&lt;p&gt;A simple pro-data-integrity chore was to enable the weekly scrub timers for my zpools (I think these come with ucore OOTB):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; enable&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --now&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs-scrub-weekly@ssd.timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;systemctl&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; enable&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --now&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs-scrub-weekly@tank.timer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;smart&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#smart&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;S.M.A.R.T.&lt;/h3&gt;
&lt;p&gt;Stands for Self-Monitoring, Analysis, and Reporting Technology. Used to monitor disk health n stuff. &lt;code&gt;smartd&lt;/code&gt; was already running when I checked (thanks ucore). Now (according to the internet) all that was left was to configure ZED, a system integrated into ZFS that can notify me in the event of any errors. The configuration file &lt;code&gt;/etc/zfs/zed.d/zed.rc&lt;/code&gt; was pretty self-documenting, and enabling notifications using &lt;a href=&quot;https://ntfy.sh/&quot;&gt;Ntfy&lt;/a&gt; was a breeze. I set it up to make a silent notification on my phone every time a scrub is run, so I can remain reassured that the disks are fine.&lt;/p&gt;
&lt;h3 id=&quot;snapshot&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#snapshot&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Snapshot&lt;/h3&gt;
&lt;p&gt;To set up automatic ZFS snapshots, I used &lt;a href=&quot;https://github.com/jimsalterjrs/sanoid&quot;&gt;sanoid&lt;/a&gt;, which also happens to come bundled with ucore. There was also a nice default config to take as a starting point for my own, so I did exactly that: &lt;code&gt;sudo cp /etc/sanoid/sanoid.defaults.conf /etc/sanoid/sanoid.conf&lt;/code&gt;. The default config contains one ZFS snapshot configuration template called “default” and I basically did not edit it at all, just applied the template to all the different ZFS datasets I have (according to &lt;code&gt;zfs list&lt;/code&gt;). Here’s an example of what I did for all my datasets:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[tank]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use_template&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; = default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I ran &lt;code&gt;sudo sanoid&lt;/code&gt; to test it and got &lt;code&gt;FATAL ERROR: I don&apos;t understand the setting version you&apos;ve set in [version] in /etc/sanoid/sanoid.conf&lt;/code&gt;. Well, I apparently just needed to remove the whole &lt;code&gt;[version]&lt;/code&gt; block at the top from the config, that doesn’t seem to be useful anyways. After that it just worked.&lt;/p&gt;
&lt;p&gt;To get the snapshots visible to users, I also had to run &lt;code&gt;sudo zfs set snapdir=visible tank&lt;/code&gt; for each of my datasets.&lt;/p&gt;
&lt;p&gt;Finally, I could run &lt;code&gt;sudo systemctl enable sanoid.timer --now&lt;/code&gt; and just forget about snapshots.&lt;/p&gt;
&lt;h3 id=&quot;real-backups&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#real-backups&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;Real backups&lt;/h3&gt;
&lt;p&gt;Steps thus far have made sure that my data has a greater chance of staying intact on this server. But “RAID IS NOT A BACKUP” and neither are snapshots. To survive disaster, I need to make real backups. The following two, in order, are most important in this context:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backing up &lt;code&gt;ssd/services&lt;/code&gt; (which contains all data for self-hosted services on the server, but is just a single SSD that can break and lose all data instantly) to &lt;code&gt;tank&lt;/code&gt; (the slow HDD pool)&lt;/li&gt;
&lt;li&gt;Backing up &lt;code&gt;tank&lt;/code&gt; to a separate server (be it one in my control or in “the cloud”)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://restic.net/&quot;&gt;Restic&lt;/a&gt; is a great backup solution that can do incremental deduplicated backups from pretty much any computer or server to pretty much any file storage backend. To set up my restic backups I’ve previously tested and used GUIs like &lt;a href=&quot;https://github.com/garethgeorge/backrest&quot;&gt;Backrest&lt;/a&gt;, &lt;a href=&quot;https://github.com/nicotsx/zerobyte/&quot;&gt;Zerobyte&lt;/a&gt; or &lt;a href=&quot;https://apps.gnome.org/DejaDup/&quot;&gt;Déjà Dup&lt;/a&gt; (sticking to this on my non-server machines btw), but today I felt like setting up &lt;a href=&quot;https://github.com/cupcakearmy/autorestic&quot;&gt;autorestic&lt;/a&gt; as a CLI alternative. Sure, the plain restic CLI is usable as well, but I like not knowing how to use the tools I rely on and instead using simplistic abstractions on top of them (or maybe configuration files or something idk).&lt;/p&gt;
&lt;p&gt;To install, I ran the following commands in the &lt;code&gt;core&lt;/code&gt; user’s homedirectory:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;mise&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; use&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; restic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;mise&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; use&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; github:cupcakearmy/autorestic&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works great, because both programs are self-contained binary programs.&lt;/p&gt;
&lt;p&gt;I created my &lt;code&gt;autorestic.yml&lt;/code&gt; configuration file inside a subdirectory in my main server config git repo, which also contains configuration for all apps I’m running with &lt;code&gt;podman compose&lt;/code&gt; as well as all my custom systemd units (which put to use using &lt;code&gt;systemctl --user link&lt;/code&gt;) and configuration for &lt;code&gt;copyparty&lt;/code&gt;. The configuration format is pretty simple, here’s an example for just backing up my container/service/database SSD dataset to the main backup repository on &lt;code&gt;tank&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;locations&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  ssd&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/var/ssd/services/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    to&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;backends&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;  tank&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;local&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/var/tank/e/Backup/restic&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To give the program the password to the restic repo, I also had to create &lt;code&gt;.autorestic.env&lt;/code&gt; containing &lt;code&gt;AUTORESTIC_TANK_RESTIC_PASSWORD=&amp;#x3C;password-here&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;&lt;em&gt;And that’s how I would’ve done it, foolishly, had it worked.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Fortunately, trying to run a backup with this configuration literally just made the program freeze. I tried with restic manually, and the same thing happened. I took a few-day break, and when I came back to the problem I tried to comb through the internet for advice, and learned in the process that this is not at all how one should do backups of ZFS datasets, especially ones with active databases on them.&lt;/p&gt;
&lt;p&gt;The better, so called &lt;em&gt;atomic&lt;/em&gt; way, is to take the backups from ZFS snapshots. This makes sure the data doesn’t change while a backup is running.&lt;/p&gt;
&lt;p&gt;The even better way is to treat ZFS snapshots &lt;em&gt;as the backups&lt;/em&gt; and send them around using &lt;code&gt;zfs send&lt;/code&gt; or &lt;code&gt;syncoid&lt;/code&gt;. This allows ZFS to handle pretty much all parts of the process, including deduplication and data integrity.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;syncoid&lt;/code&gt; comes pre-installed on ucore and has a bit nice UX, so I opted to use that for backing up the &lt;code&gt;ssd/services&lt;/code&gt; dataset. I created a new ZFS dataset on the &lt;code&gt;tank&lt;/code&gt; pool for this purpose, at &lt;code&gt;tank/ZFSBackup&lt;/code&gt; and ran &lt;code&gt;syncoid ssd/services tank/ZFSBackup/services&lt;/code&gt; to initiate a first backup.&lt;/p&gt;
&lt;p&gt;To automate these backups I created a systemd &lt;code&gt;.service&lt;/code&gt; and &lt;code&gt;.timer&lt;/code&gt; and enabled the timer (again, pretty much just following instructions from the ucore README):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# syncoid-ssd.service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=syncoid ssd to tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=oneshot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/bash -c &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;syncoid ssd/services tank/ZFSBackup/services&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# syncoid-ssd.timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=syncoid ssd to tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Timer]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;OnBootSec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=1min&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;OnUnitActiveSec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=6h&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WantedBy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=timers.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For backing up &lt;code&gt;tank&lt;/code&gt;, I unfortunately could not use this simpler method, since I do not have a ZFS backup target available. For this, I still had to figure out how to combine Restic and ZFS snapshots. To learn &lt;em&gt;how&lt;/em&gt;, I had to read a bunch of stuff on the topic including &lt;a href=&quot;https://www.aarsen.me/posts/2022-02-15-sweet-unattended-backups.html&quot;&gt;this blog post&lt;/a&gt;, &lt;a href=&quot;https://forum.restic.net/t/backup-from-zfs-snapshot/10490&quot;&gt;this restic forum thread&lt;/a&gt;, &lt;a href=&quot;https://github.com/restic/restic/issues/3557&quot;&gt;this GitHub thread&lt;/a&gt; and &lt;a href=&quot;https://gist.github.com/stackcoder/ccb3b17812ed11700ee83d762b970b98&quot;&gt;this GitHub Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I learned that Restic doesn’t yet have a good way to associate backups taken from different paths with each other, so they should not be taken from the always mounted &lt;code&gt;.zfs/snapshots/&amp;#x3C;snapshotname&gt;&lt;/code&gt; path. The better way is to instead mount the snapshot to a stable path. This mounting is the only part of the script that requires &lt;code&gt;sudo&lt;/code&gt;, but &lt;a href=&quot;https://forum.restic.net/t/naming-snapshots-and-the-benefts-thereof/8391&quot;&gt;hopefully&lt;/a&gt; &lt;a href=&quot;https://github.com/restic/restic/issues/4026&quot;&gt;restic&lt;/a&gt; &lt;a href=&quot;https://github.com/restic/restic/pull/3200&quot;&gt;will&lt;/a&gt; &lt;a href=&quot;https://github.com/restic/restic/issues/1376&quot;&gt;soon&lt;/a&gt; &lt;a href=&quot;https://github.com/restic/restic/issues/2714&quot;&gt;fix&lt;/a&gt; &lt;a href=&quot;github.com/restic/restic/issues/3557&quot;&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then I rolled my own backup wrapper based on these principles using Nushell (which I love). Here’s (the first MVP version of) what I ended up with:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;nu&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# zfs-restic.nu&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;#!/usr/bin/env nu&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; datasets &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;	&quot;tank/e/Garden&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;	&quot;tank/e/DCIM&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;	# etc... define all datasets to back up here&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tempMountpoint &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;/var/zfs-snapshot/&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; restic &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	repo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;rclone:qnap:/share/restic&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	passwordFile&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;/var/home/core/.qnap-restic-pw.txt&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hostname &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; open&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /etc/hostname&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; backup&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;dataset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; snapshotName &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;restic-(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;date now&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; format date&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;%Y-%m-%d_%H:%M:%S&quot;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	^&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; snap&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$dataset&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)@(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$snapshotName&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;Created zfs snapshot (&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$dataset&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)@(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$snapshotName&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; backupPath &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $tempMountpoint &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $dataset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;Mounting snapshot at (&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$backupPath&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)...&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	^&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; mkdir&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $backupPath&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	^&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; mount&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$dataset&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)@(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$snapshotName&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $backupPath&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;Backing up (&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$backupPath&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)...&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;		(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;restic&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; backup&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $backupPath&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--exclude&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; .cache&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--exclude-caches&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--exclude-if-present&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; .resticexclude&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--verbose&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--host&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $hostname &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--tag&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; zfs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--tag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $dataset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--repo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $restic.repo &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;			--password-file&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $restic.passwordFile)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	} &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;		print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Ran into error while backing up&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	} &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;finally&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;		print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Cleaning up...&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;		^&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; umount&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $backupPath&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;		print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;Unmounted zfs snapshot (&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$backupPath&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;		zfs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$dataset&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)@(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$snapshotName&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;		print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;Destroyed zfs snapshot (&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$dataset&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)@(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$snapshotName&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; forget&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;dataset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; $&quot;Forgetting old restic snapshots of (&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$dataset&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;restic&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; forget&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--keep-daily&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 14&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--keep-monthly&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--keep-yearly&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--verbose&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--tag&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; zfs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--tag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $dataset &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--repo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $restic.repo &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;		--password-file&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $restic.passwordFile)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Subcommands&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;   backup: back up all configured datasets&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	print&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;   forget: remove old backups for all configured datasets&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; &quot;main backup&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; dataset &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $datasets {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;		backup&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $dataset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; &quot;main forget&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [] {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;	for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; dataset &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $datasets {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;		forget&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $dataset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, all that was left was to make this script run automatically using systemd. However, since it needs to be a system-level service, and I wanted it to be set-it-and-forget-it and such, it felt off calling the &lt;code&gt;nu&lt;/code&gt; and &lt;code&gt;restic&lt;/code&gt; binaries installed by &lt;a href=&quot;https://mise.jdx.dev/&quot;&gt;Mise&lt;/a&gt; into the admin users home directory. Since Fedora CoreOS / ucore is an “atomic” / “image-based” / “immutable” distribution, I got to build a personal custom image for my server as well, yay! This is actually very easy, especially with the tools I’m working on to make it way easier: &lt;a href=&quot;https://blue-build.org/&quot;&gt;BlueBuild&lt;/a&gt;. I just created this so-called recipe file in my &lt;a href=&quot;https://github.com/xynydev/linuXYZ/&quot;&gt;pre-existing custom image repository&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# yaml-language-server: $schema=https://schema.blue-build.org/recipe-v1.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;modules&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;dnf&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    repos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      copr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        enable&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;jdxcode/mise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    install&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;      packages&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;restic&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        - &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;mise&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;   # the nushell version in fedora repos is too old&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  - &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;copy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    from&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;ghcr.io/nushell/nushell:latest-alpine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    src&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/usr/bin/nu&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;    dest&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/usr/bin/nu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After adding that file to my GitHub Workflow build matrix and pushing, all I had to do was wait for the image to build and to switch to it on my server using &lt;code&gt;sudo bootc switch ghcr.io/xynydev/eserv&lt;/code&gt;. After rebooting, both &lt;code&gt;nu&lt;/code&gt; and &lt;code&gt;restic&lt;/code&gt; were now available, and I could create a systemd &lt;code&gt;.service&lt;/code&gt; and &lt;code&gt;.timer&lt;/code&gt; for running the backups, pretty much in exactly the same way as I did for syncoid.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# zfs-restic.service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=restic backup tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=oneshot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/nu /var/ssd/services/eserv-home/zfs-restic/zfs-restic.nu backup&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;ExecStart&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=/usr/bin/nu /var/ssd/services/eserv-home/zfs-restic/zfs-restic.nu forget&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;# zfs-restic.timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Description&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=restic backup tank&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Timer]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;OnBootSec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=1min&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;OnUnitActiveSec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=6h&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;WantedBy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=timers.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, to get these to work, all I had to do was re-create the &lt;code&gt;qnap&lt;/code&gt; rclone remote using &lt;code&gt;sudo rclone config&lt;/code&gt; and enable the &lt;code&gt;.timer&lt;/code&gt; unit.&lt;/p&gt;
&lt;h2 id=&quot;11-conclusion&quot;&gt;&lt;a class=&quot;header-anchor-link&quot; href=&quot;#11-conclusion&quot;&gt;&lt;span class=&quot;icon icon-link&quot;&gt;&lt;/span&gt;&lt;/a&gt;11. Conclusion&lt;/h2&gt;
&lt;p&gt;And there it was! A full-featured homeserver / NAS build, that only took maybe around a week to complete, and would have taken less if I had focused on it and only it.&lt;/p&gt;
&lt;p&gt;Obviously, this is not for everyone. Most people are busy, so they just buy into a brand of appliance NAS (or a commercial cloud offering) and forget about it. That’s totally valid. As a hobbyist, though, I want to know how everything on my servers and desktops works and how I could set it up from scratch all over again. To be in control. No mindless clicking through UIs to figure things out, but configuration files and documentation, please. Having something as important as all of my personal files stored on something that I do not know the ins and outs of is just a bit anxiety-inducing.&lt;/p&gt;
&lt;p&gt;And most important, this was really fun! If you have the time and energy, I really suggest learning how all the puzzle pieces come together, be it on a homeserver project like this or any other thing you want to nerd about. Figuring things out is one of the most rewarding experiences in life, and I would not consider giving up that in favour of a boring default consumer appliance or an uncustomizable operating system, or having an AI-agent do everything for me.&lt;/p&gt;
&lt;p&gt;I hope you learned something here as well. If you liked it, &lt;a href=&quot;https://xyny.art/links&quot;&gt;follow me everywhere I guess&lt;/a&gt;, &lt;a href=&quot;https://xyny.art/blog/feed.xml&quot;&gt;subscribe to this “blog” using RSS&lt;/a&gt;, and go out onto a busy square or street to shout compliments about the post.&lt;/p&gt;</content:encoded><category>server</category><category>selfhosting</category><enclosure url="https://xyny.art/_astro/eserv.DSCiEd_b.png" length="0" type="image/png"/></item></channel></rss>