Reverse-Proxy in eigenes Projekt ausgelagert
Ein Caddy pro Compose-Projekt funktioniert nur, solange es ein Projekt gibt: Port 443 laesst sich nicht teilen, und die TLS-Konfiguration verteilt sich sonst ueber fremde Repos. Der Proxy liegt jetzt zentral in docker-edge. - caddy-Service und Caddyfile entfernt - web haengt im gemeinsamen externen Netz "edge" und veroeffentlicht keinen Port mehr - json-file-Logrotation gesetzt, Docker rotiert sonst gar nicht - README auf die neue Aufteilung umgeschrieben Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
# Mailadresse fuer Let's Encrypt (Ablaufwarnungen). Ueberschreibbar per .env
|
|
||||||
email {$ACME_EMAIL:business.djnizz@gmail.com}
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Weiterleitung www -> Apex ----------------------------------------------
|
|
||||||
# Setzt einen DNS-A-Record fuer www.djnizz.at voraus. Wenn es den nicht gibt,
|
|
||||||
# diesen Block auskommentieren, sonst versucht Caddy dauerhaft erfolglos ein
|
|
||||||
# Zertifikat dafuer zu holen.
|
|
||||||
www.{$DOMAIN:djnizz.at} {
|
|
||||||
redir https://{$DOMAIN:djnizz.at}{uri} permanent
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Hauptseite -------------------------------------------------------------
|
|
||||||
{$DOMAIN:djnizz.at} {
|
|
||||||
encode zstd gzip
|
|
||||||
|
|
||||||
header {
|
|
||||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
|
||||||
X-Content-Type-Options "nosniff"
|
|
||||||
X-Frame-Options "SAMEORIGIN"
|
|
||||||
Referrer-Policy "strict-origin-when-cross-origin"
|
|
||||||
Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()"
|
|
||||||
Cross-Origin-Opener-Policy "same-origin"
|
|
||||||
-Server
|
|
||||||
}
|
|
||||||
|
|
||||||
# Astro haengt einen Content-Hash an alle Assets unter /_astro/ -
|
|
||||||
# die duerfen daher unbegrenzt gecacht werden.
|
|
||||||
# ">" ersetzt den Header, statt einen zweiten danebenzustellen -
|
|
||||||
# der Node-Adapter setzt fuer gehashte Assets bereits ein Cache-Control.
|
|
||||||
@immutable path /_astro/*
|
|
||||||
header @immutable >Cache-Control "public, max-age=31536000, immutable"
|
|
||||||
|
|
||||||
reverse_proxy web:4321
|
|
||||||
|
|
||||||
log {
|
|
||||||
output file /var/log/caddy/access.log {
|
|
||||||
roll_size 10MiB
|
|
||||||
roll_keep 4
|
|
||||||
roll_keep_for 336h
|
|
||||||
}
|
|
||||||
# Client-IPs werden gekuerzt und Cookies/Auth-Header nicht mitgeloggt.
|
|
||||||
# Muss zur Datenschutzerklaerung passen.
|
|
||||||
format filter {
|
|
||||||
wrap json
|
|
||||||
fields {
|
|
||||||
request>remote_ip ip_mask {
|
|
||||||
ipv4 24
|
|
||||||
ipv6 32
|
|
||||||
}
|
|
||||||
request>headers>Cookie delete
|
|
||||||
request>headers>Authorization delete
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
# djnizz.at
|
# djnizz.at
|
||||||
|
|
||||||
Website von DJ NIZZ. Astro 7 (statisch vorgerendert) hinter einem Node-Server,
|
Website von DJ NIZZ. Astro 7 (statisch vorgerendert) hinter einem Node-Server,
|
||||||
Tailwind 4, ausgeliefert per Docker + Caddy mit automatischem HTTPS.
|
Tailwind 4, als Docker-Container.
|
||||||
|
|
||||||
|
TLS und Domain kommen vom zentralen Reverse-Proxy im Projekt
|
||||||
|
[`docker-edge`](https://github.com/nizzgruber/docker-edge) – dieser Stack
|
||||||
|
veröffentlicht selbst keinen Port.
|
||||||
|
|
||||||
## Inhalte ändern
|
## Inhalte ändern
|
||||||
|
|
||||||
@@ -86,9 +90,9 @@ sudo netfilter-persistent save
|
|||||||
### 2. DNS
|
### 2. DNS
|
||||||
|
|
||||||
A-Record `djnizz.at` → öffentliche IP der Instanz. Wenn `www.djnizz.at` genutzt
|
A-Record `djnizz.at` → öffentliche IP der Instanz. Wenn `www.djnizz.at` genutzt
|
||||||
werden soll, dafür ebenfalls einen A-Record anlegen – sonst den `www`-Block im
|
werden soll, dafür ebenfalls einen A-Record anlegen – sonst den `www`-Block in
|
||||||
[`Caddyfile`](Caddyfile) auskommentieren, weil Caddy sonst dauerhaft erfolglos
|
`sites/djnizz.at.caddy` des Edge-Projekts auskommentieren, weil Caddy sonst
|
||||||
ein Zertifikat dafür anfordert.
|
dauerhaft erfolglos ein Zertifikat dafür anfordert.
|
||||||
|
|
||||||
### 3. Docker installieren
|
### 3. Docker installieren
|
||||||
|
|
||||||
@@ -135,76 +139,32 @@ meldet, ist normal und kein Fehler.
|
|||||||
|
|
||||||
### 5. Starten
|
### 5. Starten
|
||||||
|
|
||||||
|
TLS, Domains und Security-Header liegen **nicht** in diesem Repo, sondern
|
||||||
|
zentral im Projekt [`docker-edge`](https://github.com/nizzgruber/docker-edge):
|
||||||
|
ein einziger Caddy besitzt die Ports 80/443 und bedient alle Dienste der VM.
|
||||||
|
Zwei Container können sich Port 443 nicht teilen – deshalb bringt diese
|
||||||
|
Anwendung keinen eigenen Reverse-Proxy mehr mit.
|
||||||
|
|
||||||
|
Falls das gemeinsame Netz noch nicht existiert:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker network create edge
|
||||||
|
```
|
||||||
|
|
||||||
|
Dann diesen Stack starten – er veröffentlicht keinen einzigen Port, erreichbar
|
||||||
|
ist er nur über das Netz `edge`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone git@github-djnizz:nizzgruber/djnizz_website.git
|
git clone git@github-djnizz:nizzgruber/djnizz_website.git
|
||||||
cd djnizz_website
|
cd djnizz_website
|
||||||
```
|
|
||||||
|
|
||||||
Jetzt kommt es darauf an, ob auf dem Server **schon** etwas auf Port 80/443 hört
|
|
||||||
(z. B. ein Vault-Container oder ein vorhandener nginx). Prüfen mit:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo ss -tulpn | grep -E ':(80|443)\s'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Variante A – Ports sind frei:** Caddy dieses Projekts übernimmt sie.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose --profile edge up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
**Variante B – Ports sind belegt:** Zwei Prozesse können sich einen Port nicht
|
|
||||||
teilen. Dann läuft nur der Web-Container, gebunden an `127.0.0.1:4321`, und der
|
|
||||||
bereits vorhandene Reverse-Proxy leitet dorthin weiter.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
Passender vhost, wenn der vorhandene Proxy **Caddy auf dem Host** ist:
|
Die zugehörige vhost-Datei liegt im Edge-Projekt unter
|
||||||
|
`sites/djnizz.at.caddy` und zeigt auf `djnizz-web:4321`. Nach Änderungen dort:
|
||||||
```caddy
|
|
||||||
djnizz.at {
|
|
||||||
encode zstd gzip
|
|
||||||
reverse_proxy 127.0.0.1:4321
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Wenn es **nginx** ist:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
server_name djnizz.at;
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:4321;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Zertifikat danach mit `sudo certbot --nginx -d djnizz.at`.
|
|
||||||
|
|
||||||
Läuft der vorhandene Proxy selbst **in einem Container**, ist es sauberer, ihn
|
|
||||||
ins Netz dieses Projekts zu hängen statt über Loopback zu gehen – dann kann er
|
|
||||||
direkt `web:4321` ansprechen:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker network connect djnizz_website_djnizz <name-des-proxy-containers>
|
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
|
||||||
```
|
|
||||||
|
|
||||||
> In Variante B sind die Security-Header, das `immutable`-Caching und die
|
|
||||||
> IP-Maskierung aus dem [`Caddyfile`](Caddyfile) **nicht** aktiv – die stecken in
|
|
||||||
> der Caddy-Konfiguration dieses Projekts. Übernimm die entsprechenden Blöcke in
|
|
||||||
> die Konfiguration deines vorhandenen Proxys, sonst stimmt auch die Aussage in
|
|
||||||
> der Datenschutzerklärung zu gekürzten IP-Adressen nicht mehr.
|
|
||||||
|
|
||||||
Caddy holt sich das Let's-Encrypt-Zertifikat automatisch, sobald die Domain auf
|
|
||||||
den Server zeigt. Fortschritt prüfen:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose logs -f caddy
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Updates ausrollen
|
### Updates ausrollen
|
||||||
@@ -216,24 +176,17 @@ docker compose up -d --build
|
|||||||
|
|
||||||
### Konfiguration
|
### Konfiguration
|
||||||
|
|
||||||
Domain und ACME-Mailadresse lassen sich per `.env` neben der
|
Dieser Stack hat keine eigene Konfiguration – Domain, Zertifikate und Header
|
||||||
`docker-compose.yml` überschreiben:
|
liegen im Edge-Projekt.
|
||||||
|
|
||||||
```env
|
|
||||||
DOMAIN=djnizz.at
|
|
||||||
ACME_EMAIL=business.djnizz@gmail.com
|
|
||||||
```
|
|
||||||
|
|
||||||
> Das Volume `caddy_data` enthält die TLS-Zertifikate. Nicht löschen – sonst
|
|
||||||
> werden bei jedem Neustart neue Zertifikate angefordert und irgendwann greift
|
|
||||||
> das Rate-Limit von Let's Encrypt.
|
|
||||||
|
|
||||||
## Datenschutz
|
## Datenschutz
|
||||||
|
|
||||||
Die Seite lädt nichts von externen Servern: Schriften sind selbst gehostet, es
|
Die Seite lädt nichts von externen Servern: Schriften sind selbst gehostet, es
|
||||||
gibt keine Cookies, kein Tracking und keine eingebetteten Player. Caddy kürzt in
|
gibt keine Cookies, kein Tracking und keine eingebetteten Player.
|
||||||
den Access-Logs die Client-IP (`ip_mask`) und löscht sie nach 14 Tagen – das muss
|
|
||||||
so bleiben, sonst stimmt die Datenschutzerklärung nicht mehr.
|
Der Edge-Caddy kürzt in den Access-Logs die Client-IP (`ip_mask`) und löscht sie
|
||||||
|
nach 14 Tagen. Das muss so bleiben, sonst stimmt die Datenschutzerklärung nicht
|
||||||
|
mehr – der zuständige Baustein heißt dort `private_log`.
|
||||||
|
|
||||||
Wenn später ein Booking-Formular, Analytics oder Spotify-/YouTube-Embeds
|
Wenn später ein Booking-Formular, Analytics oder Spotify-/YouTube-Embeds
|
||||||
dazukommen, muss `src/pages/datenschutz.astro` entsprechend erweitert werden.
|
dazukommen, muss `src/pages/datenschutz.astro` entsprechend erweitert werden.
|
||||||
|
|||||||
+20
-40
@@ -1,51 +1,31 @@
|
|||||||
|
# Nur die Anwendung. TLS, Domains und Security-Header liegen zentral im
|
||||||
|
# Edge-Projekt (docker-edge), das als einziger Stack die Ports 80/443 besitzt.
|
||||||
|
#
|
||||||
|
# Voraussetzung: das gemeinsame Netz existiert und der Edge-Caddy laeuft.
|
||||||
|
# docker network create edge
|
||||||
|
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
build: .
|
build: .
|
||||||
image: djnizz-website:latest
|
image: djnizz-website:latest
|
||||||
container_name: djnizz-web
|
container_name: djnizz-web
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Nur auf Loopback veroeffentlicht: aus dem Internet nicht erreichbar,
|
# Kein Port-Mapping: der Node-Prozess ist ausschliesslich innerhalb des
|
||||||
# aber ein bereits vorhandener Reverse-Proxy auf dem Host kann darauf
|
# edge-Netzes erreichbar, von aussen kommt man nur ueber Caddy dran.
|
||||||
# zugreifen. Mit eigenem Caddy (Profil "edge") laeuft der Verkehr
|
expose:
|
||||||
# stattdessen ueber das interne Docker-Netz.
|
- '4321'
|
||||||
ports:
|
|
||||||
- '${WEB_BIND:-127.0.0.1:4321}:4321'
|
|
||||||
networks:
|
networks:
|
||||||
- djnizz
|
- edge
|
||||||
security_opt:
|
security_opt:
|
||||||
- no-new-privileges:true
|
- no-new-privileges:true
|
||||||
|
# Docker rotiert json-file-Logs sonst gar nicht - die Platte laeuft voll.
|
||||||
caddy:
|
logging:
|
||||||
# Startet nur mit: docker compose --profile edge up -d
|
driver: json-file
|
||||||
# Weglassen, wenn auf dem Server bereits ein Reverse-Proxy die Ports
|
options:
|
||||||
# 80/443 belegt - zwei Prozesse koennen sich einen Port nicht teilen.
|
max-size: '10m'
|
||||||
profiles: ['edge']
|
max-file: '3'
|
||||||
image: caddy:2-alpine
|
|
||||||
container_name: djnizz-caddy
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- '80:80'
|
|
||||||
- '443:443'
|
|
||||||
- '443:443/udp' # HTTP/3
|
|
||||||
environment:
|
|
||||||
DOMAIN: ${DOMAIN:-djnizz.at}
|
|
||||||
ACME_EMAIL: ${ACME_EMAIL:-business.djnizz@gmail.com}
|
|
||||||
volumes:
|
|
||||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
||||||
- caddy_data:/data # Zertifikate - dieses Volume nicht loeschen
|
|
||||||
- caddy_config:/config
|
|
||||||
- caddy_logs:/var/log/caddy
|
|
||||||
depends_on:
|
|
||||||
- web
|
|
||||||
networks:
|
|
||||||
- djnizz
|
|
||||||
security_opt:
|
|
||||||
- no-new-privileges:true
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
caddy_data:
|
|
||||||
caddy_config:
|
|
||||||
caddy_logs:
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
djnizz:
|
edge:
|
||||||
|
name: edge
|
||||||
|
external: true
|
||||||
|
|||||||
Reference in New Issue
Block a user