Endlich Überblick über Linux-Updates - dieses Tool fehlte mir im Homelab | Patchmon

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.