Upgrading self-hosted Pangolin Enterprise Edition from 1.21 to 1.25.3 (and patching Node2Shell)

Pangolin is the tunneled reverse proxy in front of most of my self-hosted services. It runs as a small Docker Compose stack of Pangolin, Gerbil (WireGuard) and Traefik on a VPS. Mine was still on the Enterprise Edition image ee-1.21.0. When Node2Shell (CVE-2026-111497) was published for Node.js, it was time to catch up four minor versions. This post covers the path I took, the versions that belong together, and how I verified the result.

Read more

Upgrading a neglected Redmine: PostgreSQL 9.6 → 15 and Redmine 5.0 → 6.1 in Docker

While checking my homelab for PHP2Shell, I took a closer look at my Redmine install. It isn’t PHP (Redmine is Ruby on Rails), but what I found was bad enough: sameersbn/redmine:5.0.2 from 2022 and sameersbn/postgresql:9.6, a database version that went end of life in 2021. Redmine 5.x is end of life too. Time to fix it properly, and to write it down for next time.

The last time I touched this install was in 2022, when I restored a 2017 backup into Redmine 5.0.2. This post picks up where that one left off.

Read more

PHP2Shell: patching a custom Nextcloud Docker image (and the :latest trap)

After patching my WordPress stack for PHP2Shell (CVE-2026-109618 and CVE-2026-109619), the next one on the list was Nextcloud. It deserved more care: it holds my files, and it runs on the official nextcloud:apache image, which means Apache with mod_php, the setup where the confirmed exploit fires before any application code runs.

Read more

PHP2Shell: patching my Dockerized WordPress in five minutes

On 21 October 2026 the PHP project shipped an emergency release for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, nicknamed PHP2Shell. Both are rated CVSS v4.0 9.2 and allow remote code execution without logging in. Details had leaked a day before the planned disclosure, so the patch window was short. This is a quick write-up of how I patched the WordPress stack that runs this blog.

Read more

A hardened Hetzner Cloud server with Docker in one cloud-init file (2026 edition)

When I spin up a new Hetzner Cloud VM, I paste a cloud-init file into the “Cloud config” box and let the server set itself up. Hetzner’s community tutorial has a nice baseline: a sudo user, SSH moved to port 2222, root and password logins disabled, fail2ban and ufw. What it doesn’t have is Docker. This post is the version I actually use, plus a few things I corrected after checking it against current documentation.

Read more

Deploying LXC containers at scale on Proxmox: cloud-init alternatives

Every time I spin up a new LXC on Proxmox, I ask myself the same question: why can’t I just hand it a cloud-init file like I do with VMs? The short answer is that cloud-init is a VM-only feature in Proxmox. LXC containers don’t support it natively. But there are several approaches that get you to the same place — or better.

This post covers the options, the trade-offs, and what I actually use for a fleet of Ubuntu + Docker + Docker Compose + Dockge containers.

Read more

Homelab logs and metrics with Grafana Alloy: journald to Loki, metrics to Prometheus

My homelab has grown to a good dozen Linux hosts: Proxmox nodes, Docker VMs, a few VPSs. For a while every host had something different collecting logs and metrics: an old OpenTelemetry Collector here, a Docker Loki logging driver there, nothing at all somewhere else. Now every host runs Grafana Alloy with almost the same config:

  • Logs: journald → Loki
  • Host metrics: built-in node exporter → Prometheus
  • Container metrics (Docker hosts only): built-in cAdvisor → Prometheus

Everything is pushed. Prometheus doesn’t need a scrape job per host and the hosts don’t need any open ports. And no, you don’t need Mimir for that: Prometheus can receive remote writes itself.

Read more

UPS shutdown with NUT over SNMP – Part 1: Proxmox VE

My Proxmox host and my TrueNAS share one UPS: an APC Smart-UPS SMT1500RMI2U with an AP9630 (NMC2) network management card. No USB cable, just Ethernet/SNMP.

Until now NUT ran as a container on the Proxmox host and served everything else. That’s a classic single point of failure: if Proxmox goes down first, the NUT server goes with it and nobody else gets told anything.

The design

  • No master/slave. Each host polls the UPS card itself over SNMP and shuts itself down.
  • Staggered thresholds: Proxmox shuts down at 50% battery, TrueNAS only at 40%. That way every VM/container writing to NAS shares is already stopped cleanly before the NAS goes down (consumer before provider).
  • Read-only SNMP community. No host can accidentally cut power to the shared UPS, even though NUT runs locally as primary.

Part 2 covers the TrueNAS side. This part is about Proxmox VE 8 (Debian 12, NUT 2.8.0).

Read more

Running SeAT 5 in Docker: every problem I hit and how I fixed it

I run SeAT, the EVE Online corporation management tool, for our corp in Docker on a Proxmox LXC, managed with Dockge. Getting it from SeAT 4 to SeAT 5 and then keeping it healthy turned into a long series of problems. This post collects all of them in one place, with the fixes that actually worked, so the next person (or future me) doesn’t have to dig through logs again.

The stack is a split compose setup, so every command needs the full -f chain:

Services are front, worker, scheduler, cache (Redis) and mariadb.

Read more

Ubuntu 24.04 Server Quick Start: Sudo User, SSH Hardening, fail2ban, Docker and Dockge

Every time I spin up a new Ubuntu server I go through the same handful of steps before anything else touches it. This post is that checklist, written down so I (and hopefully you) don’t have to piece it together again. It assumes a fresh Ubuntu 24.04 LTS install where your SSH public key is already in place for the initial login.

Throughout the post I use youruser as the new account name and 2222 as the new SSH port. Replace both with your own values.

Golden rule: keep your current SSH session open the whole time and test every change from a second terminal. That way a typo never locks you out.

Read more