Drei Fehler an der Live-Seite: 1. Die Figur begann bei top-0 und ragte damit in die Navigationsleiste - Kopf und Schulter lagen hinter "Start" und "Ueber mich". Sie startet jetzt bei top-16 bzw. top-20, also genau unter dem Header. 2. Auf schmalen Screens war der Kopf komplett abgeschnitten. Das Bild skalierte ueber die Breite (h-auto w-full); bei 72 % Breite wird das hochformatige Motiv hoeher als sein Container, und items-end schneidet dann oben ab. Es skaliert jetzt durchgehend ueber die Hoehe (h-full w-auto object-bottom), damit passt es immer hinein. 3. Das Genre-Laufband sprang sichtbar zurueck. Zwei Kopien wurden um -50 % verschoben, aber eine Kopie ist auf breiten Bildschirmen schmaler als der Viewport - dadurch klaffte vor dem Neustart eine Luecke. Jetzt zwei Spuren mit min-w-full, beide um ihre volle eigene Breite (-100 %); Spur 2 steht beim Neustart exakt auf der Startposition von Spur 1. Das umgebende Element bekam ausserdem das fehlende overflow-hidden. Nachgemessen bei 1265x720 und 375x812: Kopf unterhalb der Headerkante, beide Spuren gleich breit und mindestens viewportbreit, kein horizontaler Scroll. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
djnizz.at
Website von DJ NIZZ. Astro 7 (statisch vorgerendert) hinter einem Node-Server, Tailwind 4, als Docker-Container.
TLS und Domain kommen vom zentralen Reverse-Proxy im Projekt
docker-edge – dieser Stack
veröffentlicht selbst keinen Port.
Inhalte ändern
Fast alles steht in src/data/site.ts – Texte, Genres,
Kontaktdaten, Navigation, Social-Links. Für normale Textänderungen musst du
keine Komponente anfassen.
- Social-Profile: In
SOCIALSdieurleintragen. Einträge ohne URL werden automatisch ausgeblendet, du kannst also alles stehen lassen, was du noch nicht hast. - Neues Genre: In
GENRESergä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 inaccentVarinsrc/components/About.astroexistieren. - Impressum / Datenschutz:
src/pages/impressum.astroundsrc/pages/datenschutz.astro.
Lokal entwickeln
npm install
npm run dev
Läuft auf http://localhost:4321.
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:
npm run assets
Der freigestellte Render src/assets/nizz-cutout.png entsteht separat aus dem
Ganzkörper-Bild:
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:
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:
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 in
sites/djnizz.at.caddy des Edge-Projekts auskommentieren, weil Caddy sonst
dauerhaft erfolglos ein Zertifikat dafür anfordert.
3. Docker installieren
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:
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:
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
TLS, Domains und Security-Header liegen nicht in diesem Repo, sondern
zentral im Projekt 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:
docker network create edge
Dann diesen Stack starten – er veröffentlicht keinen einzigen Port, erreichbar
ist er nur über das Netz edge:
git clone git@github-djnizz:nizzgruber/djnizz_website.git
cd djnizz_website
docker compose up -d --build
Die zugehörige vhost-Datei liegt im Edge-Projekt unter
sites/djnizz.at.caddy und zeigt auf djnizz-web:4321. Nach Änderungen dort:
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
Updates ausrollen
git pull
docker compose up -d --build
Konfiguration
Dieser Stack hat keine eigene Konfiguration – Domain, Zertifikate und Header liegen im Edge-Projekt.
Datenschutz
Die Seite lädt nichts von externen Servern: Schriften sind selbst gehostet, es gibt keine Cookies, kein Tracking und keine eingebetteten Player.
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
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.