Website djnizz.at: Hero- und About-Sektion mit Docker-Deployment

Astro 7 mit Tailwind 4 und Node-Adapter. Alle Seiten werden vorgerendert,
der Node-Server ist dabei, damit spaeter einzelne Routen (Booking-Formular)
ohne Umbau am Deployment dynamisch werden koennen.

Inhalt:
- Fullscreen-Hero mit freigestelltem Render, animierten Lasern und
  Genre-Laufband; Typografie als HTML statt eingebranntem Bildtext
- About-Sektion mit Genre-Karten und Eckdaten
- Impressum und Datenschutzerklaerung
- Zentrale Inhaltsdatei src/data/site.ts

Technik:
- Selbst gehostete Schriften, keine Cookies, kein Tracking, keine
  externen Requests
- Docker Multi-Stage (238 MB) hinter Caddy mit automatischem HTTPS,
  Security-Headern und IP-maskierten Logs
- scripts/cutout.mjs stellt den Render ueber eine Sobel-Kantenkarte frei
  und entfernt eingeschlossene Hintergrundflaechen

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 23:17:13 +02:00
co-authored by Claude Opus 5
commit 074c87ed79
38 changed files with 7740 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
# djnizz.at
Website von DJ NIZZ. Astro 7 (statisch vorgerendert) hinter einem Node-Server,
Tailwind 4, ausgeliefert per Docker + Caddy mit automatischem HTTPS.
## Inhalte ändern
Fast alles steht in **[`src/data/site.ts`](src/data/site.ts)** Texte, Genres,
Kontaktdaten, Navigation, Social-Links. Für normale Textänderungen musst du
keine Komponente anfassen.
- **Social-Profile**: In `SOCIALS` die `url` eintragen. Einträge ohne URL werden
automatisch ausgeblendet, du kannst also alles stehen lassen, was du noch
nicht hast.
- **Neues Genre**: In `GENRES` ergänzen. Marquee, Genre-Karten, Zähler in der
About-Sektion, Footer-Text und die strukturierten Daten ziehen automatisch nach.
Für die Akzentfarbe muss der Name in `accentVar` in
[`src/components/About.astro`](src/components/About.astro) existieren.
- **Impressum / Datenschutz**: [`src/pages/impressum.astro`](src/pages/impressum.astro)
und [`src/pages/datenschutz.astro`](src/pages/datenschutz.astro).
## Lokal entwickeln
```bash
npm install
npm run dev
```
Läuft auf http://localhost:4321.
```bash
npm run build # nach dist/ bauen
npm run preview # gebaute Seite wie in Produktion starten
```
## Bild-Assets
Die Quellbilder liegen in `src/assets/`. Abgeleitete Dateien (Hero-Hintergrund,
OG-Bild, Favicons) erzeugt:
```bash
npm run assets
```
Der freigestellte Render `src/assets/nizz-cutout.png` entsteht separat aus dem
Ganzkörper-Bild:
```bash
node scripts/cutout.mjs pfad/zum/render.jpg src/assets/nizz-cutout.png 70
```
Das Skript trennt über eine Sobel-Kantenkarte frei und entfernt zusätzlich
eingeschlossene Hintergrundflächen (z. B. zwischen Arm und Oberkörper). Der
letzte Parameter ist die Kantenschwelle höher = aggressiver, damit fallen
weiche Bodenschatten weg.
## Deployment auf Oracle Cloud
Läuft sowohl auf Ampere A1 (ARM) als auch auf x86 die verwendeten Images sind
Multi-Arch.
### 1. Netzwerk freigeben (zwei Stellen!)
Der häufigste Stolperstein bei OCI: Ports müssen **sowohl** in der Cloud-Firewall
**als auch** in der Instanz freigegeben werden.
**a) VCN Security List / NSG** in der OCI-Konsole Ingress-Regeln für
`0.0.0.0/0` auf TCP 80 und TCP 443 (und UDP 443, wenn HTTP/3 genutzt werden soll).
**b) Firewall in der Instanz.** Oracle-Linux-Images bringen firewalld mit:
```bash
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --permanent --add-port=443/udp
sudo firewall-cmd --reload
```
Ubuntu-Images von Oracle haben stattdessen eine restriktive iptables-Regel:
```bash
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT
sudo netfilter-persistent save
```
### 2. DNS
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
[`Caddyfile`](Caddyfile) auskommentieren, weil Caddy sonst dauerhaft erfolglos
ein Zertifikat dafür anfordert.
### 3. Docker installieren
```bash
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
```
Danach einmal neu einloggen.
### 4. Starten
```bash
git clone https://github.com/nizzgruber/djnizz_website.git
cd djnizz_website
docker compose up -d --build
```
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
```bash
git pull
docker compose up -d --build
```
### Konfiguration
Domain und ACME-Mailadresse lassen sich per `.env` neben der
`docker-compose.yml` überschreiben:
```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
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
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.
Wenn später ein Booking-Formular, Analytics oder Spotify-/YouTube-Embeds
dazukommen, muss `src/pages/datenschutz.astro` entsprechend erweitert werden.
## Struktur
```
src/
assets/ Bilder (werden beim Build zu WebP/AVIF optimiert)
components/ Header, Hero, About, Footer, SocialIcon
data/site.ts Zentrale Inhalts- und Konfigurationsdatei
layouts/ Base (SEO, JSON-LD), Legal
pages/ index, impressum, datenschutz, 404
styles/ global.css (Tailwind-Theme, Animationen)
scripts/ Einmalige Bildaufbereitung
```
Die Seiten sind alle vorgerendert. Der Node-Adapter ist trotzdem drin, damit
später einzelne Routen (z. B. `/api/booking`) mit `export const prerender = false`
dynamisch werden können, ohne dass sich am Deployment etwas ändert.