<?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>Forem: Benjamin Touchard</title>
    <description>The latest articles on Forem by Benjamin Touchard (@benjy33000).</description>
    <link>https://forem.com/benjy33000</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%2F1740181%2F3f1038da-05fb-410f-832b-0bd4c2f84fc9.png</url>
      <title>Forem: Benjamin Touchard</title>
      <link>https://forem.com/benjy33000</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/benjy33000"/>
    <language>en</language>
    <item>
      <title>Your Docker Stack Is Running. But Is Anyone Actually Watching It?</title>
      <dc:creator>Benjamin Touchard</dc:creator>
      <pubDate>Sat, 02 May 2026 12:23:20 +0000</pubDate>
      <link>https://forem.com/benjy33000/your-docker-stack-is-running-but-is-anyone-actually-watching-it-51j5</link>
      <guid>https://forem.com/benjy33000/your-docker-stack-is-running-but-is-anyone-actually-watching-it-51j5</guid>
      <description>&lt;p&gt;You deployed your app. It runs. The containers are green. Job done, right?&lt;/p&gt;

&lt;p&gt;Except here's what's probably happening right now on your production server and you don't know about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That Postgres container is listening on &lt;code&gt;0.0.0.0:5432&lt;/code&gt; because you forgot to scope the port binding&lt;/li&gt;
&lt;li&gt;Your MariaDB image has a critical update (11.4 → 12.2.2) that's been sitting there for weeks&lt;/li&gt;
&lt;li&gt;One of your SSL certificates expires in 6 days&lt;/li&gt;
&lt;li&gt;That "temporary test container" you spun up on Friday afternoon is still running, exposed to the internet, and it's now Monday&lt;/li&gt;
&lt;li&gt;Your nightly backup cron job silently stopped working 3 days ago&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nobody's watching. Because setting up proper monitoring for a Docker stack is a pain, so most of us just... don't.&lt;/p&gt;

&lt;p&gt;Let's talk about why that's a problem, what the existing solutions look like, and why I ended up building my own.&lt;/p&gt;




&lt;h2&gt;
  
  
  The numbers are worse than you think
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SSL certificates: the ticking time bomb
&lt;/h3&gt;

&lt;p&gt;72% of organizations experienced at least one certificate-related outage in the past year. 34% had multiple. The average outage takes 2.6 hours to identify and 2.7 more to fix.&lt;/p&gt;

&lt;p&gt;And it's about to get much worse. As of March 2026, the CA/Browser Forum is phasing certificate validity down from 398 days to 200 days — and eventually to 47 days by 2029. That means you'll go from renewing certs once a year to roughly 8 times a year. Manual tracking with a calendar reminder? Good luck.&lt;/p&gt;

&lt;p&gt;Microsoft Teams went down for hours because of an expired certificate. Spotify had an outage on their podcast platform for the same reason. The US government had 80 certificates expire at once, taking multiple government websites offline. These aren't small companies with junior sysadmins — these are organizations with entire security teams.&lt;/p&gt;

&lt;p&gt;If it happens to them, it's happening to your production servers too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Container security: what you can't see can hurt you
&lt;/h3&gt;

&lt;p&gt;37% of organizations reported container or Kubernetes security incidents in 2024. The most common attack vectors? Vulnerable base images (32%), containers running as root (28%), and exposed Docker sockets (18%).&lt;/p&gt;

&lt;p&gt;In November 2025, researchers found over 10,000 Docker Hub images leaking live production credentials — API keys, cloud tokens, database passwords — from more than 100 organizations, including a Fortune 500 company. A national bank's architect had hundreds of public images on a personal Docker Hub account, several leaking internal infrastructure credentials.&lt;/p&gt;

&lt;p&gt;And that's just the stuff that makes the news. What about your Redis container that's been running in privileged mode since that debugging session last month? Or the MongoDB port you exposed for "quick testing" that's still binding to 0.0.0.0?&lt;/p&gt;

&lt;h3&gt;
  
  
  The container you forgot about
&lt;/h3&gt;

&lt;p&gt;We've all done it. You spin up a container for a quick test on a staging or production server — a database, a cache, a random API service. Someone pings you on Slack, you context-switch to something urgent, and the container sits there. If it's Friday afternoon, it sits there all weekend. With an open port. On a public-facing server.&lt;/p&gt;

&lt;p&gt;No alert. No notification. No dashboard telling you "hey, this thing is exposed and probably shouldn't be."&lt;/p&gt;

&lt;p&gt;The attack surface of your infrastructure is not what you think it is. It's what you deployed plus what you forgot you deployed. And when you manage multiple servers or client environments, the problem multiplies.&lt;/p&gt;




&lt;h2&gt;
  
  
  What about monitoring tools? Yes, they exist. About 15 of them.
&lt;/h2&gt;

&lt;p&gt;The monitoring landscape in 2026 is not a lack of options — it's an excess. About 75% of Kubernetes environments use Prometheus. Most serious setups pair it with Grafana, cAdvisor, and AlertManager. That's already 4 containers just to watch your other containers.&lt;/p&gt;

&lt;p&gt;Here's what a "proper" monitoring stack looks like for a typical production Docker setup on a dedicated server:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you need to monitor&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Additional containers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Container metrics (CPU/RAM)&lt;/td&gt;
&lt;td&gt;Prometheus + cAdvisor + Grafana&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP endpoint uptime&lt;/td&gt;
&lt;td&gt;Uptime Kuma&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cron job monitoring&lt;/td&gt;
&lt;td&gt;Healthchecks.io (or self-hosted)&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL certificates&lt;/td&gt;
&lt;td&gt;A bash script, or... another tool&lt;/td&gt;
&lt;td&gt;0-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image updates&lt;/td&gt;
&lt;td&gt;Manual &lt;code&gt;docker pull&lt;/code&gt;, or Watchtower&lt;/td&gt;
&lt;td&gt;0-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status page for users&lt;/td&gt;
&lt;td&gt;Cachet, Statusnook, or another tool&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;6-8 containers&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And that doesn't even cover network security analysis (exposed ports, privileged containers) or CVE detection on your running images. For that you'd need to add something like Trivy or Grype, plus custom scripting to scan your running containers.&lt;/p&gt;

&lt;p&gt;Let's look at what this actually means in docker-compose terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prometheus + Grafana + cAdvisor (container metrics)
&lt;/h3&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;prometheus&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;prom/prometheus:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./prometheus.yml:/etc/prometheus/prometheus.yml&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;prometheus_data:/prometheus&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9090:9090"&lt;/span&gt;

  &lt;span class="na"&gt;grafana&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;grafana/grafana:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;grafana_data:/var/lib/grafana&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;

  &lt;span class="na"&gt;cadvisor&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;gcr.io/cadvisor/cadvisor:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/sys:/sys:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/lib/docker/:/var/lib/docker:ro&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;

  &lt;span class="na"&gt;alertmanager&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;prom/alertmanager:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./alertmanager.yml:/etc/alertmanager/alertmanager.yml&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9093:9093"&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;prometheus_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;grafana_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's 4 containers, 3 config files to maintain, and you still need to write PromQL queries and build Grafana dashboards before you see anything useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uptime Kuma (HTTP/TCP checks)
&lt;/h3&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;uptime-kuma&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;louislam/uptime-kuma:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;uptime-kuma_data:/app/data&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3001:3001"&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;uptime-kuma_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, clean, but it only does endpoint checks. It doesn't know about your containers, their resource usage, their images, or their network exposure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Healthchecks.io (cron monitoring)
&lt;/h3&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;healthchecks&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;healthchecks/healthchecks:latest&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;SITE_ROOT=https://checks.example.com&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SECRET_KEY=your-secret-key&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB=sqlite&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;healthchecks_data:/data&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;healthchecks_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another container, another UI, another set of credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  The total cost
&lt;/h3&gt;

&lt;p&gt;At this point you're running 6+ monitoring containers to watch 20 containers. That's a 30% overhead ratio just for observability. Each tool has its own UI, its own alerting config, its own data store. None of them talk to each other. None of them give you a single view of "is my stack healthy?"&lt;/p&gt;

&lt;p&gt;And you still don't have SSL monitoring, image update detection, or network security analysis.&lt;/p&gt;

&lt;p&gt;This is over-engineering for a fundamentally simple need: &lt;strong&gt;knowing if your stuff is running, safe, and up to date.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why most people don't monitor properly
&lt;/h2&gt;

&lt;p&gt;It's not laziness. It's friction.&lt;/p&gt;

&lt;p&gt;The Prometheus+Grafana stack is incredibly powerful — it's what runs Google-scale infrastructure. But for a team running 10-50 containers on a dedicated server or a small cluster, it's like using a Formula 1 pit crew to check the tire pressure on your daily driver. The setup time alone kills the motivation, and then you have to maintain it.&lt;/p&gt;

&lt;p&gt;So what actually happens?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You deploy Uptime Kuma for the HTTP checks because it's easy&lt;/li&gt;
&lt;li&gt;You tell yourself you'll add proper metrics "later"&lt;/li&gt;
&lt;li&gt;"Later" never comes&lt;/li&gt;
&lt;li&gt;You find out about problems when users complain or when you SSH in and something is red&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sound familiar? Yeah, me too.&lt;/p&gt;




&lt;h2&gt;
  
  
  So I built the thing I wanted
&lt;/h2&gt;

&lt;p&gt;After running this exact fragmented setup for way too long, I decided to build what I actually needed: one container that does all of it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintenant&lt;/strong&gt; is a single Docker container that monitors your entire stack. You mount the Docker socket (read-only — it never touches your containers) and in 30 seconds you have:&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;maintenant&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/kolapsis/maintenant:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/proc:/host/proc:ro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;maintenant-data:/data&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MAINTENANT_ADDR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0:8080"&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;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;maintenant-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No config file. No PromQL. No Grafana dashboards to build. It auto-discovers everything on first start.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplhr2aljw4xrsby9c9nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplhr2aljw4xrsby9c9nk.png" alt="Dashboard showing all monitors, uptime, response times, resource usage" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What it covers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Container monitoring&lt;/strong&gt;: every container is tracked the moment it starts. State changes, health checks, restart loops, CPU/RAM/network/disk per container. Grouped by Compose project automatically. Top consumers view to spot the greedy ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwla14gfbl3p1y8taamj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwla14gfbl3p1y8taamj.png" alt="Containers view with Compose grouping and resource metrics" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP/TCP endpoint monitoring&lt;/strong&gt;: define probes via Docker labels — no config files, no UI clicks. Maintenant picks them up when the container starts:&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;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;maintenant.endpoint.http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api:3000/health"&lt;/span&gt;
  &lt;span class="na"&gt;maintenant.endpoint.interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15s"&lt;/span&gt;
  &lt;span class="na"&gt;maintenant.endpoint.failure-threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Heartbeat/cron monitoring&lt;/strong&gt;: create a monitor, get a URL, add one &lt;code&gt;curl&lt;/code&gt; to your cron job. Maintenant tracks start/finish times, durations, and alerts when a job goes missing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null https://your-instance.com/ping/&lt;span class="o"&gt;{&lt;/span&gt;uuid&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SSL/TLS certificate tracking&lt;/strong&gt;: auto-detected from your HTTPS endpoints, plus standalone monitors for any domain. Alerts at 30, 14, 7, 3, and 1 day before expiry. With certificates moving to 200-day validity this year and 47 days by 2029, this isn't optional anymore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqscdxvwv4jhl48tt5dy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqscdxvwv4jhl48tt5dy.png" alt="Certificates view with validity tracking" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update detection&lt;/strong&gt;: scans OCI registries (Docker Hub, GHCR, etc.), compares digests and semver tags. Flags critical version jumps — like that MariaDB 11.4 → 12.2.2 that you might have missed. No more running &lt;code&gt;docker pull&lt;/code&gt; manually and hoping for the best.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjz6cxyoilm08m98xbp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjz6cxyoilm08m98xbp0.png" alt="Updates view showing critical/available/pinned" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network security analysis&lt;/strong&gt;: automatically scans your containers' network configuration and flags risky patterns — database ports exposed on 0.0.0.0, containers in privileged mode, host-network mode, and for Kubernetes, NodePort/LoadBalancer without NetworkPolicy. This is the "test container you forgot about on Friday" detector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public status page&lt;/strong&gt;: built-in, customizable, auto-reflects your monitor states. No manual update needed — if something goes down, your status page shows it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wg3ccar1cakbygs90i8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wg3ccar1cakbygs90i8.png" alt="Status page in operational state" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The stack
&lt;/h3&gt;

&lt;p&gt;Single Go binary. Less than 20 MB of RAM at idle. SQLite in WAL mode — no Postgres, no Redis, no external anything. The Vue 3 frontend is embedded in the binary via Go's &lt;code&gt;embed.FS&lt;/code&gt;. Real-time updates via SSE.&lt;/p&gt;

&lt;p&gt;One container instead of six. Same coverage, fraction of the resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  It's also a MCP server
&lt;/h3&gt;

&lt;p&gt;Maintenant has a built-in Model Context Protocol server. You can query your infrastructure health, read container logs, and check alert status from Claude or any MCP-compatible AI assistant. Because in 2026, your monitoring tool should be queryable by your AI tools too.&lt;/p&gt;




&lt;h2&gt;
  
  
  The business model (I'll be upfront)
&lt;/h2&gt;

&lt;p&gt;Maintenant is open-core under &lt;strong&gt;AGPL-3.0&lt;/strong&gt;. The full codebase — including Pro features — is visible on GitHub. Nothing is in a private repo.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Community Edition&lt;/strong&gt; is the real product: containers, endpoints, heartbeats, SSL certificates, update detection, network security insights, status page, Kubernetes support, Webhook + Discord alerts. Monitors defined via Docker labels are unlimited. Manually added monitors have soft caps (10 endpoints, 10 heartbeats, 5 standalone TLS certificates) — generous enough for most setups, and label-driven config is the recommended approach anyway.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Pro Edition&lt;/strong&gt; (29€/month or 290€/year) lifts all limits and adds Slack/Teams/Email (SMTP) alerts, alert escalation and routing, CVE detection via OSV.dev, security posture dashboard, incident management, maintenance windows, and subscriber notifications.&lt;/p&gt;

&lt;p&gt;I'm a solo developer. This is how I sustain the project. If the free edition covers your needs, that's the intended experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="c"&gt;# open http://localhost:8080&lt;/span&gt;
&lt;span class="c"&gt;# your containers are already there&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/kOlapsis/maintenant" rel="noopener noreferrer"&gt;github.com/kOlapsis/maintenant&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://maintenant.dev" rel="noopener noreferrer"&gt;maintenant.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://docs.maintenant.dev" rel="noopener noreferrer"&gt;docs.maintenant.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've been running the "5 tabs and a prayer" monitoring setup on your production servers, give it a try. It takes 30 seconds and replaces a lot of duct tape.&lt;/p&gt;

&lt;p&gt;Whether you manage a single dedicated server or multiple environments for your clients, Maintenant gives you the full picture from one container.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kubernetes</category>
      <category>security</category>
      <category>devops</category>
    </item>
    <item>
      <title>I built two open-source tools faster by letting AI write most of the code</title>
      <dc:creator>Benjamin Touchard</dc:creator>
      <pubDate>Sat, 20 Dec 2025 11:20:40 +0000</pubDate>
      <link>https://forem.com/benjy33000/i-built-two-open-source-tools-faster-by-letting-ai-write-most-of-the-code-688</link>
      <guid>https://forem.com/benjy33000/i-built-two-open-source-tools-faster-by-letting-ai-write-most-of-the-code-688</guid>
      <description>&lt;p&gt;Over the past weeks, I built two open-source projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one in a few weeks,&lt;/li&gt;
&lt;li&gt;the other in a few days.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not because I rushed.&lt;br&gt;
Not because they are toy projects.&lt;/p&gt;

&lt;p&gt;But because I changed &lt;em&gt;who types the code&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually changed (and what didn’t)
&lt;/h2&gt;

&lt;p&gt;I didn’t “let AI build a product”.&lt;/p&gt;

&lt;p&gt;I still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;define the architecture,&lt;/li&gt;
&lt;li&gt;decide what exists and what doesn’t,&lt;/li&gt;
&lt;li&gt;control data models,&lt;/li&gt;
&lt;li&gt;review every line,&lt;/li&gt;
&lt;li&gt;say no very often.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What changed is simple:&lt;br&gt;
&lt;strong&gt;I don’t type most of the code anymore.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AI does.&lt;/p&gt;




&lt;h2&gt;
  
  
  This is not about prompts or magic
&lt;/h2&gt;

&lt;p&gt;This has nothing to do with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clever prompts,&lt;/li&gt;
&lt;li&gt;autonomous agents,&lt;/li&gt;
&lt;li&gt;“vibe coding” without thinking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It works because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I know exactly what I want,&lt;/li&gt;
&lt;li&gt;I know when something is wrong,&lt;/li&gt;
&lt;li&gt;I know how the system should behave.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI is fast.&lt;br&gt;
I am precise.&lt;/p&gt;

&lt;p&gt;That combination matters more than prompts.&lt;/p&gt;




&lt;h2&gt;
  
  
  How I actually use AI to code
&lt;/h2&gt;

&lt;p&gt;My workflow is closer to this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I describe &lt;em&gt;very precisely&lt;/em&gt; what needs to be implemented&lt;/li&gt;
&lt;li&gt;The AI writes the code&lt;/li&gt;
&lt;li&gt;I read it like a strict reviewer&lt;/li&gt;
&lt;li&gt;I ask for corrections, refactors, deletions&lt;/li&gt;
&lt;li&gt;I integrate or reject&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The AI writes faster than I ever could.&lt;br&gt;
I think slower, but better.&lt;/p&gt;

&lt;p&gt;It feels very similar to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the first smart autocompletion,&lt;/li&gt;
&lt;li&gt;then IDE refactoring tools,&lt;/li&gt;
&lt;li&gt;then real-time linting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same shift. Bigger scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two different projects, same approach
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ackify
&lt;/h3&gt;

&lt;p&gt;Ackify is an open-source tool to handle &lt;strong&gt;internal document acknowledgements&lt;/strong&gt;:&lt;br&gt;
proof that people actually read internal policies, procedures, or mandatory documents.&lt;/p&gt;

&lt;p&gt;It required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a clear domain model,&lt;/li&gt;
&lt;li&gt;strong constraints,&lt;/li&gt;
&lt;li&gt;no feature creep.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI helped write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;handlers,&lt;/li&gt;
&lt;li&gt;storage layers,&lt;/li&gt;
&lt;li&gt;repetitive logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I stayed in control of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scope,&lt;/li&gt;
&lt;li&gt;semantics,&lt;/li&gt;
&lt;li&gt;guarantees.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SHM
&lt;/h3&gt;

&lt;p&gt;SHM (Self-Hosted Metrics) is much smaller.&lt;br&gt;
It answers one question:&lt;br&gt;
&lt;em&gt;“Is this self-hosted app actually used?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It was built in days because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the scope was tiny,&lt;/li&gt;
&lt;li&gt;the rules were strict,&lt;/li&gt;
&lt;li&gt;the AI handled most of the boilerplate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different scale.&lt;br&gt;
Same method.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI as a force multiplier, not a decision maker
&lt;/h2&gt;

&lt;p&gt;The biggest misunderstanding about AI-assisted coding is thinking it replaces thinking.&lt;/p&gt;

&lt;p&gt;It doesn’t.&lt;/p&gt;

&lt;p&gt;It replaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;typing speed,&lt;/li&gt;
&lt;li&gt;mechanical repetition,&lt;/li&gt;
&lt;li&gt;obvious glue code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The moment you stop knowing what you want,&lt;br&gt;
the output degrades immediately.&lt;/p&gt;

&lt;p&gt;AI is not creative in architecture.&lt;br&gt;
It is efficient in execution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters for solo developers and open-source
&lt;/h2&gt;

&lt;p&gt;For solo developers, time is the real constraint.&lt;/p&gt;

&lt;p&gt;AI doesn’t give you ideas.&lt;br&gt;
It gives you &lt;strong&gt;throughput&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That makes it possible to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explore ideas faster,&lt;/li&gt;
&lt;li&gt;kill bad ones earlier,&lt;/li&gt;
&lt;li&gt;finish small useful tools instead of polishing one forever.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s exactly how many open-source needs are met:&lt;br&gt;
small tools, precise scope, fast iteration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;I don’t feel replaced by AI.&lt;br&gt;
I feel amplified.&lt;/p&gt;

&lt;p&gt;I still design.&lt;br&gt;
I still decide.&lt;br&gt;
I still review.&lt;/p&gt;

&lt;p&gt;I just don’t type as much anymore.&lt;/p&gt;

&lt;p&gt;And that’s fine.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Proving people actually read internal documents is still a mess</title>
      <dc:creator>Benjamin Touchard</dc:creator>
      <pubDate>Sat, 20 Dec 2025 11:15:33 +0000</pubDate>
      <link>https://forem.com/benjy33000/proving-people-actually-read-internal-documents-is-still-a-mess-2ng7</link>
      <guid>https://forem.com/benjy33000/proving-people-actually-read-internal-documents-is-still-a-mess-2ng7</guid>
      <description>&lt;p&gt;I’ve worked on internal tools, compliance processes, and regulated environments for years.&lt;/p&gt;

&lt;p&gt;And there is one recurring problem that almost everyone underestimates:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you prove that people actually read internal documents?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not signed contracts.&lt;br&gt;&lt;br&gt;
Not legal agreements.&lt;br&gt;&lt;br&gt;
Just things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;internal procedures&lt;/li&gt;
&lt;li&gt;security policies&lt;/li&gt;
&lt;li&gt;onboarding documents&lt;/li&gt;
&lt;li&gt;mandatory trainings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers are usually disappointing.&lt;/p&gt;




&lt;h2&gt;
  
  
  How this is usually handled
&lt;/h2&gt;

&lt;p&gt;In most teams, it looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a PDF sent by email&lt;/li&gt;
&lt;li&gt;a shared folder or intranet page&lt;/li&gt;
&lt;li&gt;a checkbox in a form&lt;/li&gt;
&lt;li&gt;sometimes a signature on paper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Can you prove that employees read this document?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer is often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Well… we sent it.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s not proof.&lt;br&gt;&lt;br&gt;
And in audits, that difference matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why existing tools don’t really fit
&lt;/h2&gt;

&lt;p&gt;There are many tools for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;e-signatures&lt;/li&gt;
&lt;li&gt;contract management&lt;/li&gt;
&lt;li&gt;document workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;heavy&lt;/li&gt;
&lt;li&gt;expensive&lt;/li&gt;
&lt;li&gt;SaaS-only&lt;/li&gt;
&lt;li&gt;designed for legal or sales use cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They solve problems like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signing contracts&lt;/li&gt;
&lt;li&gt;closing deals&lt;/li&gt;
&lt;li&gt;external compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But internal acknowledgements are different.&lt;/p&gt;

&lt;p&gt;They are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;frequent&lt;/li&gt;
&lt;li&gt;low-risk&lt;/li&gt;
&lt;li&gt;internal&lt;/li&gt;
&lt;li&gt;boring but mandatory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using a full contract-signing platform for that feels excessive.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually needed
&lt;/h2&gt;

&lt;p&gt;From a technical and operational point of view, I needed something simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prove that a document was presented&lt;/li&gt;
&lt;li&gt;prove that it was acknowledged&lt;/li&gt;
&lt;li&gt;keep a verifiable record&lt;/li&gt;
&lt;li&gt;without managing contracts or identities manually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No document storage SaaS.&lt;br&gt;&lt;br&gt;
No legal framing.&lt;br&gt;&lt;br&gt;
No complexity.&lt;/p&gt;

&lt;p&gt;Just &lt;strong&gt;proof of read&lt;/strong&gt;, done properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  A pragmatic response: Ackify
&lt;/h2&gt;

&lt;p&gt;So I built &lt;strong&gt;Ackify&lt;/strong&gt;, an open-source tool focused on one thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal document acknowledgements.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ackify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generates acknowledgement requests&lt;/li&gt;
&lt;li&gt;records confirmations&lt;/li&gt;
&lt;li&gt;produces verifiable proof&lt;/li&gt;
&lt;li&gt;stays simple by design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not a replacement for legal signature platforms.&lt;br&gt;&lt;br&gt;
It’s a tool for internal compliance and operational needs.&lt;/p&gt;

&lt;p&gt;👉 Repository: &lt;a href="https://github.com/btouchard/ackify-ce" rel="noopener noreferrer"&gt;https://github.com/btouchard/ackify-ce&lt;/a&gt;&lt;br&gt;
👉 Website: &lt;a href="https://ackify.eu" rel="noopener noreferrer"&gt;https://ackify.eu&lt;/a&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Why this problem is mostly ignored
&lt;/h2&gt;

&lt;p&gt;Internal compliance is not shiny.&lt;/p&gt;

&lt;p&gt;It doesn’t:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate revenue directly&lt;/li&gt;
&lt;li&gt;impress investors&lt;/li&gt;
&lt;li&gt;fit growth dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it costs time, energy, and stress when done badly.&lt;/p&gt;

&lt;p&gt;Big platforms optimize for contracts and transactions.&lt;br&gt;&lt;br&gt;
Small teams just need clarity and traceability.&lt;/p&gt;

&lt;p&gt;This gap is where many open-source tools live.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;Not every problem needs an enterprise platform.&lt;/p&gt;

&lt;p&gt;Some problems just need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a clear scope&lt;/li&gt;
&lt;li&gt;a simple workflow&lt;/li&gt;
&lt;li&gt;and reliable evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Internal acknowledgements are one of them.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>selfhosted</category>
      <category>devops</category>
      <category>compliance</category>
    </item>
    <item>
      <title>Why I refuse to ship Google Analytics in open-source projects</title>
      <dc:creator>Benjamin Touchard</dc:creator>
      <pubDate>Sat, 20 Dec 2025 11:03:15 +0000</pubDate>
      <link>https://forem.com/benjy33000/why-i-refuse-to-ship-google-analytics-in-open-source-projects-47dp</link>
      <guid>https://forem.com/benjy33000/why-i-refuse-to-ship-google-analytics-in-open-source-projects-47dp</guid>
      <description>&lt;p&gt;I build open-source applications, most of them self-hosted.&lt;/p&gt;

&lt;p&gt;Like many developers, I need metrics. Not marketing metrics. Just basic signals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the application actually used?&lt;/li&gt;
&lt;li&gt;How many instances are alive?&lt;/li&gt;
&lt;li&gt;Which features are used at all?&lt;/li&gt;
&lt;li&gt;And for a long time, the default answer was obvious: Google Analytics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But at some point, I decided to stop shipping it entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Google Analytics is a poor fit for open-source and self-hosted apps
&lt;/h2&gt;

&lt;p&gt;Google Analytics is not a bad tool. It’s just built for a completely different purpose.&lt;/p&gt;

&lt;p&gt;It assumes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a centralized SaaS product,&lt;/li&gt;
&lt;li&gt;tracked end-users,&lt;/li&gt;
&lt;li&gt;marketing funnels,&lt;/li&gt;
&lt;li&gt;cookies, consent banners, and external dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that aligns well with self-hosted open-source software.&lt;/p&gt;

&lt;p&gt;Embedding GA in an open-source app means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sending usage data outside the user’s infrastructure,&lt;/li&gt;
&lt;li&gt;introducing legal and privacy concerns you don’t control,&lt;/li&gt;
&lt;li&gt;tracking individuals when you only want aggregate usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, the cost (technical, ethical, cognitive) is higher than the value.&lt;/p&gt;




&lt;h2&gt;
  
  
  Existing alternatives didn’t really solve my problem
&lt;/h2&gt;

&lt;p&gt;I looked at many “privacy-friendly” or “self-hosted” analytics tools, like Countly, PostHog, ...&lt;/p&gt;

&lt;p&gt;Most of them still assume:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;websites, not distributed instances,&lt;/li&gt;
&lt;li&gt;user tracking (even anonymized),&lt;/li&gt;
&lt;li&gt;dashboards designed for marketing teams,&lt;/li&gt;
&lt;li&gt;heavy setups for very simple questions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I needed was much simpler.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually need as a developer / CTO
&lt;/h2&gt;

&lt;p&gt;For open-source and self-hosted software, my questions are boring but essential:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this instance still running?&lt;/li&gt;
&lt;li&gt;Is anyone using this feature?&lt;/li&gt;
&lt;li&gt;Is adoption growing or stagnating?&lt;/li&gt;
&lt;li&gt;Did this release break usage patterns?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don’t need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page views,&lt;/li&gt;
&lt;li&gt;funnels,&lt;/li&gt;
&lt;li&gt;session replay,&lt;/li&gt;
&lt;li&gt;user identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I just need &lt;strong&gt;signals&lt;/strong&gt;, not surveillance.&lt;/p&gt;




&lt;h2&gt;
  
  
  A pragmatic response: build something smaller
&lt;/h2&gt;

&lt;p&gt;So I built a small open-source service called SHM (Self-Hosted Metrics).&lt;/p&gt;

&lt;p&gt;It’s intentionally minimal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it accepts simple JSON events,&lt;/li&gt;
&lt;li&gt;it doesn’t track users,&lt;/li&gt;
&lt;li&gt;it’s agnostic to the application,&lt;/li&gt;
&lt;li&gt;it works well with self-hosted deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not analytics.&lt;br&gt;
The goal is &lt;strong&gt;observability of usage&lt;/strong&gt;, without violating the principles of open-source or self-hosting.&lt;/p&gt;

&lt;p&gt;Repository:&lt;br&gt;
👉 &lt;a href="https://github.com/btouchard/shm" rel="noopener noreferrer"&gt;https://github.com/btouchard/shm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;h2&gt;
  
  
  What this says about the open-source ecosystem
&lt;/h2&gt;

&lt;p&gt;A lot of real needs sit between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“no metrics at all”&lt;/li&gt;
&lt;li&gt;and “full SaaS analytics stacks”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Big tools don’t care about these needs.&lt;br&gt;
They’re not scalable, not monetizable, and not flashy.&lt;/p&gt;

&lt;p&gt;But for maintainers, indie developers, and small teams, they matter.&lt;/p&gt;

&lt;p&gt;Not everything needs to be measured like a growth funnel.&lt;br&gt;
Sometimes, knowing that your software is simply used is enough.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>selfhosted</category>
      <category>privacy</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
