<?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: tyxak</title>
    <description>The latest articles on DEV Community by tyxak (@tyxak).</description>
    <link>https://dev.to/tyxak</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3941080%2F6762ff41-dc6c-43b1-ab36-aca5ac1d16a5.png</url>
      <title>DEV Community: tyxak</title>
      <link>https://dev.to/tyxak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tyxak"/>
    <language>en</language>
    <item>
      <title>I built a self-hosted Linux fleet manager with no database and zero pip dependencies</title>
      <dc:creator>tyxak</dc:creator>
      <pubDate>Tue, 19 May 2026 22:33:00 +0000</pubDate>
      <link>https://dev.to/tyxak/i-built-a-self-hosted-linux-fleet-manager-with-no-database-and-zero-pip-dependencies-12e1</link>
      <guid>https://dev.to/tyxak/i-built-a-self-hosted-linux-fleet-manager-with-no-database-and-zero-pip-dependencies-12e1</guid>
      <description>&lt;p&gt;I manage a small fleet of Linux servers and got tired of the options:&lt;br&gt;
Ansible is great but not a dashboard. Grafana + Prometheus is powerful&lt;br&gt;
but heavy. Checkmk and Zabbix are overkill for a handful of machines.&lt;br&gt;
So I built my own.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is RemotePower?
&lt;/h2&gt;

&lt;p&gt;RemotePower is a self-hosted control plane for Linux servers. One small&lt;br&gt;
Python agent per host, one nginx + CGI server, flat JSON storage. No&lt;br&gt;
database, no framework, no pip dependencies — pure Python stdlib.&lt;/p&gt;

&lt;p&gt;The agent heartbeats every 60 seconds. The dashboard auto-refreshes.&lt;br&gt;
Everything just works.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Remote command execution&lt;/strong&gt; — run commands, reboot, shutdown,
Wake-on-LAN. Batch across devices. Cron scheduling. Command library
and allowlist. Browser SSH via xterm.js.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVE scanning&lt;/strong&gt; — OSV.dev backed, real CVSS v3.1 scoring,
per-CVE ignore list&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Patch management&lt;/strong&gt; — pending updates across the fleet, one-click
upgrade, update history, patch alerts via webhook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration drift detection&lt;/strong&gt; — hash critical files, baseline
diffing, drift_detected webhook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxmox VE integration&lt;/strong&gt; — manage QEMU VMs and LXC containers,
create and rollback snapshots, no SDK needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container awareness&lt;/strong&gt; — Docker, Podman, Kubernetes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom monitoring scripts&lt;/strong&gt; — write any bash check server-side,
assign it to devices, get fleet-wide pass/fail every 5 minutes.
Exit 0 = OK, anything else = FAIL. No SSH needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and alerts&lt;/strong&gt; — ping, TCP, HTTP probes, TLS/DNS expiry,
17 webhook event types (Discord, Slack, ntfy, Gotify)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI assistant&lt;/strong&gt; — optional LLM integration (Ollama, Anthropic,
OpenAI). Triage CVEs, prioritise patches, generate monitoring
scripts. Disabled by default, no cloud calls unless you choose one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP server&lt;/strong&gt; — lets any MCP-capable AI client query fleet state&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;p&gt;[ agent (Python) ] --heartbeat--&amp;gt; [ nginx + CGI ] --&amp;gt; [ flat JSON ]&lt;/p&gt;

&lt;p&gt;Push-based. Agents reach out — the server never needs inbound access&lt;br&gt;
to your hosts. The agent is a single Python file with no dependencies&lt;br&gt;
beyond the standard library.&lt;/p&gt;

&lt;p&gt;The server is the same — pure Python CGI behind nginx. Atomic file&lt;br&gt;
writes throughout. The entire thing runs on a Raspberry Pi.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why no database?
&lt;/h2&gt;

&lt;p&gt;For a small-to-medium fleet, a database is overhead without benefit.&lt;br&gt;
Flat JSON files are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to back up (one file, one command)&lt;/li&gt;
&lt;li&gt;Easy to inspect (&lt;code&gt;cat devices.json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Easy to version control&lt;/li&gt;
&lt;li&gt;Fast enough for hundreds of devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backup export is a single ZIP. Restore is extracting it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why no pip dependencies?
&lt;/h2&gt;

&lt;p&gt;Every dependency is a supply chain risk, a version conflict waiting&lt;br&gt;
to happen, and something that breaks on the next distro upgrade.&lt;br&gt;
Python's stdlib covers everything RemotePower needs: HTTP, JSON,&lt;br&gt;
cryptography (hmac, hashlib), subprocess, threading, logging.&lt;/p&gt;

&lt;p&gt;The agent deploys as a single file copy. No virtualenv, no pip install,&lt;br&gt;
no Docker required.&lt;/p&gt;
&lt;h2&gt;
  
  
  Custom monitoring scripts
&lt;/h2&gt;

&lt;p&gt;The newest feature and probably the most useful for day-to-day ops.&lt;/p&gt;

&lt;p&gt;You write a bash script on the server — anything you want. Check if&lt;br&gt;
nginx is responding, verify a backup file is fresh, test a database&lt;br&gt;
port. Assign it to any set of devices. The agent runs it every 5&lt;br&gt;
minutes and reports back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
curl &lt;span class="nt"&gt;-sf&lt;/span&gt; &lt;span class="nt"&gt;--max-time&lt;/span&gt; 10 http://localhost/ &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"HTTP OK"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit 0 = OK. Anything else = FAIL. Edge-triggered webhooks fire on&lt;br&gt;
status changes — once when it breaks, once when it recovers. No alert&lt;br&gt;
fatigue.&lt;/p&gt;

&lt;p&gt;The UI has an AI generate button — describe the check in plain English,&lt;br&gt;
get a bash script back, review it, save it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Try the demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://demoremote.tvipper.com" rel="noopener noreferrer"&gt;https://demoremote.tvipper.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Username: &lt;code&gt;demo&lt;/code&gt; / Password: &lt;code&gt;demo&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/tyxak/remotepower" rel="noopener noreferrer"&gt;https://github.com/tyxak/remotepower&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clone, point nginx at &lt;code&gt;server/&lt;/code&gt;, enrol a host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/tyxak/remotepower
./client/remotepower-agent enroll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Happy to answer questions about the architecture, the no-dependency&lt;br&gt;
approach, or any of the features. And if you self-host your own&lt;br&gt;
servers, I'd love to know what you'd want to see next.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>selfhosted</category>
      <category>homelab</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
