Schlagwort: Ubuntu

  • Docker Services mit Traefik verwalten

    Mit dem Reverse-Proxy Traefik lassen sich Docker-Container effizient verwalten und komfortabel im Browser aufrufen – ganz ohne manuelles Jonglieren mit Portnummern.

    In diesem Beitrag richten wir eine lokale Testumgebung ein, die verschiedene Webprojekte umfasst: mehrere WordPress-Instanzen, phpMyAdmin, Joomla, Drupal, eine statische HTML Seiten und eine Landing-Page für das Projekt. Host-System ist Ubuntu 25.04.

    Alle Dateien und Skripte des Projekts haben wir für Sie auf GitHub bereitgestellt.

    GitHub. Projekt WebDev

    Im vorherigen Beitrag haben wir bereits gezeigt, wie sich eine einfache WordPress-Testumgebung mit Docker aufsetzen lässt. Nun erweitern wir dieses Setup und machen es durch Traefik deutlich flexibler und übersichtlicher.

    Projektstruktur

    Alle Dienste werden in einem übergeordneten Projektverzeichnis namens WebDev organisiert. Für jeden Container gibt es einen eigenen Unterordner mit einer individuellen docker-compose.yaml. Ein zentrales Skript steuert den Start und Stopp aller Container gleichzeitig.

    Das Projekt umfasst:

    • traefik – zentrale Reverse-Proxy-Konfiguration
    • wp1, wp2 – zwei eigenständige WordPress-Instanzen
    • drupal1 – Drupal mit PostgreSQL
    • joomla1 – Joomla mit MySQL
    • html – statische Website mit NGINX
    • pma – phpMyAdmin zur Datenbankverwaltung
    • landingpage – eine zentrale Startseite mit Links zu allen Projekten
    • README.md-Dateien – Dokumentation pro Container (optional)

    Verzeichnisbaum:

    WebDev/
    ├── drupal1/
    │   ├── compose.yaml
    │   └── README.md
    ├── html/
    │   ├── compose.yaml
    │   └── public/
    │       └── index.html
    ├── joomla1/
    │   ├── compose.yaml
    │   └── README.md
    ├── landingpage/
    │   ├── compose.yaml
    │   ├── public/
    │   │   ├── index.html
    │   │   └── styles.css
    │   └── README.md
    ├── pma/
    │   ├── compose.yaml
    │   └── README.md
    ├── traefik/
    │   └── compose.yaml
    ├── wp1/
    │   ├── compose.yaml
    │   └── README.md
    ├── wp2/
    │   ├── compose.yaml
    │   └── README.md
    ├── start-all.sh
    ├── stop-all.sh
    └── README.md

    Container erstellen

    Die einzelnen Unterordner enthalten jeweils ihre eigene Compose-Datei. Jedes Web-Projekt verwendet einen eigenen Datenbank-Container.

    1. Traefik als Reverse-Proxy

    Der traefik-Container ist die zentrale Schaltstelle. Er lauscht auf Port 80 (lokal begrenzt auf 127.0.0.1) und leitet Anfragen basierend auf der gewünschten Domain weiter.

    Jeder Service registriert sich bei Traefik über Container-Labels, etwa:

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wp1.rule=Host(`wp1.localhost`)"
      - "traefik.http.routers.wp1.entrypoints=web"

    Anhand diese Labels erkennt Traefik den Service, an den die Anfrage weitergeleitet werden soll. Ohne Traefik würde diese Adressierung durch Port-Nummern vorgenommen.

    Wir erstellen den Container mit einer compose.yaml Datei:

    # traefik compose local restricted
    
    services:
      traefik:
        image: traefik:v3.4
        command:
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--entrypoints.web.address=:80"
          - "--api.dashboard=true"
          - "--api.insecure=true"    
          - "--log.level=INFO"
        ports:
          - "127.0.0.1:80:80"        # nur lokal zugänglich
          - "127.0.0.1:8080:8080"    # Dashboard nur lokal
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
        networks:
          - webdev-net
        restart: unless-stopped
    
    networks:
      webdev-net:
        external: true

    Ein Dashboard unter http://localhost:8080 zeigt aktive Router, Services und Netzwerke. Für die Testumgebung ist eine Authentifizierung nicht erforderlich, im Produktiveinsatz aber unbedingt.

    Die Ansicht im Dashboard lässt sich mit den üblichen Tastenkombinationen vergrößern und verkleinern, ohne dabei unbenutzbar zu werden.

    Strg + Plus-Taste
    Strg + Bindestrick (Minus)

    2. Webprojekte (CMS und statisch)

    Jedes CMS wird in einem eigenen Compose-Projekt betrieben:

    • WordPress (mit MariaDB)
    • Drupal (mit PostgreSQL)
    • Joomla (mit MySQL)
    • HTML-Seite (mit NGINX)

    Alle sind über .localhost-Domains erreichbar, z. B.

    wp1.localhostdrupal1.localhost

    Beispiel für eine compose.yaml Datei:

    # compose.yaml Example
    
    services:
      wordpress1:
        image: wordpress
        environment:
          WORDPRESS_DB_HOST: db_wp1
          WORDPRESS_DB_USER: wordpress
          WORDPRESS_DB_PASSWORD: examplepass
          WORDPRESS_DB_NAME: wordpress
        volumes:
          - wp1_data:/var/www/html
        networks:
          - webdev-net
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.wp1.rule=Host(`wp1.localhost`)"
          - "traefik.http.routers.wp1.entrypoints=web"
        restart: unless-stopped
    
      db_wp1:
        image: mariadb
        container_name: wp1-db_wp1
        environment:
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress
          MYSQL_PASSWORD: examplepass
          MYSQL_ROOT_PASSWORD: rootpass
        volumes:
          - db_wp1_data:/var/lib/mysql
        networks:
          - webdev-net
        restart: unless-stopped
    
    volumes:
      wp1_data:
      db_wp1_data:
    
    networks:
      webdev-net:
        external: true

    Erläuterungen:

    Domain wp1.localhostwird von Traefik per Label erkann
    Netzwerk webdev-netalle Container (inkl. Traefik) müssen darin sein
    Keine Ports notwendigdank Traefik entfallen individuelle ports:-Einträge
    Datenbank-Zugang über phpMyAdminMit Host db_wp1, Benutzer wordpress, Passwort examplepass

    Sie starten die einzelnen Web-Instanzen jeweils aus dem Verzeichnis heraus, in dem sich die compose.yaml Datei befindet. Weiter unten zeigen wir, wie man alle Container gleichzeitig per Skript starten kann.

    In einem Terminal, z.B. für wp1:

    cd WebDev/wp1
    # und Starten mit
    sudo docker compose up -d

    Die Seite im Browser erreichen Sie dann mit der Eingabe von

    wp1.localhost

    Weiter unten erklären wir, wie Sie eine Landing-Page erstellen, von der aus alle Web-Projekte im Browser aufgerufen werden.

    Nun startet wie gewohnt die Installation:

    3. phpMyAdmin

    Zur Verwaltung der MariaDB- und MySQL-Datenbanken verwenden wir phpMyAdmin. Durch die Umgebungsvariable PMA_ARBITRARY=1 kann man beim Login frei wählen, mit welchem Datenbankhost man sich verbindet – etwa

    db_wp1oder db_joomla1

    Die WordPress-Datenbank ist vor der Installation noch leer, Joomla haben wir schon eingerichtet, die Datenbank ist mit Inhalten gefüllt.

    4. Landing Page

    Eine einfache statische Startseite listet alle Projekte mit Links auf. Sie wird über NGINX bereitgestellt und ist unter webdev.localhost erreichbar. Das HTML-Gerüst ist minimal gehalten, das Styling erfolgt per styles.css.

    Netzwerk

    Alle Container verwenden dasselbe benannte externe Netzwerk webdev-net, um miteinander zu kommunizieren und von Traefik erkannt zu werden.

    Container starten und stoppen per Skript

    Für den bequemen Start/Stopp der gesamten Umgebung haben wir zwei Skripte angelegt, die Sie im Terminal aufrufen:

    # alle Projekte starten:
    sudo bash start-all.sh
    # alle Projekte stoppen:
    sudo bash stop-all.sh   

    Weil docker-compose in unserer Installation Administratorrechte benötigt, also der einzelne Befehl lauten würde:

    sudo docker compose up -d

    starten wir zunächst ein Terminal als Administrator sudo bash und führen anschließend das Skript mit allen Start- oder Stop-Befehlen aus.

    Das Start-Skript im Editor VSCode. Links im Explorer die Projektverzeichnisse.

    Ausblick

    Die Umgebung lässt sich flexibel erweitern – z. B. um:

    • weitere CMS-Systeme wie Typo3 oder DokuWiki
    • Webmail, Newsletter-Tools oder Shop-Systeme
    • einen internen Mailserver für Testzwecke
    • automatische Zertifikate mit Let’s Encrypt (bei externem Zugriff)