Rocky container
Installation
DATEN
| Parameter | Wert | Erläuterung |
|---|---|---|
| VM Name | container | Name der VM |
| Disk | 20GB | Vorgabe übernehmen |
| CPU | 4 Cores | Kerne |
| Ram | 4 GB | Speicher |
| Netzwerk (NIC) | DMZ | Interface-Zuweisung in VirtualBox |
| Admin | root | Passwort: radler |
| User | kit | Passwort: kit |
| IP | 10.88.2XX.39/24 | Statische IP |
| CIDR | 24 | Classless Inter-Domain Routing Präfixlänge |
| GW | 10.88.2XX.1 | GATEWAY |
| NS | 10.88.2XX.21 | Resolver |
| FQDN | container.it2XX.int | Fully Qualified Domain Name |
| DOM | it2XX.int | Domain Name |
Hostname
- hostnamectl hostname FQDN
Netzwerk
- nmcli con mod enp0s3 ipv4.addresses IP/CIDR
- nmcli con mod enp0s3 ipv4.gateway GW
- nmcli con mod enp0s3 ipv4.dns NS
- nmcli con mod enp0s3 ipv4.method manual
- nmcli con mod enp0s3 connection.autoconnect yes
- nmcli con up enp0s3
Nameserver & Suchdomain
Der DNS wird bereits über nmcli gesetzt. Suchdomain ergänzen:
- nmcli con mod enp0s3 ipv4.dns-search DOM
- nmcli con up enp0s3
Tools die wir haben wollen
- dnf install vim sudo git curl tcpdump nmap wget epel-release policycoreutils-python-utils tar
Kit Stamm-CA ziehen und in das System einbauen
- wget https://web.samogo.de/certs/ca.crt
- cp ca.crt /etc/pki/ca-trust/source/anchors/
- update-ca-trust extract
Zertifikat und Key holen
- wget -nv -O /tmp/own.int.tgz https://web.samogo.de/certs/it2XX.int.tgz
- tar -C /tmp -xvzf /tmp/own.int.tgz
- mv /tmp/fullchain.pem /etc/ssl/own.crt
- mv /tmp/privkey.pem /etc/ssl/own.key
Monitoring mit Uptime Kuma und Caddy (container.it2XX.int)
Als Ausblick nach der klassischen Systemadministration wird auf der Maschine container.it2XX.int ein kleines Container-Setup gezeigt: Uptime Kuma als Monitoring-Tool, davor Caddy als Reverse Proxy. Beide laufen als Podman-Container, verwaltet über podman-compose.
Was ist Podman
Podman ist eine Container-Engine, kompatibel zur Docker-CLI, aber ohne zentralen Root-Daemon.
- Wichtigste Unterschiede zu Docker
- Daemonless: Docker braucht einen dauerhaft laufenden Root-Daemon
(dockerd). Fällt er aus oder wird kompromittiert, sind alle Container betroffen. Podman startet Container als direkte Kindprozesse ohne zentralen Daemon.
- Rootless by Default: Podman-Container laufen standardmäßig ohne
Root-Rechte. Ein Escape aus dem Container landet nicht automatisch bei Root auf dem Host.
- Systemd-Integration: Podman-Container lassen sich nativ als
systemd-Units verwalten (Quadlets), passt gut in RHEL/Rocky-Abläufe.
- Merksatz
Docker = ein Daemon regiert alle Container (meist als Root) | Podman = jeder Container ein eigener Prozess, standardmäßig ohne Root-Rechte
podman-compose installieren
- Pip-Paket installieren (EPEL-Version ist teils veraltet)
- dnf install -y python3-pip
- pip3 install podman-compose
Vorbereitung: Zertifikate
Die Zertifikate liegen bereits vor unter:
/etc/ssl/own.crt/etc/ssl/own.key
Wie Container sich im Netzwerk finden: DNS über container_name
Podman (wie Docker) legt für jedes in networks: definierte
Netz ein eigenes internes DNS auf. Jeder Container ist darin unter
seinem container_name erreichbar – nicht unter localhost
und nicht über die Host-IP.
- Merksatz
container_name = Hostname im internen Compose-Netz. Zwei Container im
selben networks:-Eintrag erreichen sich gegenseitig per
ping container_name bzw. curl http://container_name:PORT.
Das bedeutet konkret für unser Setup: Caddy spricht Uptime Kuma nicht
über 127.0.0.1:3001 an, sondern über uptime-kuma:3001
– beide hängen im Netz monitoring.
Container 1: Uptime Kuma
Uptime Kuma braucht keinen externen Port. Es lauscht intern auf Port 3001 und wird ausschließlich über Caddy nach außen gereicht. Daten (SQLite-DB, Konfiguration) liegen in einem benannten Volume, damit sie Container-Neustarts und -Updates überleben.
uptime-kuma:
image: docker.io/louislam/uptime-kuma:1
container_name: uptime-kuma
volumes:
- uptime-kuma-data:/app/data
networks:
- monitoring
- Wichtig
Kein ports:-Eintrag nötig. Ein Backend-Dienst, der nur von
Caddy angesprochen wird, muss nicht auf dem Host exponiert werden –
das wäre sogar ein unnötiges Sicherheitsrisiko (Port läge dann offen
am Host-Netz, ungeschützt durch TLS).
Container 2: Caddy (Reverse Proxy)
Caddy ist der einzige Container, der Ports nach außen (Host) öffnen
muss, weil er der einzige Kontaktpunkt von außen ist. Er terminiert
TLS mit dem vorhandenen Zertifikat und leitet intern per Klartext-HTTP
an uptime-kuma:3001 weiter.
caddy:
image: docker.io/library/caddy:2
container_name: caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:Z
- /etc/ssl/own.crt:/etc/ssl/own.crt:Z
- /etc/ssl/own.key:/etc/ssl/own.key:Z
- caddy-data:/data
networks:
- monitoring
depends_on:
- uptime-kuma
- Hinweis SELinux
Das :Z an den Bind-Mounts (Caddyfile, Zertifikate) ist auf
Rocky notwendig, damit Caddy trotz aktivem SELinux Lesezugriff über den
passenden Kontext erhält. Bei benannten Volumes (uptime-kuma-data,
caddy-data) ist das nicht nötig, das übernimmt Podman selbst.
Caddyfile
Die Caddyfile ist Caddys eigene Konfigurationsdatei (reiner Text, kein YAML/JSON). Sie legt pro Domain fest, welches Zertifikat benutzt wird und wohin intern weitergeleitet wird.
- Im selben Verzeichnis wie die compose.yaml anlegen (z. B. /opt/monitoring/Caddyfile)
kuma.it2XX.int {
tls /etc/ssl/own.crt /etc/ssl/own.key
reverse_proxy uptime-kuma:3001
}
Aufbau:
kuma.it2XX.int {– für welchen Hostnamen (Host-Header) der Block gilttls ...– welches Zertifikat/Key für diesen Host verwendet wirdreverse_proxy uptime-kuma:3001– wohin die entschlüsselte Anfrage intern weitergeleitet wird (container_name als DNS-Name)
Einen zweiten Dienst dazugeben
Soll z. B. HedgeDoc als zweiter Dienst hinzu, gilt immer dasselbe Schema:
- Container-Definition mit eigenem container_name in
compose.yaml - Container hängt im selben
networks:-Eintrag (monitoring) - Kein
ports:-Eintrag beim Backend-Dienst – nur Caddy exponiert Ports - Eigener Host-Block in der Caddyfile, der per
container_name:internerPortauf den Dienst zeigt
hedgedoc:
image: docker.io/linuxserver/hedgedoc:latest
container_name: hedgedoc
volumes:
- hedgedoc-data:/config
networks:
- monitoring
notes.it2XX.int {
tls /etc/ssl/own.crt /etc/ssl/own.key
reverse_proxy hedgedoc:3000
}
Nicht vergessen: neues Volume (hedgedoc-data) unter
volumes: deklarieren.
- Merksatz
Ein neuer Dienst braucht drei Dinge: eigener container_name, gleiches
Netzwerk wie Caddy, eigener Host-Block in der Caddyfile mit
container_name:Port. Der Port nach außen bleibt immer nur
80/443 bei Caddy – alles andere läuft intern.
compose.yaml (vollständig, Beispiel mit zwei Backend-Diensten)
version: "3"
services:
uptime-kuma:
image: docker.io/louislam/uptime-kuma:1
container_name: uptime-kuma
volumes:
- uptime-kuma-data:/app/data
networks:
- monitoring
hedgedoc:
image: docker.io/linuxserver/hedgedoc:latest
container_name: hedgedoc
volumes:
- hedgedoc-data:/config
networks:
- monitoring
caddy:
image: docker.io/library/caddy:2
container_name: caddy
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:Z
- /etc/ssl/own.crt:/etc/ssl/own.crt:Z
- /etc/ssl/own.key:/etc/ssl/own.key:Z
- caddy-data:/data
networks:
- monitoring
depends_on:
- uptime-kuma
- hedgedoc
volumes:
uptime-kuma-data:
hedgedoc-data:
caddy-data:
networks:
monitoring:
Starten und Stoppen
- Stack starten
- cd /opt/monitoring
- podman-compose up -d
- Status prüfen
- podman-compose ps
- Stack stoppen
- podman-compose down
Test
- Aufruf im Browser
https://kuma.it2XX.int https://notes.it2XX.int
Beim ersten Aufruf fragt Uptime Kuma nach Anlegen eines Admin-Accounts. Danach lassen sich Monitore für ns, www, ldap, client und fw anlegen (Ping, TCP-Port, HTTP) und der Status live auf dem Dashboard verfolgen.
Merksatz (Zusammenfassung)
podman-compose = ein YAML-File statt mehrerer podman-run-Befehle | container_name = DNS-Name im internen Netz | nur Caddy exponiert Ports nach außen | jeder neue Dienst = eigener Block in compose.yaml + eigener Host-Block in der Caddyfile