<?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: Benjamin Touchard</title>
    <description>The latest articles on DEV Community by Benjamin Touchard (@benjy33000).</description>
    <link>https://dev.to/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>DEV Community: Benjamin Touchard</title>
      <link>https://dev.to/benjy33000</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benjy33000"/>
    <language>en</language>
    <item>
      <title>I shipped a 20-feature DevOps tool solo in 60 days using Claude Code — the unfiltered breakdown</title>
      <dc:creator>Benjamin Touchard</dc:creator>
      <pubDate>Thu, 07 May 2026 18:50:15 +0000</pubDate>
      <link>https://dev.to/benjy33000/i-shipped-a-20-feature-devops-tool-solo-in-60-days-using-claude-code-the-unfiltered-breakdown-3mb3</link>
      <guid>https://dev.to/benjy33000/i-shipped-a-20-feature-devops-tool-solo-in-60-days-using-claude-code-the-unfiltered-breakdown-3mb3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — I built &lt;a href="https://maintenant.dev" rel="noopener noreferrer"&gt;Maintenant&lt;/a&gt;, a 20-feature monitoring tool (Docker + Kubernetes + endpoints + certs + alerts + status page + MCP server), solo, in two months, with Claude Code. AGPL-3.0 open-core, Pro tier at €29/month, real users in production. This post is not a pitch. It's the honest breakdown — what actually got 10x'd, what completely wasted my time, what I'd never claim about AI coding, and why the code was probably the easiest part. If you're a senior dev considering whether to bet on LLM-augmented development, this is what the inside actually looks like.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everyone's writing "I built X with AI" posts. &lt;strong&gt;This one tells you what they leave out.&lt;/strong&gt;&lt;/p&gt;




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

&lt;p&gt;Maintenant is a Go binary that runs on about 17 MB of RAM at idle. You drop it into a container and it auto-discovers your Docker, Swarm and Kubernetes workloads, watches your HTTP and TCP endpoints, your cron jobs through heartbeats, your TLS certificates, the resource usage of every service, detects images with updates available, flags dangerous network configurations — exposed database ports, 0.0.0.0 bindings, privileged containers — exposes a public status page, and ships alerts through webhooks, Discord, and on the Pro edition Slack, Teams, and email. It also ships an embedded MCP server with OAuth2 so an AI assistant can query your infrastructure directly. Everything is stored in SQLite with WAL, no external dependencies. No Postgres, no Redis, no message queue. The Vue 3 + TypeScript + Tailwind frontend is embedded into the binary through &lt;code&gt;embed.FS&lt;/code&gt;. One Docker image, one process, zero orchestration.&lt;/p&gt;

&lt;p&gt;I built it alone. AGPL-3.0 open-core, Pro edition at €29/month for agencies and freelancers managing client infrastructure, with a CLA for external contributors. License keys signed with Ed25519, delivered through an environment variable. Marketing site on Hugo + PocketBase handling Stripe checkout and license verification. Full documentation. And I built all of it by working with Claude Code in a continuous loop.&lt;/p&gt;

&lt;p&gt;This is where most "I built X with AI" posts derail. They tell you about the excitement, the screenshots, the "look ma, no hands" energy. &lt;strong&gt;This one does the opposite.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest timeline (this is where most posts lie)
&lt;/h2&gt;

&lt;p&gt;I started in March 2026, even though I'd been mulling the idea over before that. So &lt;strong&gt;two months, two and a half months of serious work&lt;/strong&gt; to arrive at what I just described — twenty features, dual-licensing, marketing site, documentation, MCP server.&lt;/p&gt;

&lt;p&gt;Which wouldn't have been possible if I were discovering Claude Code at the same time as I was building Maintenant. I've been using Claude Code daily for about a year and a half — on other projects, on client refactorings, on explorations that ended up in the drawer. The custom skills, the verification reflexes, the instinct for when to frame tightly versus when to let it breathe: all of it pre-existed Maintenant. &lt;strong&gt;The product was built on accumulated practice, not discovered during construction.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction matters because it changes what this article can promise. If you start today with Claude Code and aim for twenty features in two months, you're going to wreck yourself. Not because the tool doesn't allow it — it does — but because practice with the tool is itself an investment, and the short two months only work on top of eighteen long months upstream.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Maintenant exists in the first place
&lt;/h2&gt;

&lt;p&gt;People who run Docker seriously always end up with the same stack: Uptime Kuma for uptime checks, Portainer or Dozzle for containers, a cron script for TLS certificates, a half-configured Grafana for metrics, and a status page running on a public Notion. Five tabs, five databases, five alerting layers that don't talk to each other.&lt;/p&gt;

&lt;p&gt;Maintenant replaces all five. Not because it does each one better than the specialist — Grafana will always be more powerful for metrics. But because the friction of juggling five tools costs more than the quality delta on each one. When you're chasing a problem you want to see the container state, recent logs, the HTTP check hitting it, the certificate of the endpoint and the CPU consumption all on the same page. Not by swiping between five dashboards.&lt;/p&gt;

&lt;p&gt;The principle is strict: &lt;strong&gt;observe, never act.&lt;/strong&gt; Maintenant doesn't restart anything, doesn't pull anything, doesn't touch anything. It's a witness. That simplifies the code, the security model, and the trust a client places in the thing they deploy. Read-only is non-negotiable.&lt;/p&gt;

&lt;p&gt;It's a product that has a reason to exist independently of who built it or with what. That matters for the rest of the post.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Claude actually 10x'd
&lt;/h2&gt;

&lt;p&gt;First thing to clarify: I'm a senior Go developer, fractional CTO, and I've been doing web work for twenty-five years — I was hosting PHP and Flash sites on dedicated LAMP servers back when "DevOps" wasn't a word yet. &lt;strong&gt;I'm not learning how to code with an LLM.&lt;/strong&gt; So when I say "Claude accelerated me", I'm not talking about "it wrote the code I couldn't write". I'm talking about bandwidth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The frontend, for one.&lt;/strong&gt; My daily stack is Go, backend, network protocols, systems work. Vue 3 with TypeScript and Tailwind is not my home turf. I can do it, but slowly, second-guessing the conventions, losing time wondering if this should be &lt;code&gt;&amp;lt;script setup&amp;gt;&lt;/code&gt; or an explicit Composition API. With Claude knowing the stack better than I do, I attack a new component as if I had a frontend dev sitting next to me. Not so it makes the calls — I decide architecture, UX, visual conventions — but so it carries the cognitive load of the framework. The result: a real-time dashboard with uPlot charts, PWA support, SSE streaming, that would have been a project of its own in a classic solo build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scaffolding new modules&lt;/strong&gt;, same story. The MCP server with its OAuth2 PKCE flow and refresh token rotation. The OSV.dev scan for CVEs with risk scoring. The network insights that inspect OCI manifests to map images to their software ecosystems. Each is a feature that takes two to five solid days in classic mode: read specs, understand APIs, write code, test. With Claude, I spend those two to five days validating, refining, integrating cleanly into existing architecture. Going from blank file to a working first draft happens in an afternoon. &lt;strong&gt;It's not just faster — it's qualitatively different.&lt;/strong&gt; The friction of starting a module disappears, so I start things I would have indefinitely postponed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mass refactorings.&lt;/strong&gt; By the time Maintenant crossed ten internal services, the initial architecture cracked. I was sitting on a six-hundred-line &lt;code&gt;main.go&lt;/code&gt; that wired everything in the wrong order, with latent circular dependencies and an event bus typed through &lt;code&gt;interface{}&lt;/code&gt;. Refactoring that by hand is three weeks of pain — breaking five things on every commit, adding tests that didn't exist. With a &lt;code&gt;go-refactoring&lt;/code&gt; skill I wrote for Claude — encoding my conventions for typed events, App container extraction, dependency injection, test coverage patterns — I shipped the refactor in four days. Coverage went from embarrassing to respectable. Zero regressions in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything that isn't code.&lt;/strong&gt; The docs that track the code closely instead of drifting. The cold-email pitches to tech YouTubers and journalists, contextual rewriting every time, the chore every solo dev procrastinates on. The LinkedIn copy, in casual French dev tone, with the link in the first comment to dodge the algorithm's shadow-ban. Article drafts, exactly like this one. The Pro landing page copy. Terms of service, DPA, legal mentions. All that overhead that historically leaves a solo dev with a great product and anemic communication.&lt;/p&gt;

&lt;p&gt;This is where the leverage gets unreasonable. The code is still mine, under my control, with my architectural choices. But the twenty-eight other things that make a product actually exist — documentation, website, communication, outreach, billing, legal — suddenly become possible at a level that was out of reach for one person.&lt;/p&gt;

&lt;h2&gt;
  
  
  What completely wasted my time
&lt;/h2&gt;

&lt;p&gt;If I stopped here this article would be sellable and dishonest. Here's the honest part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature hallucinations.&lt;/strong&gt; Several times Claude generated content — for LinkedIn, for the docs, for a pitch — that mentioned alert channels Maintenant doesn't have. Telegram, Gotify, Ntfy. None of these exist in the product. They exist in Uptime Kuma, in self-hosted culture, so statistically they emerge whenever monitoring is the topic. If I hadn't reread, I would have shipped false claims that would have torpedoed my credibility. The cost isn't in the correction — it's in the &lt;strong&gt;constant vigilance&lt;/strong&gt;. Every output, I have to go back to the README and verify. &lt;strong&gt;The verification cost is constant. It does not decrease over time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Over-engineering when scope isn't bounded.&lt;/strong&gt; When I look at my own Claude Code usage data — 263 commits across 90 sessions, around 440 cumulative hours — the most frequent friction pattern isn't factual hallucination, which only fires 2 times over that period. It's "wrong approach" (31 incidents) and "misunderstood request" (25). A 56-to-2 ratio between scope drift and hallucination. The conclusion is sharp: my specs were clear, but Claude drifted toward over-engineering anyway. A refactor that wanted to factor out two things that had nothing to do with each other, an extra abstraction layer to "prepare for the future", a gitignored baseline file force-added because some &lt;code&gt;tasks.md&lt;/code&gt; mentioned it — costing me a rebase to roll back. &lt;strong&gt;The dominant risk isn't that the LLM invents false things. It's that it does correct things you didn't ask for.&lt;/strong&gt; The fix is mechanical: "you touch X, you do not modify Y, and you don't factor out anything that wasn't explicitly requested", at the start of every task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Misdiagnosis before verification.&lt;/strong&gt; Adjacent pattern, different mechanism. Claude proposes a root cause, declares it fixed, and you have to force it to reproduce the bug before proposing a fix. It's not a capacity issue — on sessions where I push it to reproduce concretely, read the logs, test the request before proposing a correction, it gets it right. It's an instinct issue: by default the model jumps to the conclusion. The fix is in the default prompt: "reproduce the bug before proposing a fix", and always anchor the environment and the layer at the start of any debug. It's a framing discipline, not a model limit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The SaaS detour.&lt;/strong&gt; At a moment of commercial doubt, I explored offering Maintenant as SaaS with a client-side agent. It's a seductive architecture for an LLM — opens up plenty of technical directions. Except for my target audience, sysadmins and CTOs who care about data sovereignty, the SaaS model destroys the pitch. I lost a week exploring it before reverting to self-hosted only. &lt;strong&gt;The LLM couldn't have known on its own that this direction was strategically wrong&lt;/strong&gt; — that's a cost on me for not framing it from the start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cost of custom skills.&lt;/strong&gt; All the advantages I described above don't exist out of the box. They exist because I wrote skills that encode my conventions, my rules, my anti-patterns. &lt;code&gt;go-refactoring&lt;/code&gt;, &lt;code&gt;mobile-first-audit&lt;/code&gt; for the Vue/Tailwind frontend, &lt;code&gt;linkedin-post-generator&lt;/code&gt; for the casual French tone, &lt;code&gt;linkedin-lead-capture&lt;/code&gt; for analyzing comments on my posts, &lt;code&gt;linkedin-trend-research&lt;/code&gt; for the editorial radar. And on top of that, I built Maintenant following the &lt;a href="https://github.com/github/spec-kit" rel="noopener noreferrer"&gt;GitHub Spec Kit&lt;/a&gt; workflow — spec-driven development that forces you to articulate the need, the plan, and the breakdown into atomic tasks before writing a single line of code. Without that discipline, outputs scatter in every direction. With it, they converge. &lt;strong&gt;But writing skills takes time. Maintaining them too. And adopting Spec Kit takes discipline at the moment you'd be tempted to "just go fast". It's a real investment, not a free lunch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trade-off between velocity and understanding.&lt;/strong&gt; Some modules Claude helped me scaffold quickly, I understand less deeply than if I had written them line by line. It's a different kind of technical debt: I could re-read and own them, but every time I haven't taken that time, I'm less equipped to intervene quickly when a bug surfaces. On critical modules, I re-read. On peripheral modules, I let it slide. Conscious trade-off, but it has a price.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real shift no one talks about
&lt;/h2&gt;

&lt;p&gt;If I had to isolate the thing that changed the most between building Maintenant with Claude versus building it alone, it wouldn't be the speed of writing code. &lt;strong&gt;It would be the ratio between dev time and everything-else time.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Historically, a solo developer spends eighty percent of their time on code and neglects the rest. Documentation rots. The marketing site is ugly. LinkedIn copy doesn't exist. YouTube pitches never go out. Terms of service come from a template found on some blog. The product is technically solid and commercially invisible.&lt;/p&gt;

&lt;p&gt;With a well-orchestrated LLM, that ratio inverts. Code stays central but takes up less absolute mental space. Documentation gets updated in near real-time because writing 200 words takes two minutes. The marketing site gets iterated on every week. LinkedIn copy becomes a morning routine. Cold-email pitches to YouTubers — DB Tech, Christian Lempa, Techno Tim, NetworkChuck — go out in series instead of marinating six months in a draft. Terms of service get reviewed, the DPA exists, the legal page is up to date. The product takes the shape it should have had all along.&lt;/p&gt;

&lt;p&gt;And that's not code. &lt;strong&gt;It's an organizational shift.&lt;/strong&gt; The solo developer of 2026 who knows how to orchestrate an LLM can hold a product surface that in 2022 required a team of three or four people — a developer, a technical writer, a part-time commercial, a community manager.&lt;/p&gt;

&lt;p&gt;Here's the line worth keeping:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The LLM doesn't lift a junior to senior level. It lifts a senior to team-of-four level.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Individual skill is still the ceiling. But the cost of the surrounding activities — which historically consumed the developer's energy — collapses. So the same skill can cover much more product surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd actually tell you to do
&lt;/h2&gt;

&lt;p&gt;If you want to do the same — not necessarily a monitoring product, any ambitious solo project — here's what works for me, in order of priority.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Write custom skills early.&lt;/strong&gt; Not after six months when you're sick of re-prompting the same conventions. The third time you correct the same thing, that's a skill. Mine run between two hundred and a thousand words; they encode anti-patterns, architecture rules, tone, references. They transform Claude from "smart intern with no context" into "colleague who knows your codebase".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use a structured spec workflow.&lt;/strong&gt; For non-trivial features, I use &lt;a href="https://github.com/github/spec-kit" rel="noopener noreferrer"&gt;GitHub Spec Kit&lt;/a&gt; — a spec-driven development framework that produces a spec, an implementation plan, and an atomic task breakdown before any code gets written. The thinking phase is explicit and critiquable upfront. &lt;strong&gt;This prevents drift because you catch wrong directions at the markdown stage instead of at the two-thousand-lines-to-revert stage.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Interrupt firmly and early.&lt;/strong&gt; The cost of a late revert is ten times the cost of a quick "stop, you're overflowing". When Claude starts touching things you didn't ask about, factoring out things you didn't request, claiming something works without verifying — don't hesitate. Cut, redirect, force the restart. &lt;strong&gt;The difference between a session that ends clean and one that ends in technical debt is almost always interruption latency.&lt;/strong&gt; The longer you wait, the more expensive the rollback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Verify every factual claim.&lt;/strong&gt; Every feature mentioned in a post, a pitch, a doc — back to the README. Every number — verify. Every competitive comparison — verify. The LLM is an excellent generator of plausibility; it doesn't distinguish true from plausible. &lt;strong&gt;That's your job and it stays your job.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Keep strategic decisions to yourself.&lt;/strong&gt; The LLM can explore directions, weigh technical trade-offs, propose architectures. It cannot decide your market positioning, your licensing model, your commercial target, your pricing. Those decisions you take alone, or with other humans who know your context. Otherwise you end up with a lost week on a SaaS detour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Invest in the everything-but-code.&lt;/strong&gt; This is where leverage is strongest and where solo developers have historically been most behind. Documentation, communication, outreach, legal, billing. &lt;strong&gt;If all you do is code better, you miss nine-tenths of the gain.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;Maintenant exists. It has GitHub stars, Docker pulls, users opening issues and discussions on the repo. The Pro tier has conversions. &lt;strong&gt;The product isn't a "look what I built with an AI" demo&lt;/strong&gt; — it's something people actually use in production on their dedicated servers and client infrastructure.&lt;/p&gt;

&lt;p&gt;And it exists only because I was able, alone, to maintain a product surface that would have required a small team three years ago. &lt;strong&gt;That's the real story.&lt;/strong&gt; Not the AI that codes. The orchestration skill that multiplies a senior developer.&lt;/p&gt;

&lt;p&gt;Code doesn't disappear. Craft doesn't disappear. Architectural rigor, test discipline, critical reading of every output, domain knowledge — all of it remains indispensable, and even more so than before, because without those guardrails an LLM produces pretty plausible content that ships to production and sinks you. But the ratio between "what you can do" and "what you can ship" has changed radically.&lt;/p&gt;

&lt;p&gt;For a solo developer with a clear vision, &lt;strong&gt;this is probably the best time to be building since the invention of the web framework.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  If you got something out of this
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;⭐ &lt;strong&gt;&lt;a href="https://github.com/kolapsis/maintenant" rel="noopener noreferrer"&gt;Star Maintenant on GitHub&lt;/a&gt;&lt;/strong&gt; if you want to follow what comes next — I'm shipping a new module roughly every two weeks&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;&lt;a href="https://maintenant.dev" rel="noopener noreferrer"&gt;Try Maintenant on your stack&lt;/a&gt;&lt;/strong&gt; — single Docker container, AGPL-3.0, free community edition&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;Drop a comment&lt;/strong&gt; with your own LLM-coding war stories. I'm especially curious about the workflows other senior devs have settled into.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Follow&lt;/strong&gt; for follow-up posts: I'm planning a deeper dive on the custom skills setup and how I run Spec Kit on real product work specifically.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  About me
&lt;/h3&gt;

&lt;p&gt;I'm Benjamin Touchard, senior Go developer and fractional CTO, building &lt;a href="https://maintenant.dev" rel="noopener noreferrer"&gt;Maintenant&lt;/a&gt; under the &lt;a href="https://kolapsis.com" rel="noopener noreferrer"&gt;Kolapsis&lt;/a&gt; brand from Bordeaux, France. I write about LLM-augmented development, self-hosted infrastructure, and what solo product building actually looks like in 2026. Find me on &lt;a href="https://github.com/kolapsis" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; or &lt;a href="https://linkedin.com/in/benjamin-touchard" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>opensource</category>
      <category>claude</category>
    </item>
    <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://dev.to/benjy33000/your-docker-stack-is-running-but-is-anyone-actually-watching-it-51j5</link>
      <guid>https://dev.to/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://dev.to/benjy33000/i-built-two-open-source-tools-faster-by-letting-ai-write-most-of-the-code-688</link>
      <guid>https://dev.to/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://dev.to/benjy33000/proving-people-actually-read-internal-documents-is-still-a-mess-2ng7</link>
      <guid>https://dev.to/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://dev.to/benjy33000/why-i-refuse-to-ship-google-analytics-in-open-source-projects-47dp</link>
      <guid>https://dev.to/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>
