Containerized LEMP: Best Practices für Nginx und PHP in Docker

Ein moderner LEMP-Stack (Linux, Nginx, MySQL/MariaDB, PHP) lässt sich in Containern effizient betreiben, um Isolation, Portabilität und einfache Skalierung zu gewährleisten. Durch die Nutzung von Docker und Docker Compose können Nginx als Reverse Proxy, PHP-FPM als Applikationsserver und die Datenbank sauber orchestriert werden. In diesem Tutorial zeigen wir praxisnah, wie ein containerisierter LEMP-Stack aufgebaut und nach Best Practices konfiguriert wird.

Systemvoraussetzungen

  • Linux-Distribution: Ubuntu 22.04 LTS oder CentOS 9
  • Root- oder sudo-Zugriff
  • Docker installiert:
    sudo apt install docker.io -y
  • Docker Compose installiert:
    sudo apt install docker-compose -y
  • Grundkenntnisse in CLI, Netzwerken und Linux-Dateisystem

Projektstruktur

Für einen strukturierten Aufbau empfiehlt sich folgende Verzeichnisstruktur:

/var/www/container-lemp/
├─ app/
│  └─ Dockerfile
├─ nginx/
│  └─ default.conf
├─ db/
│  └─ init.sql
└─ docker-compose.yml

Dockerfile für PHP-FPM

PHP-FPM wird in einem eigenen Container betrieben, um Webanfragen der App zu verarbeiten.

# app/Dockerfile
FROM php:8.1-fpm

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y 
    libpq-dev 
    libonig-dev 
    zip 
    unzip 
    git 
    && docker-php-ext-install pdo pdo_mysql mbstring

COPY . .

RUN chown -R www-data:www-data /var/www/html

Nginx als Reverse Proxy

Nginx leitet Anfragen an den PHP-FPM Container weiter und dient als Webserver für statische Assets.

# nginx/default.conf
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/html;

    index index.php index.html index.htm;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        access_log off;
    }
}

Datenbank Setup

MySQL oder MariaDB können via Container betrieben werden. Initialisierungsskripte erleichtern die Bereitstellung.

# db/init.sql
CREATE DATABASE webapp;
CREATE USER webuser@'%' IDENTIFIED BY 'Str0ngP@ss';
GRANT ALL PRIVILEGES ON webapp.* TO webuser@'%';
FLUSH PRIVILEGES;

Docker Compose Datei

Docker Compose orchestriert die Services, definiert Netzwerke, Volumes und Abhängigkeiten.

# docker-compose.yml
version: "3.9"

services:
  app:
    build: ./app
    container_name: php-fpm
    restart: always
    networks:
      - lempnet
    volumes:
      - ./app:/var/www/html
    depends_on:
      - db

  nginx:
    image: nginx:stable
    container_name: nginx
    restart: always
    ports:
      - "80:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./app:/var/www/html
    depends_on:
      - app
    networks:
      - lempnet

  db:
    image: mariadb:11
    container_name: mariadb
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: RootStr0ngP@ss
      MYSQL_DATABASE: webapp
      MYSQL_USER: webuser
      MYSQL_PASSWORD: Str0ngP@ss
    volumes:
      - db-data:/var/lib/mysql
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    networks:
      - lempnet

volumes:
  db-data:

networks:
  lempnet:

Stack starten und prüfen

cd /var/www/container-lemp
docker-compose up -d
docker-compose ps

Logs und Monitoring

  • PHP-FPM Logs:
    docker-compose logs -f app
  • Nginx Logs:
    docker-compose logs -f nginx
  • Datenbank Logs:
    docker-compose logs -f db

Netzwerkplanung

Für Multi-Container Deployments können eigene Subnetze definiert werden, um Isolation und Sicherheit zu erhöhen.

IPv4 Beispiel

<math>
PHP-FPM-IP = 172.21.0.2/24
MariaDB-IP = 172.21.0.3/24
Nginx-IP = 172.21.0.4/24
Subnetzadresse = 172.21.0.0
Broadcastadresse = 172.21.0.255
</math>

IPv6 Beispiel (optional)

<math>
PHP-FPM-IP = fd00:lemp:1::2/64
MariaDB-IP = fd00:lemp:1::3/64
Nginx-IP = fd00:lemp:1::4/64
Subnetzadresse = fd00:lemp:1::0
Broadcastadresse = fd00:lemp:1::ffff:ffff:ffff:ffff
</math>

Best Practices

  • Volumes für Datenbank und App nutzen, um Persistenz sicherzustellen
  • Umgebungsvariablen und Secrets sicher verwalten
  • Statische Assets via Nginx ausliefern und Caching aktivieren
  • SSL/TLS für HTTPS einsetzen (z. B. mit Let’s Encrypt)
  • Health Checks und Restart-Richtlinien für Container definieren
  • Regelmäßige Backups für Datenbankvolumes
  • Test- und Produktionsumgebung strikt trennen
  • Firewall und Docker-Netzwerke konfigurieren
  • Monitoring über Logs oder Tools wie Prometheus/Grafana implementieren
  • Container-Updates kontrolliert durchführen, um Downtime zu vermeiden

Konfiguriere Cisco Router & Switches und liefere ein Packet-Tracer-Lab/GNS3

Ich biete professionelle Unterstützung im Bereich Netzwerkkonfiguration und Network Automation für private Anforderungen, Studienprojekte, Lernlabore, kleine Unternehmen sowie technische Projekte. Ich unterstütze Sie bei der Konfiguration von Routern und Switches, der Erstellung praxisnaher Topologien in Cisco Packet Tracer, dem Aufbau und Troubleshooting von GNS3- und EVE-NG-Labs sowie bei der Automatisierung von Netzwerkaufgaben mit Netmiko, Paramiko, NAPALM und Ansible. Kontaktieren Sie mich jetzt – klicken Sie hier.

Meine Leistungen umfassen:

  • Professionelle Konfiguration von Routern und Switches

  • Einrichtung von VLANs, Trunks, Routing, DHCP, NAT, ACLs und weiteren Netzwerkfunktionen

  • Erstellung von Topologien und Simulationen in Cisco Packet Tracer

  • Aufbau, Analyse und Fehlerbehebung von Netzwerk-Labs in GNS3 und EVE-NG

  • Automatisierung von Netzwerkkonfigurationen mit Python, Netmiko, Paramiko, NAPALM und Ansible

  • Erstellung von Skripten für wiederkehrende Netzwerkaufgaben

  • Dokumentation der Konfigurationen und Bereitstellung nachvollziehbarer Lösungswege

  • Konfigurations-Backups, Optimierung bestehender Setups und technisches Troubleshooting

Benötigen Sie Unterstützung bei Ihrem Netzwerkprojekt, Ihrer Simulation oder Ihrer Network-Automation-Lösung? Kontaktieren Sie mich jetzt – klicken Sie hier.

Related Articles