<?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: Pan M.</title>
    <description>The latest articles on DEV Community by Pan M. (@panosm).</description>
    <link>https://dev.to/panosm</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%2F4174685%2F9c53b84b-7940-4544-abdb-0cc4a22900aa.jpg</url>
      <title>DEV Community: Pan M.</title>
      <link>https://dev.to/panosm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/panosm"/>
    <language>en</language>
    <item>
      <title>How I monitor my entire home network for free - no port forwarding, no VPN</title>
      <dc:creator>Pan M.</dc:creator>
      <pubDate>Sat, 10 Oct 2026 06:19:25 +0000</pubDate>
      <link>https://dev.to/panosm/how-i-monitor-my-entire-home-network-for-free-no-port-forwarding-no-vpn-2jk9</link>
      <guid>https://dev.to/panosm/how-i-monitor-my-entire-home-network-for-free-no-port-forwarding-no-vpn-2jk9</guid>
      <description>&lt;p&gt;After a power outage took out half my containers and I didn't notice for hours, I decided I needed proper uptime monitoring. Here's how I got it for free, without opening a single inbound port.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I run a home server I call "mother" — Fedora Linux, Podman, about 10 containers:&lt;br&gt;
Home Assistant, Frigate NVR, AdGuard Home, Mosquitto MQTT, Nginx Proxy Manager and a few others.&lt;/p&gt;

&lt;p&gt;For a long time I had zero visibility into whether things were actually running.&lt;br&gt;
After a power outage I found out half my containers hadn't come back up — only discovered it when my automations stopped working hours later.&lt;/p&gt;

&lt;p&gt;I looked at existing monitoring tools but hit the same wall every time: they're either cloud-only (can't reach 192.168.0.x private IPs) or they require you to open inbound ports to your network. Neither option worked for me.&lt;/p&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;I found &lt;a href="https://github.com/monitorion/monitorion-worker" rel="noopener noreferrer"&gt;Monitorion's private worker&lt;/a&gt;&lt;br&gt;
— MIT licensed, runs in Docker, and flips the model entirely.&lt;/p&gt;

&lt;p&gt;Instead of the cloud poking your services from outside, a lightweight agent runs&lt;br&gt;
&lt;strong&gt;inside your network&lt;/strong&gt; and pushes results outward. No inbound ports. No tunnels.&lt;br&gt;
No VPN. Just outbound HTTPS to the platform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Home Network]                    [Monitorion Cloud]

  home-assistant:8123  ──┐
  frigate:5000         ──┤
  adguard:3000         ──┼──► dashboard + alerts
  router (192.168.0.1) ──┤
  NAS (192.168.0.108)  ──┘

  ↑ all checks run from inside your network
  ↑ no inbound ports required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup — under 5 minutes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Create a free account at app.monitorion.com&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Go to Settings → Private Workers → Add Worker and copy your &lt;code&gt;wkr_…&lt;/code&gt; key&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Add this to your &lt;code&gt;docker-compose.yaml&lt;/code&gt;:&lt;/strong&gt;&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;monitorion-worker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/monitorion/monitorion-worker:latest&lt;/span&gt;
  &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;monitorion-worker&lt;/span&gt;
  &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
  &lt;span class="na"&gt;cap_add&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NET_RAW&lt;/span&gt;   &lt;span class="c1"&gt;# required for ping checks&lt;/span&gt;
  &lt;span class="na"&gt;cap_drop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ALL&lt;/span&gt;
  &lt;span class="na"&gt;security_opt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;no-new-privileges:true&lt;/span&gt;
  &lt;span class="na"&gt;read_only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=16m&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONITORION_PLATFORM_URL=https://app.monitorion.com&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONITORION_API_KEY=wkr_xxxxxxxxxxxx&lt;/span&gt;   &lt;span class="c1"&gt;# paste your key here&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;WORKER_NAME=mother&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run it:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;docker compose up -d monitorion-worker&lt;/p&gt;

&lt;p&gt;The worker registers itself with the platform, polls for jobs every 15 seconds,runs the checks, and pushes results out. Done.&lt;/p&gt;

&lt;p&gt;What I'm monitoring now&lt;/p&gt;

&lt;p&gt;All private IPs, all from inside the LAN:&lt;/p&gt;

&lt;p&gt;HTTP checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AdGuard Home (:3000)&lt;/li&gt;
&lt;li&gt;Home Assistant (:8123)&lt;/li&gt;
&lt;li&gt;Frigate NVR (:5000)&lt;/li&gt;
&lt;li&gt;Homepage dashboard (:3002)&lt;/li&gt;
&lt;li&gt;Excalidraw (:3003)&lt;/li&gt;
&lt;li&gt;Nginx Proxy Manager (:81)&lt;/li&gt;
&lt;li&gt;Cockpit server admin (:9090)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Port checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH (:22)&lt;/li&gt;
&lt;li&gt;MQTT / Mosquitto (:1883)&lt;/li&gt;
&lt;li&gt;AdGuard DNS (:53)&lt;/li&gt;
&lt;li&gt;Reolink entrance camera RTSP (:554)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ping checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Main router (192.168.0.1)&lt;/li&gt;
&lt;li&gt;Second AP / TP-Link (192.168.0.2)&lt;/li&gt;
&lt;li&gt;Seagate NAS (192.168.0.108)&lt;/li&gt;
&lt;li&gt;Reolink camera (192.168.0.173)&lt;/li&gt;
&lt;li&gt;Somfy TaHoma smart blinds gateway (192.168.0.209)&lt;/li&gt;
&lt;li&gt;Roborock S5 vacuum (192.168.0.248)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;13 check types are supported in total — including SSL cert expiry, DNS, SMTP, WebSocket, and a JSON API checker that can assert on response field values.&lt;/p&gt;

&lt;p&gt;What it caught immediately&lt;/p&gt;

&lt;p&gt;Within the first few days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Home Assistant went down for ~3 minutes during a container restart — would have missed it completely before&lt;/li&gt;
&lt;li&gt;Nginx Proxy Manager had a brief hiccup after watchtower auto-updated it and recreated the container with a broken config — caught within 15 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I paid&lt;/p&gt;

&lt;p&gt;Nothing. The free account covers the private worker and email alerts.&lt;/p&gt;

&lt;p&gt;What I wish was better&lt;/p&gt;

&lt;p&gt;The REST API doesn't let you assign the private worker to monitors programmatically — you have to open each monitor in the dashboard and set "Run from → your worker" manually. With 18 monitors this took a few minutes.&lt;br&gt;
A bulk-assign option would be a big quality-of-life improvement.&lt;/p&gt;

&lt;p&gt;Useful links&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Worker repo (MIT): &lt;a href="https://github.com/monitorion/monitorion-worker" rel="noopener noreferrer"&gt;https://github.com/monitorion/monitorion-worker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Platform: &lt;a href="https://app.monitorion.com" rel="noopener noreferrer"&gt;https://app.monitorion.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy to answer questions about the Podman setup, the cgroupv2 quirks I ran into, or the full compose stack.&lt;/p&gt;

</description>
      <category>selfhosted</category>
      <category>homelab</category>
      <category>docker</category>
      <category>monitoring</category>
    </item>
  </channel>
</rss>
