Rocky container: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 1: Zeile 1:
= Installation =
 
=== DATEN ===
 
{| class="wikitable" style="background-color: #f2f2f2;"
 
! 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
 
|}
 
{{Vorlage:Rocky Setup}}
 
 
 
== Monitoring mit Uptime Kuma und Caddy (container.it2XX.int) ==
 
== Monitoring mit Uptime Kuma und Caddy (container.it2XX.int) ==
  
Zeile 59: Zeile 26:
 
jeder Container ein eigener Prozess, standardmäßig ohne Root-Rechte
 
jeder Container ein eigener Prozess, standardmäßig ohne Root-Rechte
  
=== podman-compose installieren ===
+
=== Wie Container sich im Netzwerk finden: DNS über container_name ===
 +
 
 +
Podman (wie Docker) legt für jedes in <code>networks:</code> definierte
 +
Netz ein eigenes internes DNS auf. Jeder Container ist darin unter
 +
seinem '''container_name''' erreichbar – nicht unter <code>localhost</code>
 +
und nicht über die Host-IP.
 +
 
 +
;Merksatz
 +
container_name = Hostname im internen Compose-Netz. Zwei Container im
 +
selben <code>networks:</code>-Eintrag erreichen sich gegenseitig per
 +
<code>ping container_name</code> bzw. <code>curl http://container_name:PORT</code>.
 +
 
 +
Das bedeutet konkret für unser Setup: Caddy spricht Uptime Kuma nicht
 +
über <code>127.0.0.1:3001</code> an, sondern über <code>uptime-kuma:3001</code>
 +
– beide hängen im Netz <code>monitoring</code>.
 +
 
 +
=== 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.
 +
 
 +
<syntaxhighlight lang="yaml">
 +
  uptime-kuma:
 +
    image: docker.io/louislam/uptime-kuma:1
 +
    container_name: uptime-kuma
 +
    volumes:
 +
      - uptime-kuma-data:/app/data
 +
    networks:
 +
      - monitoring
 +
</syntaxhighlight>
  
;Pip-Paket installieren (EPEL-Version ist teils veraltet)
+
;Wichtig
*dnf install -y python3-pip
+
Kein <code>ports:</code>-Eintrag nötig. Ein Backend-Dienst, der nur von
*pip3 install podman-compose
+
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).
  
=== Vorbereitung: Zertifikate ===
+
=== Container 2: Caddy (Reverse Proxy) ===
  
Die Zertifikate liegen bereits vor unter:
+
Caddy ist der einzige Container, der Ports nach außen (Host) öffnen
* <code>/etc/ssl/own.crt</code>
+
muss, weil er der einzige Kontaktpunkt von außen ist. Er terminiert
* <code>/etc/ssl/own.key</code>
+
TLS mit dem vorhandenen Zertifikat und leitet intern per Klartext-HTTP
 +
an <code>uptime-kuma:3001</code> weiter.
 +
 
 +
<syntaxhighlight lang="yaml">
 +
  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
 +
</syntaxhighlight>
 +
 
 +
;Hinweis SELinux
 +
Das <code>:Z</code> 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 ===
 
=== Caddyfile ===
  
;Caddyfile im Projektverzeichnis anlegen (z. B. /opt/monitoring/Caddyfile)
+
;Im selben Verzeichnis wie die compose.yaml anlegen (z. B. /opt/monitoring/Caddyfile)
 
<pre>
 
<pre>
 
kuma.it2XX.int {
 
kuma.it2XX.int {
Zeile 81: Zeile 106:
 
</pre>
 
</pre>
  
=== compose.yaml ===
+
Das <code>reverse_proxy uptime-kuma:3001</code> ist genau die Stelle, an
 +
der der container_name als DNS-Name verwendet wird.
 +
 
 +
=== Einen zweiten Dienst dazugeben ===
 +
 
 +
Soll z. B. HedgeDoc als zweiter Dienst hinzu, gilt immer dasselbe
 +
Schema:
 +
 
 +
# Container-Definition mit eigenem '''container_name''' in <code>compose.yaml</code>
 +
# Container hängt im '''selben''' <code>networks:</code>-Eintrag (<code>monitoring</code>)
 +
# Kein <code>ports:</code>-Eintrag beim Backend-Dienst – nur Caddy exponiert Ports
 +
# Eigener Host-Block in der Caddyfile, der per <code>container_name:internerPort</code> auf den Dienst zeigt
 +
 
 +
<syntaxhighlight lang="yaml">
 +
  hedgedoc:
 +
    image: docker.io/linuxserver/hedgedoc:latest
 +
    container_name: hedgedoc
 +
    volumes:
 +
      - hedgedoc-data:/config
 +
    networks:
 +
      - monitoring
 +
</syntaxhighlight>
 +
 
 +
<pre>
 +
notes.it2XX.int {
 +
    tls /etc/ssl/own.crt /etc/ssl/own.key
 +
    reverse_proxy hedgedoc:3000
 +
}
 +
</pre>
 +
 
 +
Nicht vergessen: neues Volume (<code>hedgedoc-data</code>) unter
 +
<code>volumes:</code> deklarieren.
 +
 
 +
;Merksatz
 +
Ein neuer Dienst braucht drei Dinge: eigener container_name, gleiches
 +
Netzwerk wie Caddy, eigener Host-Block in der Caddyfile mit
 +
<code>container_name:Port</code>. 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) ===
  
;Im selben Verzeichnis wie die Caddyfile anlegen
 
 
<syntaxhighlight lang="yaml">
 
<syntaxhighlight lang="yaml">
 
version: "3"
 
version: "3"
Zeile 93: Zeile 156:
 
     volumes:
 
     volumes:
 
       - uptime-kuma-data:/app/data
 
       - uptime-kuma-data:/app/data
 +
    networks:
 +
      - monitoring
 +
 +
  hedgedoc:
 +
    image: docker.io/linuxserver/hedgedoc:latest
 +
    container_name: hedgedoc
 +
    volumes:
 +
      - hedgedoc-data:/config
 
     networks:
 
     networks:
 
       - monitoring
 
       - monitoring
Zeile 111: Zeile 182:
 
     depends_on:
 
     depends_on:
 
       - uptime-kuma
 
       - uptime-kuma
 +
      - hedgedoc
  
 
volumes:
 
volumes:
 
   uptime-kuma-data:
 
   uptime-kuma-data:
 +
  hedgedoc-data:
 
   caddy-data:
 
   caddy-data:
  
Zeile 119: Zeile 192:
 
   monitoring:
 
   monitoring:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
;Hinweis SELinux
 
Das <code>:Z</code> 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.
 
  
 
=== Starten und Stoppen ===
 
=== Starten und Stoppen ===
Zeile 143: Zeile 210:
 
<pre>
 
<pre>
 
https://kuma.it2XX.int
 
https://kuma.it2XX.int
 +
https://notes.it2XX.int
 
</pre>
 
</pre>
  
Zeile 149: Zeile 217:
 
(Ping, TCP-Port, HTTP) und der Status live auf dem Dashboard verfolgen.
 
(Ping, TCP-Port, HTTP) und der Status live auf dem Dashboard verfolgen.
  
=== Merksatz ===
+
=== Merksatz (Zusammenfassung) ===
podman-compose = ein YAML-File statt mehrerer podman-run-Befehle | Rest
+
podman-compose = ein YAML-File statt mehrerer podman-run-Befehle |
bleibt gleich: rootless, daemonless, systemd-nahe Verwaltung möglich.
+
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

Version vom 5. Juli 2026, 10:51 Uhr

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

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

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
}

Das reverse_proxy uptime-kuma:3001 ist genau die Stelle, an der der container_name als DNS-Name verwendet wird.

Einen zweiten Dienst dazugeben

Soll z. B. HedgeDoc als zweiter Dienst hinzu, gilt immer dasselbe Schema:

  1. Container-Definition mit eigenem container_name in compose.yaml
  2. Container hängt im selben networks:-Eintrag (monitoring)
  3. Kein ports:-Eintrag beim Backend-Dienst – nur Caddy exponiert Ports
  4. Eigener Host-Block in der Caddyfile, der per container_name:internerPort auf 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