Endlich Überblick über Linux-Updates - dieses Tool fehlte mir im Homelab | Patchmon
Übersicht
Wer mehrere Linux-Server betreibt, egal ob im Homelab oder im produktiven Umfeld, kennt das Problem: Welche Systeme sind aktuell? Wo fehlen Updates? Und wo läuft vielleicht schon seit Wochen ein verwundbares Paket?
Patchmon setzt genau hier an. Es bietet eine zentrale Übersicht über Patch-Stände, installierte Pakete und sogar Docker-Container, ohne komplizierte Setups oder schwergewichtige Management-Suiten.
In diesem Artikel schauen wir uns an, wie Patchmon per Docker installiert wird, wie die ersten Hosts eingebunden werden und welche Funktionen bereits heute zur Verfügung stehen.
Das Video zum Beitrag findet Ihr hier: https://youtu.be/HGsxjh0DUVU
Installation
Docker
Da wir Patchmon mit Docker betreiben möchten, installieren wir als Erstes natürlich erstmal Docker selbst, falls noch nicht geschehen. Das können wir ganz einfach mit dem offiziellen Convenience Script von Docker machen.
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Verzeichnis
Bevor wir fortfahren, müssen wir uns ein geeignetes Verzeichnis erstellen, wo wir Patchmon später laufen lassen wollen. Ich habe meine Docker-Compose Stacks immer gerne unter /opt, darunter erstelle ich einen neuen Ordner für Patchmon mit:
sudo mkdir patchmon
cd patchmon
Docker Compose & .env File
Als Nächstes benötigen wir das Docker Compose File für Patchmon. Dies beinhaltet alle nötigen Container. Das File können wir mit wget herunterladen und anschließend noch auf unsere Bedürfnisse anpassen.
wget -O docker-compose.yml https://raw.githubusercontent.com/PatchMon/PatchMon/refs/heads/main/docker/docker-compose.yml
In meinem Fall kommentiere ich den Port aus, da ich später nur per https über meinen Reverse-Proxy auf die Weboberfläche zugreifen möchte. Damit das funktioniert, muss ich zusätzlich noch das Netzwerk für den Reverse-Proxy (Caddy oder auch NPM) hinzufügen und allen Containern ein eigenes Internes-Netz geben.
Außerdem möchte Patchmon, dass man das Postgres-Passwort, Redis-Passwort und das JWT-Secret an verschiedenen Stellen in der Compose einfügt. Ich habe das Ganze hier ein wenig abgeändert und arbeite mit Variablen, sodass ich die 3 Werte nur einmal in dem .env File definiere.
Zusätzlich habe ich die Variablen CORS_URL und SERVER_HOST ebenfalls mit in die .env verschoben, um das Compose-File generisch zu halten.
Fertig angepasst, sieht es dann so aus:
sudo nano docker-compose.yml
# Change 3 Passwords in this file:
# Generate passwords with 'openssl rand -hex 64'
#
# 1. The database password in the environment variable POSTGRES_PASSWORD
# 2. The redis password in the command redis-server --requirepass your-redis-password-here
# 3. The jwt secret in the environment variable JWT_SECRET
#
#
# Change 2 URL areas in this file:
# 1. Setup your CORS_ORIGIN to what url you will use for accessing PatchMon frontend url
# 2. Setup your SERVER_PROTOCOL, SERVER_HOST and SERVER_PORT to what you will use for linux agents to access PatchMon
#
# This is generally the same as your CORS_ORIGIN url , in some cases it might be different - SERVER_* variables are used in the scripts for Server connection.
# You can also change this in the front-end but in the case of docker-compose - it is overwritten by the variables set here.
name: patchmon
services:
database:
image: postgres:17-alpine
container_name: patchmon-db
restart: unless-stopped
environment:
POSTGRES_DB: patchmon_db
POSTGRES_USER: patchmon_user
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- patchmon-internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U patchmon_user -d patchmon_db"]
interval: 3s
timeout: 5s
retries: 7
redis:
image: redis:7-alpine
container_name: patchmon-redis
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD} # CHANGE THIS TO YOUR REDIS PASSWORD
volumes:
- redis_data:/data
networks:
- patchmon-internal
healthcheck:
test: ["CMD", "redis-cli", "--no-auth-warning", "-a", "${REDIS_PASSWORD}", "ping"] # CHANGE THIS TO YOUR REDIS PASSWORD
interval: 3s
timeout: 5s
retries: 7
backend:
image: ghcr.io/patchmon/patchmon-backend:latest
container_name: patchmon-backend
restart: unless-stopped
# See PatchMon Docker README for additional environment variables and configuration instructions
environment:
LOG_LEVEL: info
DATABASE_URL: postgresql://patchmon_user:${POSTGRES_PASSWORD}@database:5432/patchmon_db
JWT_SECRET: ${JWT_SECRET} #CREATE A STRONG SECRET AND PUT IT HERE
SERVER_PROTOCOL: https
SERVER_HOST: ${SERVER_HOST}
SERVER_PORT: 443
CORS_ORIGIN: ${CORS_ORIGIN}
# Database Connection Pool Configuration (Prisma)
DB_CONNECTION_LIMIT: 30
DB_POOL_TIMEOUT: 20
DB_CONNECT_TIMEOUT: 10
DB_IDLE_TIMEOUT: 300
DB_MAX_LIFETIME: 1800
# Rate Limiting (times in milliseconds)
RATE_LIMIT_WINDOW_MS: 900000
RATE_LIMIT_MAX: 5000
AUTH_RATE_LIMIT_WINDOW_MS: 600000
AUTH_RATE_LIMIT_MAX: 500
AGENT_RATE_LIMIT_WINDOW_MS: 60000
AGENT_RATE_LIMIT_MAX: 1000
# Redis Configuration
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD}
REDIS_DB: 0
# Assets directory for custom branding (logos, favicons)
ASSETS_DIR: /app/assets
volumes:
- agent_files:/app/agents
- branding_assets:/app/assets
networks:
- patchmon-internal
depends_on:
database:
condition: service_healthy
redis:
condition: service_healthy
frontend:
image: ghcr.io/patchmon/patchmon-frontend:latest
container_name: patchmon-frontend
restart: unless-stopped
#ports: via nginx proxy Manager
# - "3000:3000"
volumes:
- branding_assets:/usr/share/nginx/html/assets
networks:
- patchmon-internal
- reverse-proxy
depends_on:
backend:
condition: service_healthy
volumes:
postgres_data:
redis_data:
agent_files:
branding_assets:
networks:
patchmon-internal:
driver: bridge
name: patchmon-internal
reverse-proxy:
external: true
Im zugehörigen .env-File definieren wir jetzt die Variablen:
sudo nano .env
POSTGRES_PASSWORD= #openssl rand -hex 32
REDIS_PASSWORD= #openssl rand -hex 32
JWT_SECRET= #openssl rand -hex 32
SERVER_HOST=patchmon.example.com
CORS_ORIGIN=https://patchmon.example.com
Start
Nachdem wir nun also die docker-compose.yaml und die .env in unserem Patchmon-Verzeichnis haben, können wir die Container starten.
sudo docker compose up -d
Reverse Proxy
Wie erwähnt, möchte ich Patchmon nun direkt über eine gewünschte Domain und per https erreichen. Dafür habe ich ein Reverse-Proxy-Setup auf meinem Docker Host implementiert, der dies super einfach macht. In dem aktuellen Lab basiert das auf dem Nginx Proxy Manager. Eine weitere und noch schlankere Möglichkeit ist die Umsetzung mit Caddy.
Um jetzt Patchmon erreichen zu können, haben wir bereits das reverse-proxy Docker-Netzwerk zu dem Frontend-Container hinzugefügt und in der CORS_ORIGIN Variable die gewünschte Domain angegeben. Nun können wir im Nginx Proxy Manager einfach einen neuen Host mit dem entsprechenden Containernamen hinzufügen und geben den eigentlichen Port an.

Erste Schritte
Nachdem alle Container gestartet sind und der Reverse-Proxy-Eintrag entsprechend besteht, können wir zu unserer gewählten Domain navigieren.
Benutzer erstellen
Dort angekommen, werden wir aufgefordert, einen Benutzer zu erstellen. Da dies der erste Benutzer ist, erhalten wir mit diesem die Administrator-Rolle.

Dashboard
Nachdem wir unseren Benutzer erstellt haben, landen wir auch schon auf dem Dashboard von Patchmon. Hier sehen wir später alle benötigten Informationen.

Einstellungen
Gehen wir einmal fix durch die aktuellen Einstellungsmöglichkeiten.
User Management
Unter dem Reiter User Management finden wir alles rund um Benutzer & Berechtigungen. Wir haben hier Möglichkeiten, weitere Benutzer hinzuzufügen, verschiedene Berechtigungsrollen zu erstellen und unser Profil anzupassen, mit bspw. einer Multi-Faktor-Authentifizierung.

Host Management
Hier gibt es die Möglichkeit, Gruppen für unsere Systeme zu erstellen, um uns eine bessere Übersicht zu verschaffen. Außerdem können wir die Einstellungen für die Agents vornehmen, wie bspw. das Einstellen des automatischen Update-Intervals, und erhalten Informationen zur aktuellen Version des Agenten.

Alert Management
Benachrichtigungen sind aktuell noch in Arbeit und bieten aktuell noch keine Konfigurationsmöglichkeiten. Ich vermute aber, dass dies eines der nächsten großen Feature-Updates sein wird. Wir sehen allerdings schon, dass wir später differenzieren können zwischen der Art der Updates.


Patch Management
Ein Feature, das auch sehr viel Potenzial beinhaltet, aktuell aber auch noch in Entwicklung ist, sind Policys für das Patch-Management. Diese erlauben uns später, genau zu definieren, was wann passieren soll, inklusive Auto-Updates.
An der Funktion wird mit größter Sorgfalt gearbeitet, da hier natürlich auch aus Security-Sicht einiges beachtet werden muss, um die Systeme nicht angreifbar zu machen.


Integration
Hier haben wir alle aktuell verfügbaren Integrationen aufgelistet. Zum einen gibt es die Möglichkeit, Auto-Enrollment für LXC Proxmox Container zu konfigurieren. Außerdem gibt es ein Add-On für das Tool Homepage (Dashboard) und, die bisher coolste Integration, Docker.
Die Docker-Integration gibt die Möglichkeit, Docker-Container auf den Hosts ebenfalls auf Updates zu überprüfen.


Server
Hier können Einstellungen für den Server an sich vorgenommen werden, bspw. das Branding, also die Logos anpassen, und einen Blick auf unsere Server-Version werfen.

Hosts
Kommen wir also zum Kern von Patchmon: das Überprüfen von aktuellen Patch-Ständen unserer Linux-Server. Das Hinzufügen eines Hosts ist kinderleicht.
Hinzufügen
Wenn wir im Reiter Hosts sind, können wir oben rechts Add Host auswählen.
In dem sich öffnenden Fenster geben wir nun einen Friendly Name für den Server an, womit wir ihn in Patchmon erkennen. Dann können wir den Server direkt in Gruppen zuweisen, falls vorhanden, und unter Integration noch wählen, ob eventuell darauf vorhandene Docker-Container auch überprüft werden sollen.

Nach Klick auf Create Host erhalten wir einen Befehl, den wir nun auf dem Host ausführen müssen, um den Agent zu installieren.

Auf dem System ausgeführt sieht das dann so aus.

Host Übersicht
Nun taucht der Host in der Übersicht auf und wird auch gleich überprüft.

Detail-Ansicht
Wenn wir auf den Host klicken, sehen wir eine Übersicht über installierte Pakete und wie viele davon ein Update benötigen.

Outdated Packages
Welche Pakete genau Updates benötigen, sehen wir, wenn wir auf den Punkt Outdated Packages gehen.

Docker Integration
Wenn wir die Docker-Integration aktiviert haben und sich Container auf dem System befinden, werden diese unter dem Punkt Docker aufgelistet. Wenn ein Image eine neuere Version verfügbar hat, werden wir hier dann darauf hingewiesen.

Fazit
Patchmon hat mich vor allem durch seine Klarheit und Einfachheit überzeugt. Keine überladene Oberfläche, keine unnötigen Features, sondern genau die Informationen, die man als Administrator wirklich braucht.
Auch wenn einige Funktionen wie Alerting oder Patch-Policies noch in Entwicklung sind, ist bereits gut erkennbar, wohin die Reise geht. Besonders die Docker-Integration und der saubere Agent-Ansatz machen Patchmon für moderne Umgebungen sehr spannend.
Wer heute schon den Überblick über seine Linux-Systeme behalten möchte und ein Tool sucht, das aktiv weiterentwickelt wird, sollte Patchmon definitiv ausprobieren.