Der Reverse Proxy ist die Haustür des Servers. Alle Anfragen aus dem Internet kommen bei ihm an, er sorgt für HTTPS und reicht sie an den richtigen Container weiter.
Was ist ein Reverse Proxy?
Jeder Dienst läuft in seinem eigenen Container mit eigener IP. Von außen soll aber alles über eine Adresse und die Standardports 80 (HTTP) und 443 (HTTPS) erreichbar sein. Der Reverse Proxy schaut, welcher Name aufgerufen wurde, und leitet an den passenden Container weiter:
https://docs.meinverein.de ─┐ ┌─▶ 192.168.178.40:8000 paperless
https://mitglieder.meinverein.de ─┼─▶ proxy (nginx) :443 ─┼─▶ 192.168.178.42:80 mitglieder
https://flows.meinverein.de ─┘ └─▶ 192.168.178.43:5678 flows
Nur dieser eine Container ist aus dem Internet erreichbar, Zertifikate werden zentral verwaltet, und die Anwendungen müssen sich um Verschlüsselung nicht kümmern. nginx ist dafür einer der verbreitetsten Webserver überhaupt: schnell, stabil und gut dokumentiert.
HTTPS mit Let’s Encrypt
Let’s Encrypt stellt kostenlose TLS-Zertifikate aus. Das Werkzeug certbot beweist dabei, dass einem die Domain gehört, trägt das Zertifikat direkt in nginx ein und erneuert es automatisch, bevor es nach 90 Tagen abläuft.
Installation
Container proxy (ID 100, IP 192.168.178.30) aus der Vorlage klonen, 1 Kern und 512 MB reichen. Im Router werden die Ports 80 und 443 an genau diese IP weitergeleitet (siehe Domain, DNS und Erreichbarkeit).
sudo apt install -y nginx certbot python3-certbot-nginx
sudo rm /etc/nginx/sites-enabled/default
Eine Anwendung freischalten
Pro Anwendung eine kleine Datei. Zunächst nur für Port 80, den HTTPS-Teil ergänzt certbot gleich selbst.
# /etc/nginx/sites-available/docs.meinverein.de
server {
listen 80;
server_name docs.meinverein.de;
client_max_body_size 100m; # größere Uploads erlauben
location / {
proxy_pass http://192.168.178.40:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# für Anwendungen mit Live-Verbindungen (n8n, Paperless)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo ln -s /etc/nginx/sites-available/docs.meinverein.de /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# Zertifikat holen. certbot ergänzt den HTTPS-Block und die Weiterleitung selbst.
sudo certbot --nginx -d docs.meinverein.de --redirect \
-m vorstand@meinverein.de --agree-tos --no-eff-email
# Erneuerung testen (läuft danach automatisch per systemd-Timer)
sudo certbot renew --dry-run
Für jede weitere Anwendung dasselbe: Datei kopieren, Name und Ziel-IP ändern, verlinken, certbot --nginx -d ….
Die Anwendungen nur für den Proxy öffnen
Damit niemand im Heimnetz den Proxy umgeht, nehmen die Anwendungs-Container Verbindungen auf ihrem Port nur vom Proxy an. Das geht direkt in Proxmox: beim Container unter Firewall → Optionen die Firewall einschalten und eine Regel „Eingehend, Quelle 192.168.178.30, Port 8000, Akzeptieren“ anlegen. SSH aus dem Heimnetz bleibt erlaubt.
Mit Ansible
Wer die Seiten nicht von Hand anlegen will, beschreibt sie einmal als Liste und lässt Ansible die Dateien erzeugen:
# proxy.yml (Auszug)
- hosts: proxy
become: true
vars:
sites:
- { name: docs.meinverein.de, target: "192.168.178.40:8000" }
- { name: medien.meinverein.de, target: "192.168.178.41:80" }
- { name: mitglieder.meinverein.de, target: "192.168.178.42:80" }
- { name: flows.meinverein.de, target: "192.168.178.43:5678" }
- { name: www.meinverein.de, target: "192.168.178.44:80" }
- { name: cloud.meinverein.de, target: "192.168.178.45:80" }
- { name: tresor.meinverein.de, target: "192.168.178.46:8080" }
- { name: status.meinverein.de, target: "192.168.178.32:3001" }
tasks:
- name: nginx-Seiten aus Vorlage
ansible.builtin.template:
src: site.conf.j2
dest: "/etc/nginx/sites-available/{{ item.name }}"
loop: "{{ sites }}"
notify: nginx neu laden
handlers:
- name: nginx neu laden
ansible.builtin.service: { name: nginx, state: reloaded }
Typische Stolpersteine
- Zertifikat schlägt fehl: DNS zeigt noch nicht auf die richtige IP, oder Port 80 ist im Router nicht an den Proxy weitergeleitet.
- 502 Bad Gateway: Die Anwendung läuft nicht oder die Firewall des Containers lässt den Proxy nicht durch.
- Endlose Weiterleitungen: Die Anwendung weiß nicht, dass sie hinter HTTPS läuft. Meist fehlt
X-Forwarded-Proto, oder in der Anwendung ist die externe URL nicht eingetragen. - Upload bricht ab:
client_max_body_sizeerhöhen.
Lieber klicken als tippen? Der Nginx Proxy Manager ist nginx mit Weboberfläche: Hosts und Zertifikate legt man dort per Formular an. Für den Einstieg bequemer, dafür schwerer mit Ansible und Git zu verwalten. Ich bleibe bei den Textdateien.