Git, CI, wiki, passwords, monitoring: the tools a real company needs, self-hosted from one compose file on a €15 server. No per-seat pricing, no per-minute billing, no "enterprise tier". New episodes on YouTube.
Get the stack (free) Watch the series
Eleven of 16 containers updated in one go: the commands came back after 94 seconds and nothing broke for good, but the monitoring was unreachable for 299 seconds while Docker called it healthy. Then the way back: with the old tags only 4 of 11 services went back, and the identity provider refused to start. What held: the old images plus the snapshot from before the update, 108 seconds to 43 of 43 checks, at the price of 17 minutes of data.
Two monitors had been down since September 2 and no alert reached the phone. The same 40 minute storm with seven known incidents, three sorters: the existing rules sent 32 messages and caught 4 of 7, never the long outage. A local agent gave no usable list in 28 runs and skipped the one monitor that asked to be left out. 28 lines of Python: 7 messages, 7 of 7, under 30 ms. Plus the real fixes on the box.
A test employee is disabled in single sign on, then checked from outside every three minutes for 45 minutes: ten of thirteen ways in stay open. Then the stack gets its own identity provider (Pocket ID, 22 MB), an auth gate for apps without SSO and an offboarding script. One clean run, 0.8 seconds, one of fourteen left: the offline vault copy on the laptop, which only a human can deal with.
A local 3B model reads the requests the WAF blocked and proposes exceptions, a human merges. It found 60 percent of the false alarms and made 104 proposals only an attacker had asked for. One sentence in a URL became its reason for everything. A 22 line script without AI: five of five, zero dangerous, 0.03 seconds. What held was the architecture around the agent.
CrowdSec's web application firewall inside Caddy. Out of the box it blocks known exploits on the first request and nothing else, 7 of 41. The OWASP rule set blocks 27 and breaks git and the wiki. Three tuning attempts, one of which quietly switched off the virtual patches too, and the measured price of the one that holds.
The same 24 hours of real attack logs through both tools. fail2ban banned four addresses and missed a slow bot and every root key attempt. CrowdSec flagged 23 and would have banned one. The community blocklist, the data it costs, the Docker trap with the bouncer, and a live attack with both watching.
Three small agents with one skill file each read fail2ban and the Caddy log and write the morning report. Twenty runs scored against the executor, not one fully correct: the solo agent picks the wrong counter, the crew drops fields at every hand-over. Attacker text in the log was never obeyed, but quoted into the report three times out of three.
Eight days on the public internet, about 130,000 failed logins, and the hardening checklist finally gets run. Two of its items quietly do nothing on a Docker host: the firewall that never sees the packet, and the ban that lands in the wrong chain. Measured before and after, fixes in the repo.
An ops agent that triages outages on a model you run yourself, reached over the mesh. It may propose, only a hand written allowlist may act: the same prompt injection did nothing through the tools and worked thirteen times out of thirteen when it rode in with the alert. Nothing was executed.
Three workflows wire the git server, the monitor, the wiki and the push service together. A push reaches the phone in 4.2 seconds, an outage writes its own incident page, and the editor never goes on the public internet.
The server is powered off for real. A fresh empty box gets the whole stack back with restic, one S3 bucket and three commands: two minutes fifteen, original TLS certificates included.
Uptime Kuma gets monitors that mean something, ntfy pushes outages to your phone, a status page shows customers what they can use, and a second eye at home notices when the box itself is gone.
NetBird builds a WireGuard mesh around the box, Forgejo decides who joins the network, and n8n disappears from the public internet.
Bitwarden puts single sign-on behind its Enterprise tier. Vaultwarden ships it in the container, and offboarding becomes one switch.
Your Forgejo becomes an OpenID Connect provider. Outline becomes a company wiki with real search and zero passwords of its own.
Your own CI runners, your own container registry, deploys that reach your network. Unlimited minutes, because nobody is counting.
The foundation: Caddy, Forgejo, Outline, Vaultwarden, Uptime Kuma and n8n from one compose file, with real TLS.
caddy TLS + reverse proxy, certificates renew themselves
forgejo git, CI runners, container registry, and your login everywhere
outline the company wiki, SSO via Forgejo
vaultwarden team passwords
uptime-kuma monitoring + status page
n8n automations
one compose file · one €15 server · yoursEverything shown in the videos is in the public repo, including the fixes for the traps we hit on the way: git.selfhostedops.com/selfhostedops/selfhostedops-stack