# 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. Deploy-Key einrichten Das Repo ist privat, ein HTTPS-Clone auf der VM würde also nach Zugangsdaten fragen. Stattdessen bekommt die VM einen eigenen Deploy-Key mit **Nur-Lese-Rechten**: ```bash ssh-keygen -t ed25519 -C "djnizz-vm-deploy" -f ~/.ssh/djnizz_deploy -N "" cat ~/.ssh/djnizz_deploy.pub ``` Den ausgegebenen Public Key in GitHub unter **Repo → Settings → Deploy keys → Add deploy key** eintragen und *Allow write access* **nicht** anhaken. Anschließend einen eigenen Host-Alias anlegen – bewusst nicht `Host github.com`, sonst würde dieser Key auch bei allen anderen GitHub-Repos angeboten und dort scheitern: ```bash cat >> ~/.ssh/config <<'EOF' Host github-djnizz HostName github.com User git IdentityFile ~/.ssh/djnizz_deploy IdentitiesOnly yes EOF chmod 600 ~/.ssh/config ssh -T git@github-djnizz ``` Die letzte Zeile muss mit `Hi nizzgruber/djnizz_website! You've successfully authenticated` antworten. Dass GitHub danach „does not provide shell access" meldet, ist normal und kein Fehler. ### 5. Starten ```bash git clone git@github-djnizz:nizzgruber/djnizz_website.git 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 ``` Passender vhost, wenn der vorhandene Proxy **Caddy auf dem Host** ist: ```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 docker network connect djnizz_website_djnizz ``` > 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 ```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.