<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Robin Reinecke</title>
    <description>The latest articles on DEV Community by Robin Reinecke (@robinreinecke).</description>
    <link>https://dev.to/robinreinecke</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4016116%2Fa6eec291-7077-4dbb-b4bd-9d284cceb855.jpg</url>
      <title>DEV Community: Robin Reinecke</title>
      <link>https://dev.to/robinreinecke</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robinreinecke"/>
    <language>en</language>
    <item>
      <title>Using My Server's Built-In GPU for Jellyfin and Immich</title>
      <dc:creator>Robin Reinecke</dc:creator>
      <pubDate>Thu, 08 Oct 2026 07:46:14 +0000</pubDate>
      <link>https://dev.to/robinreinecke/using-my-servers-built-in-gpu-for-jellyfin-and-immich-52of</link>
      <guid>https://dev.to/robinreinecke/using-my-servers-built-in-gpu-for-jellyfin-and-immich-52of</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/blog/2026-09-28-deploying-my-home-server-with-komodo"&gt;last post&lt;/a&gt;, I mentioned that Jellyfin and Immich use the graphics hardware inside my server's processor.&lt;br&gt;
That sentence skips the interesting part.&lt;br&gt;
My Docker containers run inside a Debian virtual machine on Proxmox, while the graphics hardware belongs to the physical server.&lt;br&gt;
I had to get the device across both boundaries before either app could use it.&lt;br&gt;
And yes, I know that by using Linux Containers (LXC) I could have avoided the VM and easily share the GPU.&lt;br&gt;
I will explain my reasons against that in this post.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why these apps need a GPU
&lt;/h2&gt;

&lt;p&gt;When a Jellyfin client can play a file as it is, the server sends the original file and does very little work.&lt;br&gt;
Jellyfin calls that &lt;a href="https://jellyfin.org/docs/general/post-install/transcoding/" rel="noopener noreferrer"&gt;Direct Play&lt;/a&gt;.&lt;br&gt;
But a Fire TV stick might not understand the video's codec, the way it was compressed.&lt;br&gt;
A remote connection might also be too slow for its bitrate, the amount of data the video needs each second.&lt;br&gt;
If Jellyfin has to convert the video, it decodes the original and encodes a new stream while someone is watching.&lt;br&gt;
That is transcoding, a bit like translating a conversation in real time: read one format, produce another, and keep up with the speaker.&lt;/p&gt;

&lt;p&gt;The Intel Core i5-14500 in this server has a UHD 770 GPU built into the processor.&lt;br&gt;
That makes it an integrated GPU, or iGPU, rather than a separate card.&lt;br&gt;
Its &lt;a href="https://www.intel.com/content/www/us/en/docs/oneapi/optimization-guide-gpu/2025-2/media-engine-hardware.html" rel="noopener noreferrer"&gt;media engine&lt;/a&gt; has dedicated hardware for video decoding and encoding, which Intel calls Quick Sync Video.&lt;br&gt;
The CPU can do the conversion in software, but handing supported video work to that hardware leaves the CPU with much less to do.&lt;br&gt;
It also means I do not need a separate graphics card just to make a video playable on a tablet.&lt;/p&gt;

&lt;p&gt;Immich has two different reasons to use the same GPU.&lt;br&gt;
Its server can use &lt;a href="https://docs.immich.app/features/hardware-transcoding/" rel="noopener noreferrer"&gt;Quick Sync to convert videos&lt;/a&gt; for playback.&lt;br&gt;
Its machine learning container can use &lt;a href="https://docs.immich.app/features/ml-hardware-acceleration/" rel="noopener noreferrer"&gt;OpenVINO&lt;/a&gt;, Intel's toolkit for running machine learning models, to run Smart Search and face recognition on the GPU's compute side.&lt;br&gt;
Quick Sync is the video tool here, not the thing that recognizes faces.&lt;br&gt;
The names matter because a working video transcode does not prove that photo search is using the GPU.&lt;/p&gt;

&lt;p&gt;&lt;a href="/images/home-server-gpu-path.svg" class="article-body-image-wrapper"&gt;&lt;img src="/images/home-server-gpu-path.svg" alt="The processor's GPU passes through Proxmox into a Debian VM, where Docker gives Jellyfin and two Immich containers access to its video and compute engines."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting the GPU from Proxmox into Debian
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.proxmox.com/en/products/proxmox-virtual-environment/overview" rel="noopener noreferrer"&gt;Proxmox&lt;/a&gt; runs directly on the physical server.&lt;br&gt;
It runs my Debian virtual machine, which in turn runs Docker and the apps.&lt;br&gt;
The first goal was to make the UHD 770 appear inside Debian.&lt;br&gt;
Until that worked, adding &lt;code&gt;/dev/dri&lt;/code&gt; to a Compose file would be like giving Jellyfin directions to a room that did not exist.&lt;/p&gt;

&lt;p&gt;I considered running the GPU apps in a separate LXC instead.&lt;br&gt;
But that would have meant additional complexity: a second network, a second set of mounts, and a second Komodo stack to manage.&lt;br&gt;
Putting all my GPU-using apps in the same Debian VM was simpler in so many regards.&lt;/p&gt;

&lt;p&gt;I gave the whole GPU to that VM through &lt;a href="https://github.com/proxmox/pve-docs/blob/master/qm-pci-passthrough.adoc" rel="noopener noreferrer"&gt;PCI passthrough&lt;/a&gt;.&lt;br&gt;
That means the Proxmox host stops using the device and the VM gets direct access to it.&lt;/p&gt;

&lt;p&gt;Before changing the VM, I checked two things on the Proxmox host: whether the machine could isolate a device for passthrough, and which device was actually the GPU.&lt;br&gt;
The BIOS already had VT-d enabled, which is Intel's switch for that isolation.&lt;br&gt;
These commands confirmed that the host saw it and found the GPU:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dmesg | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; DMAR &lt;span class="nt"&gt;-e&lt;/span&gt; IOMMU
lspci &lt;span class="nt"&gt;-nn&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; vga
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first command showed that the IOMMU was active.&lt;br&gt;
An IOMMU keeps a device handed to a VM from reading arbitrary host memory.&lt;br&gt;
The second command identified my GPU at PCI address &lt;code&gt;00:02.0&lt;/code&gt;, with device ID &lt;code&gt;[8086:4680]&lt;/code&gt;.&lt;br&gt;
The address says where it is; the ID says what it is.&lt;br&gt;
Those numbers matter in the next commands, but they will differ on another machine.&lt;/p&gt;

&lt;p&gt;I also checked the GPU's IOMMU group, the set of devices the host can safely hand over together.&lt;br&gt;
Mine was alone in group &lt;code&gt;0&lt;/code&gt;, so I was not about to give the VM a network or storage controller along with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /sys/kernel/iommu_groups/0/devices/
lspci &lt;span class="nt"&gt;-nnk&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; 8086:4680
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The directory contained only &lt;code&gt;0000:00:02.0&lt;/code&gt;.&lt;br&gt;
The &lt;code&gt;lspci&lt;/code&gt; output had no &lt;code&gt;Kernel driver in use:&lt;/code&gt; line for the GPU, which made it look free.&lt;br&gt;
I tried handing it to the VM, but it was not quite free.&lt;br&gt;
The simple display system used during boot, called the firmware framebuffer, still had a hold on it even though the usual Intel graphics driver, &lt;code&gt;i915&lt;/code&gt;, had not started.&lt;br&gt;
My first reboot taught me that a blank driver line does not mean nobody owns the screen.&lt;br&gt;
I also tried a &lt;code&gt;softdep i915 pre: vfio-pci&lt;/code&gt; rule to load the passthrough driver before &lt;code&gt;i915&lt;/code&gt;.&lt;br&gt;
That rule only runs when &lt;code&gt;i915&lt;/code&gt; loads, and on this host it never did.&lt;br&gt;
There went another reboot.&lt;br&gt;
The working setup needed to release the boot display and load the passthrough driver directly.&lt;/p&gt;

&lt;p&gt;The goal was to make Proxmox leave the GPU alone and let the &lt;code&gt;vfio-pci&lt;/code&gt; driver reserve it for the VM.&lt;br&gt;
On the Proxmox host, I kept the existing single line in &lt;code&gt;/etc/kernel/cmdline&lt;/code&gt; and added these flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intel_iommu=on iommu=pt initcall_blacklist=sysfb_init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first two keep the IOMMU enabled and set its passthrough mode.&lt;br&gt;
The last one was the fix for this machine: it stops the early framebuffer from claiming the GPU.&lt;br&gt;
The device ID also went into &lt;code&gt;/etc/modprobe.d/vfio.conf&lt;/code&gt; so &lt;code&gt;vfio-pci&lt;/code&gt; would claim this specific GPU, while &lt;code&gt;/etc/modprobe.d/blacklist-gpu.conf&lt;/code&gt; kept the host's Intel graphics drivers away:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# /etc/modprobe.d/vfio.conf
options vfio-pci ids=8086:4680 disable_vga=1

# /etc/modprobe.d/blacklist-gpu.conf
blacklist i915
blacklist xe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the &lt;code&gt;softdep&lt;/code&gt; rule never ran, I listed the VFIO modules explicitly in &lt;code&gt;/etc/modules&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vfio
vfio_iommu_type1
vfio_pci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After changing the boot line and modules, I rebuilt the boot files and restarted the host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;update-initramfs &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; all
&lt;span class="nb"&gt;sudo &lt;/span&gt;proxmox-boot-tool refresh
&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Over SSH, &lt;code&gt;lspci -nnk -d 8086:4680&lt;/code&gt; now reported &lt;code&gt;Kernel driver in use: vfio-pci&lt;/code&gt;.&lt;br&gt;
That was the host-side result I needed before attaching the GPU to the VM.&lt;br&gt;
In Proxmox, I opened the Debian VM, chose &lt;strong&gt;Hardware → Add → PCI Device&lt;/strong&gt;, and selected &lt;code&gt;0000:00:02.0&lt;/code&gt;.&lt;br&gt;
I left &lt;strong&gt;Primary GPU&lt;/strong&gt; unchecked so the VM kept its normal browser console.&lt;/p&gt;

&lt;p&gt;Finally, I checked from inside Debian rather than assuming the Proxmox setting had worked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; /dev/dri
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;vainfo intel-gpu-tools
vainfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/dev/dri/renderD128&lt;/code&gt; was present, and &lt;code&gt;vainfo&lt;/code&gt; listed the UHD 770's video capabilities.&lt;br&gt;
At this point the VM could use the GPU, but Docker still needed its own device mapping and permissions.&lt;br&gt;
The physical monitor on the host went dark after boot because its GPU now belonged to the VM.&lt;br&gt;
SSH, the Proxmox web UI, and the VM's separate browser console still worked.&lt;br&gt;
Seeing the monitor go black was finally good news, although it took me a moment to appreciate it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Giving the containers access
&lt;/h2&gt;

&lt;p&gt;Docker normally hides host devices from a container.&lt;br&gt;
The Jellyfin Compose file opens the last two doors like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;jellyfin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;devices&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/dev/dri:/dev/dri&lt;/span&gt;
    &lt;span class="na"&gt;group_add&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;992'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The device mapping makes the VM's GPU files visible inside Jellyfin.&lt;br&gt;
The group entry grants access to &lt;code&gt;renderD128&lt;/code&gt;, the file applications use for GPU work.&lt;br&gt;
&lt;code&gt;992&lt;/code&gt; is the numeric ID of the &lt;code&gt;render&lt;/code&gt; group &lt;strong&gt;inside this Debian VM&lt;/strong&gt;.&lt;br&gt;
It is not a magic Intel number, and copying it from this post into another machine is a good way to get a permission error.&lt;br&gt;
I got it with &lt;code&gt;stat -c '%g' /dev/dri/renderD128&lt;/code&gt; in the VM.&lt;/p&gt;

&lt;p&gt;I then enabled Intel Quick Sync in Jellyfin's playback settings and forced a video to transcode.&lt;br&gt;
Jellyfin reported &lt;code&gt;Transcoding (hw)&lt;/code&gt;, while &lt;code&gt;intel_gpu_top&lt;/code&gt; inside the VM showed Video engine activity and the CPU stayed near idle.&lt;br&gt;
That combination is stronger evidence than a container starting successfully or a GPU appearing in &lt;code&gt;ls /dev/dri&lt;/code&gt;.&lt;br&gt;
If the CPU were busy and the Video engine idle, I would check the FFmpeg log and the render group before calling the setup done.&lt;/p&gt;

&lt;p&gt;Immich's &lt;code&gt;immich-server&lt;/code&gt; has the same device mapping for Quick Sync video conversion.&lt;br&gt;
Its separate &lt;code&gt;immich-machine-learning&lt;/code&gt; container uses an OpenVINO image and the GPU for Smart Search and face recognition.&lt;br&gt;
The test for that second path is different: run a search or face detection job and look for activity on the GPU's Render or Compute engine.&lt;br&gt;
One physical chip is doing two kinds of work, but they are different paths through it.&lt;/p&gt;

&lt;p&gt;The useful outcome is that Jellyfin can convert a video without tying up the general-purpose CPU, and Immich is wired to use the same chip for video and image tasks.&lt;br&gt;
When a client can Direct Play, I still want it to do that.&lt;br&gt;
The fastest transcode is the one the server never has to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;This GPU setup made the services faster, but it does not answer the question that started this rebuild: what happens when a disk dies or the whole server stops working?&lt;br&gt;
Next I want to show how I back up the VM and the data it depends on.&lt;br&gt;
I also want to explain why DNS lives outside this VM.&lt;/p&gt;

</description>
      <category>homeserver</category>
      <category>selfhosting</category>
      <category>proxmox</category>
      <category>jellyfin</category>
    </item>
    <item>
      <title>Starting Over on My Home Server</title>
      <dc:creator>Robin Reinecke</dc:creator>
      <pubDate>Tue, 22 Sep 2026 06:19:15 +0000</pubDate>
      <link>https://dev.to/robinreinecke/starting-over-on-my-home-server-520a</link>
      <guid>https://dev.to/robinreinecke/starting-over-on-my-home-server-520a</guid>
      <description>&lt;p&gt;My old home server worked fine, which is exactly why it was a problem.&lt;/p&gt;

&lt;p&gt;It was an Ubuntu box that had grown organically over a couple of years.&lt;br&gt;
A dozen or so Docker Compose files, each in its own folder, each edited in place over SSH whenever something needed changing.&lt;br&gt;
Immich for photos, Jellyfin for media, Nextcloud, Vaultwarden, the usual self-hosted suspects.&lt;br&gt;
Nothing was broken.&lt;br&gt;
But nothing was written down either, and that is a different kind of broken that only shows up on the day you need it.&lt;/p&gt;

&lt;p&gt;The thing I could never answer honestly was a simple one: if this disk died tonight, how long until everything is back?&lt;br&gt;
The truthful answer was "a weekend, if I remember everything", and the part that bothered me was "if I remember".&lt;br&gt;
The state of the server lived in the server.&lt;br&gt;
There was no copy of the truth anywhere else, only my memory of which config I had hand-edited three months ago and never wrote down.&lt;/p&gt;

&lt;p&gt;This is the first post in a series about rebuilding that setup properly.&lt;br&gt;
Not because the old one was on fire, but because I wanted the boring kind of infrastructure that you can rebuild from a git repo instead of from memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with a server you edit in place
&lt;/h2&gt;

&lt;p&gt;When you SSH into a box and edit a compose file, the change is live the moment you save it.&lt;br&gt;
That feels great right up until you have twenty of those changes spread across a year.&lt;/p&gt;

&lt;p&gt;The running state and any version you might have committed drift apart silently.&lt;br&gt;
You bump an image tag to fix something at 11pm, it works, and you never write it down.&lt;br&gt;
Three months later you have no idea whether the file on disk matches the last thing you thought you deployed.&lt;br&gt;
There is no diff to look at, because there is nothing to diff against.&lt;/p&gt;

&lt;p&gt;Backups help, but a backup of a mystery is still a mystery.&lt;br&gt;
Restoring a &lt;code&gt;docker-compose.yml&lt;/code&gt; tells you what was running.&lt;br&gt;
It does not tell you why that image is pinned to an odd version, or which environment variable exists to work around a bug you fixed and forgot.&lt;/p&gt;

&lt;p&gt;I wanted the opposite of that.&lt;br&gt;
I wanted a setup where the answer to "what is running and why" is a repository I can read, and where getting back to a working state is a checkout and a deploy, not an archaeology project.&lt;/p&gt;

&lt;h2&gt;
  
  
  One rule, everything else follows
&lt;/h2&gt;

&lt;p&gt;The whole rebuild comes down to a single rule: the git repo is the single source of truth, and nothing runs that is not defined there.&lt;/p&gt;

&lt;p&gt;That sounds obvious written down.&lt;br&gt;
In practice it is the rule that kills the 11pm SSH edit, because an edit that only lives on the server violates it.&lt;br&gt;
If I want to change something, I change it in the repo, commit it, and let the server converge to match.&lt;br&gt;
The server stops being a place I log into and becomes a place that runs whatever the repo says.&lt;/p&gt;

&lt;p&gt;The one exception I allowed myself is secrets, which never touch the repo.&lt;br&gt;
Passwords, API keys, and tokens live outside git and get injected at deploy time.&lt;br&gt;
Everything else, every service definition, every pinned version, every mount path, is a file I can read in a pull request.&lt;/p&gt;

&lt;p&gt;Once that rule is fixed, most of the other decisions make themselves.&lt;br&gt;
The deployment tool has to read from git.&lt;br&gt;
Configuration has to be declarative.&lt;br&gt;
Anything that cannot be expressed as a file in the repo needs a very good reason to exist, and gets documented as an exception rather than smuggled in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of the new setup
&lt;/h2&gt;

&lt;p&gt;The base is &lt;a href="https://www.proxmox.com/" rel="noopener noreferrer"&gt;Proxmox&lt;/a&gt;, which turns one physical machine into a hypervisor I can carve into VMs and containers.&lt;br&gt;
On top of that runs a single Debian VM with Docker, and that VM holds nearly all the services.&lt;/p&gt;

&lt;p&gt;Deployment is handled by &lt;a href="https://komo.do/" rel="noopener noreferrer"&gt;Komodo&lt;/a&gt;, which watches the repo and deploys the compose stacks from it.&lt;br&gt;
Push a commit, and the server converges to match.&lt;br&gt;
No SSH, no manual &lt;code&gt;docker compose up&lt;/code&gt;, no wondering whether the running state matches the file.&lt;br&gt;
The repo is the truth, Komodo makes reality agree with it, and I get a web UI to check status from the couch instead of a terminal.&lt;/p&gt;

&lt;p&gt;I went with a proper little machine this time.&lt;br&gt;
An Intel i5-14500, picked specifically for its Quick Sync video engine so Jellyfin can transcode 4K without melting the CPU.&lt;br&gt;
64GB of RAM, and two WD Black SN850X 2TB drives in a ZFS mirror so a single dead disk is an inconvenience and not an incident.&lt;br&gt;
It idles at around 35°C and tops out at 58°C under a stress test, which is quieter and cooler than I expected from a compact case stuffed this full.&lt;/p&gt;

&lt;p&gt;I had this exact parts list sitting in a cart about a year ago, when it would have cost me roughly half.&lt;br&gt;
Then I decided to wait a little, for reasons I can no longer reconstruct, and the market decided to wait right back.&lt;br&gt;
DDR4 and NVMe prices went the wrong way in the meantime, so a few components ended up costing more than twice what they would have, and the RAM in particular now feels like a small act of financial self-harm.&lt;br&gt;
There is no lesson here, other than that "I will buy it next month" is not a procurement strategy.&lt;/p&gt;

&lt;p&gt;There is a lot more to say about each of those choices, which is rather the point of making this a series.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is coming
&lt;/h2&gt;

&lt;p&gt;Over the next few posts I want to go into the parts that actually took thought and the ones that ate an afternoon.&lt;/p&gt;

&lt;p&gt;The GitOps model with Komodo, and why I picked it over just running Portainer or writing an Ansible playbook.&lt;br&gt;
Passing the Intel iGPU into the Docker VM for hardware transcoding, which sounds like one checkbox and is not.&lt;br&gt;
Backups that I actually trust, including the offsite copy that ended up being a second small machine at another house rather than a rented bucket.&lt;br&gt;
And the failure-domain thinking that decided DNS should live outside all of this, because the one service the whole house needs is the one you do not want sharing fate with your busiest VM.&lt;/p&gt;

&lt;p&gt;The goal was never a clever server.&lt;br&gt;
It was a boring one, in the good sense: something I can reason about, rebuild from a repo, and then mostly forget about.&lt;br&gt;
The rest of the series is how I got there, decisions I am happy with and the ones I had to walk back included.&lt;/p&gt;

</description>
      <category>homeserver</category>
      <category>selfhosting</category>
      <category>proxmox</category>
    </item>
  </channel>
</rss>
