Reverse Proxy
openbill spricht einfaches HTTP auf Port 7739 des Hosts. Dein Reverse Proxy leitet dorthin weiter: 127.0.0.1:7739 vom selben Host, <server>:7739 aus einem Container (Nginx Proxy Manager) oder von einem anderen Rechner. HTTPS kommt von einem Reverse Proxy davor. Setze APP_URL in .env auf die öffentliche https://-Adresse.
Wem openbill glaubt
- Weitergeleitete Header (
X-Forwarded-For,-Proto,-Host,-Port) nur von den Adressen inTRUSTED_PROXIES: IP-Adressen oder Netze in CIDR-Schreibweise, kommagetrennt – keine Hostnamen (ein Docker-Dienstname wietraefikpasst auf nichts, die Header werden dann still ignoriert). Standard:127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7– ein Proxy auf demselben Host, im selben Docker-Netz oder in deinem LAN ist damit abgedeckt.X-Forwarded-Prefixglaubt openbill nie: openbill läuft an der Wurzel seines eigenen Hostnamens, nicht unter einem Pfad wie/openbill. - Host: nur der Host aus
APP_URL. Jeder andereHost-Header bekommt400 Bad Request. Dein Proxy muss den ursprünglichen Host weiterreichen (alle Beispiele unten tun das).
Der Port ist auf allen Adressen des Hosts veröffentlicht (OPENBILL_BIND=0.0.0.0), damit ein Proxy im Container oder auf einem anderen Rechner ihn ohne Zusatzaufwand erreicht. Wer Port 7739 von einer vertrauten Adresse aus erreicht, kann diese Header selbst setzen: https vortäuschen oder bei jedem Login-Versuch eine neue IP-Adresse (die Login-Sperre zählt je IP). Docker behält bei Anfragen von außen meist die echte Adresse, manche Setups (rootless Docker, der Userland-Proxy) reichen sie aber mit der Adresse des Docker-Gateways (172.x.0.1) weiter, und die steht in der Standardliste. Wer diese Lücke schließen will:
- Proxy auf demselben Host, nicht im Container (Caddy, nginx):
OPENBILL_BIND=127.0.0.1setzen (Standalone-Datei:"127.0.0.1:7739:8080"). Von anderen Rechnern ist der Port dann nicht erreichbar. - Proxy im Container oder auf einem anderen Host:
TRUSTED_PROXIESnur auf die Adresse des Proxys setzen (z. B.TRUSTED_PROXIES=192.168.1.10) oder Port7739in der Firewall deines Hosters aus dem Internet sperren (Docker umgeht ufw/firewalld bei veröffentlichten Ports). - Proxy im selben Docker-Netz (Traefik, Caddy im Compose): spricht direkt mit
openbill:8080; den veröffentlichten Port braucht es gar nicht.
Erreicht dein Proxy openbill von einer Adresse außerhalb von TRUSTED_PROXIES, ignoriert openbill seine Header: Links und Assets kommen als http:// heraus (Browser blockieren sie als Mixed Content), und alle Nutzer teilen sich die IP des Proxys – die Login-Sperre nach Fehlversuchen trifft dann alle gleichzeitig.
Caddy
invoices.example.com {
reverse_proxy localhost:7739
}Läuft Caddy im selben Compose-Projekt, nimm reverse_proxy openbill:8080. Caddy holt das Zertifikat selbst und begrenzt die Body-Größe nicht.
Traefik
Traefik und openbill brauchen ein gemeinsames Docker-Netz (hier das externe Netz proxy deines Traefik). Schreib das in docker-compose.override.yml neben docker-compose.yml:
services:
openbill:
# Traefik is the only way in: no published port
ports: !reset []
networks:
- default
- backend
- proxy
labels:
- traefik.enable=true
# openbill is in three networks: tell Traefik which one it shares with openbill
- traefik.docker.network=proxy
- traefik.http.routers.openbill.rule=Host(`invoices.example.com`)
- traefik.http.routers.openbill.entrypoints=websecure
- traefik.http.routers.openbill.tls.certresolver=letsencrypt
- traefik.http.services.openbill.loadbalancer.server.port=8080
networks:
proxy:
external: trueOhne traefik.docker.network nimmt Traefik womöglich openbills Adresse im internen Netz backend, die es nicht erreicht (502/504). Namen von Entrypoint und Cert-Resolver hängen von deinem Traefik ab. Traefiks Adresse im Netz proxy ist privat, die Standardliste TRUSTED_PROXIES deckt sie ab.
nginx
server {
listen 443 ssl;
server_name invoices.example.com;
# Template-Pakete und Toolkit-Pushes sind bis zu 30 MB groß
client_max_body_size 32m;
location / {
proxy_pass http://127.0.0.1:7739;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
}
}Nginx Proxy Manager
- Proxy-Host für
invoices.example.comanlegen. - Schema
http, Ziel die Adresse des Servers (öffentliche oder private IP, nicht127.0.0.1: das ist der Container von Nginx Proxy Manager selbst), Port7739. Teilen beide ein Docker-Netz (wie im Traefik-Beispiel), geht auchopenbill, Port8080. - Reiter SSL: Zertifikat anfordern, Force SSL einschalten.
- Reiter Advanced:
client_max_body_size 32m;
Checkliste
APP_URLbeginnt mithttps://und hat genau den Host, den der Browser benutzt.- Optional gehärtet: Port
7739ist aus dem Internet nicht erreichbar (OPENBILL_BIND=127.0.0.1oder Firewall), oderTRUSTED_PROXIESist auf den Proxy eingeschränkt. - Der Quelltext von
/de/loginzeigt Asset-Links mithttps://. Stehen dorthttp://-Links, steht die Adresse des Proxys nicht inTRUSTED_PROXIES. - Template-Pakete und Toolkit-Pushes sind bis zu 30 MB groß: mindestens
client_max_body_size 32merlauben (nginx); Caddy und Traefik begrenzen die Body-Größe standardmäßig nicht. - Das Template-Toolkit der Template-Autoren spricht von deren Rechner aus mit
APP_URL: Die Adresse muss dort mit gültigem Zertifikat erreichbar sein.