chore: update .gitignore to include .env.example and enhance deployment documentation with Caddy reverse proxy setup

This commit is contained in:
Hördle Bot
2025-12-01 15:19:19 +01:00
parent 68c074e9da
commit b120e5df45
7 changed files with 596 additions and 0 deletions

106
.env.example Normal file
View File

@@ -0,0 +1,106 @@
# ============================================
# Hördle Environment Variables
# ============================================
# Kopiere diese Datei zu .env und passe die Werte an deine Umgebung an:
# cp .env.example .env
#
# WICHTIG: Die .env-Datei sollte niemals in Git committed werden!
# ============================================
# Build-Time Variables (NEXT_PUBLIC_*)
# ============================================
# Diese Variablen werden beim Build-Zeitpunkt in die Next.js-App eingebettet.
# Nach dem Build können sie nicht mehr geändert werden (ohne Rebuild).
# App-Name (wird in Browser-Tab, PWA, etc. verwendet)
NEXT_PUBLIC_APP_NAME=Hördle
# App-Beschreibung (für SEO, PWA, etc.)
NEXT_PUBLIC_APP_DESCRIPTION=Daily music guessing game - Guess the song from short audio clips
# Hauptdomain (ohne https://)
NEXT_PUBLIC_DOMAIN=hoerdle.de
# Twitter/X Handle (für Meta-Tags)
NEXT_PUBLIC_TWITTER_HANDLE=@hoerdle
# Plausible Analytics - Domain
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=hoerdle.de
# Plausible Analytics - Script-URL (selbst gehostet oder extern)
NEXT_PUBLIC_PLAUSIBLE_SCRIPT_SRC=https://plausible.example.com/js/script.js
# Theme-Farbe (für Browser-UI, PWA, etc.)
NEXT_PUBLIC_THEME_COLOR=#000000
# Hintergrundfarbe (für PWA, etc.)
NEXT_PUBLIC_BACKGROUND_COLOR=#ffffff
# Credits im Footer aktivieren (true/false)
NEXT_PUBLIC_CREDITS_ENABLED=true
# Credits-Text (vor dem Link)
NEXT_PUBLIC_CREDITS_TEXT=Vibe coded with ☕ and 🍺 by
# Credits-Link-Text
NEXT_PUBLIC_CREDITS_LINK_TEXT=@yourhandle@server.social
# Credits-Link-URL
NEXT_PUBLIC_CREDITS_LINK_URL=https://server.social/@yourhandle
# ============================================
# Runtime Variables
# ============================================
# Diese Variablen können zur Laufzeit geändert werden (benötigen keinen Rebuild).
# Datenbank-URL (SQLite für lokale/kleine Deployments)
# Format: file:/path/to/database.db
DATABASE_URL=file:/app/data/prod.db
# Admin-Passwort (bcrypt Hash)
# Generiere einen Hash mit: node scripts/hash-password.js dein_passwort
# In docker-compose.yml müssen $ als $$ escaped werden!
ADMIN_PASSWORD=$2b$10$SHOt9G1qUNIvHoWre7499.eEtp5PtOII0daOQGNV.dhDEuPmOUdsq
# Zeitzone (für tägliche Puzzle-Rotation)
TZ=Europe/Berlin
# ============================================
# Optional: Gotify Integration
# ============================================
# Für Benachrichtigungen (z.B. Fehler-Alerts)
# Gotify Server URL
GOTIFY_URL=https://gotify.example.com
# Gotify App Token
GOTIFY_APP_TOKEN=your_gotify_app_token_here
# ============================================
# Optional: OpenRouter Integration
# ============================================
# Für AI-Features (falls vorhanden)
# OpenRouter API Key
OPENROUTER_API_KEY=your_openrouter_api_key_here
# ============================================
# Caddy Reverse Proxy (Optional - Production)
# ============================================
# Nur benötigt, wenn Caddy für SSL/TLS verwendet wird.
# GoDaddy API Key (für DNS-01 Challenge bei Wildcard-Zertifikaten)
# Siehe CADDY_SETUP.md für Anleitung zur Erstellung
GODADDY_API_KEY=your_godaddy_api_key_here
# GoDaddy API Secret
GODADDY_API_SECRET=your_godaddy_api_secret_here
# Email für Let's Encrypt Benachrichtigungen (optional)
CADDY_EMAIL=admin@hoerdle.de
# ============================================
# Build-Time Overrides
# ============================================
# Optional: Spezifische Version beim Build setzen
# APP_VERSION=v1.0.0

1
.gitignore vendored
View File

@@ -32,6 +32,7 @@ yarn-error.log*
# env files (can opt-in for committing if needed)
.env*
!.env.example
# vercel
.vercel

259
CADDY_SETUP.md Normal file
View File

@@ -0,0 +1,259 @@
# Caddy-Setup für Hördle
Diese Anleitung erklärt, wie du Caddy als Reverse-Proxy mit automatischen Let's Encrypt Wildcard-Zertifikaten für die Domains `hoerdle.de` und `hördle.de` (xn--hrdle-jua.de) einrichtest.
## Übersicht
Caddy übernimmt folgende Aufgaben:
- Automatische SSL/TLS-Zertifikate via Let's Encrypt
- Wildcard-Zertifikate für beide Domains (inkl. Subdomains)
- Reverse Proxy zu deinem Hördle-Container
- HTTP zu HTTPS Redirect
- Optimierte Einstellungen für Audio-Streaming und Uploads
## Voraussetzungen
1. Docker und Docker Compose installiert
2. Zugriff auf deine GoDaddy Domain-Verwaltung
3. Ports 80 und 443 müssen frei sein (Caddy übernimmt diese)
## Schritt 1: GoDaddy DNS-API-Zugangsdaten erstellen
Für Wildcard-Zertifikate benötigt Caddy DNS-01 Challenge, was API-Zugriff auf dein GoDaddy-Konto erfordert.
### GoDaddy API-Keys erstellen
1. Gehe zu [GoDaddy Developer Portal](https://developer.godaddy.com/)
2. Melde dich mit deinem GoDaddy-Konto an
3. Klicke auf **"Keys"** in der Navigation
4. Klicke auf **"Create New API Key"**
5. Fülle das Formular aus:
- **Key Name**: z.B. "Hördle Caddy DNS"
- **Environment**: Production (für echte Domains)
6. Klicke auf **"Create"**
7. **Wichtig**: Kopiere dir den **API Key** und das **API Secret** - das Secret wird nur einmal angezeigt!
### Alternative: Manuelle DNS-TXT-Records (ohne API)
Wenn du keine API-Keys verwenden möchtest, kannst du die DNS-TXT-Records manuell setzen. **Hinweis**: Dies ist nur für die initiale Zertifikatsanfrage möglich, nicht für automatische Erneuerungen.
Siehe Abschnitt "Manuelle DNS-Konfiguration (ohne API)" weiter unten.
## Schritt 2: Environment-Variablen konfigurieren
Erstelle eine `.env`-Datei im Projektverzeichnis (oder erweitere die bestehende):
```bash
# GoDaddy API-Credentials für DNS-01 Challenge
GODADDY_API_KEY=your_api_key_here
GODADDY_API_SECRET=your_api_secret_here
# Optional: Email für Let's Encrypt Benachrichtigungen
CADDY_EMAIL=markus@hoerdle.de
```
**Wichtig**: Die `.env`-Datei sollte nicht in Git committed werden (sollte bereits in `.gitignore` sein).
## Schritt 3: Docker-Netzwerk erstellen
Caddy und Hördle müssen im gleichen Docker-Netzwerk kommunizieren:
```bash
# Prüfe, ob das Netzwerk bereits existiert
docker network ls | grep hoerdle
# Falls nicht vorhanden, erstelle es
docker network create hoerdle_default
```
## Schritt 4: Caddy starten
### Option A: Mit docker-compose (Empfohlen)
```bash
# Starte Hördle + Caddy zusammen
docker compose -f docker-compose.yml -f docker-compose.caddy.yml --profile production up -d
# Nur Caddy starten (wenn Hördle bereits läuft)
docker compose -f docker-compose.caddy.yml --profile production up -d
```
### Option B: Nur Caddy starten (Hördle läuft bereits)
```bash
docker compose -f docker-compose.caddy.yml --profile production up -d
```
## Schritt 5: DNS-Konfiguration in GoDaddy
### Automatisch (mit API-Keys)
Wenn du API-Keys konfiguriert hast, wird Caddy automatisch die benötigten DNS-TXT-Records erstellen. Keine manuellen DNS-Änderungen nötig!
### Manuell (ohne API-Keys)
Wenn du die API-Keys nicht verwenden möchtest, musst du die DNS-TXT-Records manuell setzen:
#### Für hoerdle.de:
1. Gehe zu deinem [GoDaddy DNS-Verwaltung](https://dcc.godaddy.com/manage/YOUR_DOMAIN/dns)
2. Für jedes Wildcard-Zertifikat benötigst du einen TXT-Record:
- **Typ**: TXT
- **Name**: `_acme-challenge`
- **Wert**: (wird von Let's Encrypt generiert - siehe Caddy-Logs)
- **TTL**: 600 (10 Minuten)
**Wichtig**: Für Wildcard-Zertifikate brauchst du:
- Einen TXT-Record für `_acme-challenge.hoerdle.de` (Domain selbst)
- Einen TXT-Record für `_acme-challenge.*.hoerdle.de` (Wildcard)
#### Für hördle.de (xn--hrdle-jua.de):
Das gleiche Vorgehen für die Punycode-Domain:
- `_acme-challenge.xn--hrdle-jua.de`
- `_acme-challenge.*.xn--hrdle-jua.de`
**Hinweis**: Die manuelle Methode funktioniert nur für die initiale Zertifikatsanfrage. Für automatische Erneuerungen benötigst du die API-Keys.
## Schritt 6: Prüfen, ob alles funktioniert
### Caddy-Logs ansehen
```bash
docker logs -f hoerdle-caddy
```
Du solltest sehen:
- Caddy startet erfolgreich
- Let's Encrypt-Zertifikate werden angefordert
- Zertifikate sind gültig
### Zertifikate prüfen
```bash
# Prüfe Zertifikate im Browser
# Öffne: https://hoerdle.de
# Öffne: https://hördle.de
```
Oder via Command-Line:
```bash
# Prüfe Zertifikat für hoerdle.de
openssl s_client -connect hoerdle.de:443 -servername hoerdle.de < /dev/null 2>/dev/null | openssl x509 -noout -text | grep "Subject:"
# Prüfe Zertifikat für hördle.de
openssl s_client -connect xn--hrdle-jua.de:443 -servername xn--hrdle-jua.de < /dev/null 2>/dev/null | openssl x509 -noout -text | grep "Subject:"
```
## Troubleshooting
### Caddy startet nicht
**Problem**: Container stoppt sofort nach Start.
**Lösung**:
1. Prüfe Caddy-Logs: `docker logs hoerdle-caddy`
2. Prüfe Caddyfile-Syntax: `docker run --rm -v $(pwd)/Caddyfile:/etc/caddy/Caddyfile:ro caddy:2-alpine caddy validate --config /etc/caddy/Caddyfile`
3. Prüfe, ob Ports 80/443 frei sind: `sudo netstat -tlnp | grep -E ':80|:443'`
### Zertifikate werden nicht erstellt
**Problem**: Let's Encrypt-Zertifikate werden nicht angefordert.
**Lösung**:
1. Prüfe GoDaddy API-Credentials in `.env`
2. Prüfe Caddy-Logs für DNS-Challenge-Fehler
3. Stelle sicher, dass die Domains korrekt auf deinen Server zeigen (A-Records)
4. Bei manueller DNS-Konfiguration: Prüfe, ob TXT-Records korrekt gesetzt sind
### DNS-Challenge schlägt fehl
**Problem**: DNS-01 Challenge kann DNS-Records nicht erstellen.
**Lösung**:
1. Prüfe GoDaddy API-Permissions
2. Stelle sicher, dass API-Keys Production-Keys sind (nicht Development)
3. Prüfe Domain-Ownership in GoDaddy
4. Warte einige Minuten - DNS-Propagierung kann dauern
### Audio-Dateien funktionieren nicht
**Problem**: MP3-Dateien werden nicht korrekt gestreamt.
**Lösung**:
1. Prüfe Caddy-Logs: `docker logs hoerdle-caddy | grep -i range`
2. Prüfe, ob Range-Header weitergegeben werden (Browser DevTools → Network)
3. Stelle sicher, dass der `/uploads/` Handle korrekt konfiguriert ist
### Container können nicht kommunizieren
**Problem**: Caddy kann den hoerdle-Container nicht erreichen.
**Lösung**:
1. Prüfe, ob beide Container im gleichen Netzwerk sind:
```bash
docker network inspect hoerdle_default
```
2. Prüfe, ob hoerdle-Container läuft: `docker ps | grep hoerdle`
3. Teste Verbindung von Caddy zu Hördle:
```bash
docker exec hoerdle-caddy wget -O- http://hoerdle:3010/api/health
```
## Deployment-Workflow
### Caddy nur in Produktion aktivieren
Die `docker-compose.caddy.yml` verwendet das `production`-Profile. Um Caddy zu aktivieren:
```bash
# Mit Production-Profile
docker compose -f docker-compose.yml -f docker-compose.caddy.yml --profile production up -d
# Ohne Caddy (nur Hördle)
docker compose -f docker-compose.yml up -d
```
### Caddy aktualisieren
```bash
# Pull neues Caddy-Image
docker compose -f docker-compose.caddy.yml pull
# Restart Caddy-Container
docker compose -f docker-compose.caddy.yml --profile production restart caddy
```
### Caddy-Konfiguration ändern
Nach Änderungen am Caddyfile:
```bash
# Caddyfile validieren
docker run --rm -v $(pwd)/Caddyfile:/etc/caddy/Caddyfile:ro caddy:2-alpine caddy validate --config /etc/caddy/Caddyfile
# Caddy neu laden (ohne Downtime)
docker compose -f docker-compose.caddy.yml --profile production exec caddy caddy reload --config /etc/caddy/Caddyfile
```
## Sicherheit
### API-Keys schützen
- **Niemals** API-Keys in Git committen
- Verwende `.env`-Dateien (sollten in `.gitignore` sein)
- Setze minimale Berechtigungen für API-Keys in GoDaddy
- Rotiere API-Keys regelmäßig
### Firewall
Stelle sicher, dass nur Ports 80 und 443 öffentlich erreichbar sind. Port 3010 (Hördle) sollte nicht öffentlich erreichbar sein.
## Weitere Ressourcen
- [Caddy Dokumentation](https://caddyserver.com/docs/)
- [Caddy DNS-Provider](https://caddyserver.com/docs/modules/tls.dns)
- [GoDaddy API Dokumentation](https://developer.godaddy.com/doc/endpoint/domains)
- [Let's Encrypt Wildcard-Zertifikate](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge)

127
Caddyfile Normal file
View File

@@ -0,0 +1,127 @@
# Caddy-Konfiguration für Hördle
# Wildcard-Zertifikate für hoerdle.de und hördle.de (xn--hrdle-jua.de)
# DNS-01 Challenge für Wildcard-Zertifikate (GoDaddy)
# Die DNS-TXT-Records müssen manuell in GoDaddy gesetzt werden (siehe CADDY_SETUP.md)
# Domain 1: hoerdle.de (ASCII)
*.hoerdle.de, hoerdle.de {
# TLS mit DNS-01 Challenge für Wildcard
tls {
dns godaddy {env.GODADDY_API_KEY} {env.GODADDY_API_SECRET}
}
# Upload-Limit: 50MB (wie in nginx.conf.example)
request_body {
max_size 50MB
}
# Reverse Proxy zu hoerdle Container
reverse_proxy hoerdle:3010 {
# HTTP/1.1 für WebSocket Support
transport http {
versions 1.1
}
# Headers für Audio-Streaming (Range Requests)
header_up Range {http.request.header.Range}
header_up If-Range {http.request.header.If-Range}
# Kein Caching bei Range Requests
header_down Cache-Control "no-cache" {
when {http.request.header.Range}
}
# Timeouts für große Dateien (300s wie in nginx)
timeout 300s
# WebSocket Support
header_up Connection {>Connection}
header_up Upgrade {>Upgrade}
}
# Spezielle Behandlung für /uploads/ Route (Audio-Dateien)
handle /uploads/* {
reverse_proxy hoerdle:3010 {
# Range Requests für Audio-Streaming
header_up Range {http.request.header.Range}
header_up If-Range {http.request.header.If-Range}
# Buffering deaktivieren für große Dateien
# (Caddy hat kein explizites proxy_buffering, aber Timeouts setzen)
timeout 300s
# Kein Caching bei Range Requests
header_down Cache-Control "no-cache" {
when {http.request.header.Range}
}
}
}
# HTTP zu HTTPS Redirect
@http {
protocol http
}
redir @http https://{host}{uri} permanent
}
# Domain 2: hördle.de (Punycode: xn--hrdle-jua.de)
*.xn--hrdle-jua.de, xn--hrdle-jua.de {
# TLS mit DNS-01 Challenge für Wildcard
tls {
dns godaddy {env.GODADDY_API_KEY} {env.GODADDY_API_SECRET}
}
# Upload-Limit: 50MB
request_body {
max_size 50MB
}
# Reverse Proxy zu hoerdle Container
reverse_proxy hoerdle:3010 {
# HTTP/1.1 für WebSocket Support
transport http {
versions 1.1
}
# Headers für Audio-Streaming (Range Requests)
header_up Range {http.request.header.Range}
header_up If-Range {http.request.header.If-Range}
# Kein Caching bei Range Requests
header_down Cache-Control "no-cache" {
when {http.request.header.Range}
}
# Timeouts für große Dateien (300s)
timeout 300s
# WebSocket Support
header_up Connection {>Connection}
header_up Upgrade {>Upgrade}
}
# Spezielle Behandlung für /uploads/ Route (Audio-Dateien)
handle /uploads/* {
reverse_proxy hoerdle:3010 {
# Range Requests für Audio-Streaming
header_up Range {http.request.header.Range}
header_up If-Range {http.request.header.If-Range}
# Timeouts für große Dateien
timeout 300s
# Kein Caching bei Range Requests
header_down Cache-Control "no-cache" {
when {http.request.header.Range}
}
}
}
# HTTP zu HTTPS Redirect
@http {
protocol http
}
redir @http https://{host}{uri} permanent
}

View File

@@ -82,3 +82,35 @@ docker ps
```
Look for the "healthy" status in the STATUS column.
## Caddy Reverse Proxy (Optional - Production)
For production deployments with automatic SSL/TLS certificates, Caddy can be used as a reverse proxy. Caddy provides:
- Automatic Let's Encrypt certificates (including wildcard certificates)
- HTTP to HTTPS redirect
- Optimized settings for audio streaming and file uploads
- Support for both `hoerdle.de` and `hördle.de` (Punycode: `xn--hrdle-jua.de`)
### Quick Start
1. **Follow the setup guide**: See `CADDY_SETUP.md` for detailed instructions
2. **Configure environment variables**: Add GoDaddy API credentials to your `.env` file
3. **Start with Caddy**:
```bash
docker compose -f docker-compose.yml -f docker-compose.caddy.yml --profile production up -d
```
### Without Caddy
If you don't want to use Caddy, you can deploy normally:
```bash
docker compose -f docker-compose.yml up -d
```
The application will still be accessible on port 3010, but you'll need to configure SSL/TLS separately (e.g., with nginx).
### Caddy Troubleshooting
See `CADDY_SETUP.md` for detailed troubleshooting information.

10
Dockerfile.caddy Normal file
View File

@@ -0,0 +1,10 @@
# Dockerfile für Caddy mit GoDaddy DNS-Provider Plugin
FROM caddy:2-builder AS builder
RUN xcaddy build \
--with github.com/caddy-dns/godaddy
FROM caddy:2
COPY --from=builder /usr/bin/caddy /usr/bin/caddy

61
docker-compose.caddy.yml Normal file
View File

@@ -0,0 +1,61 @@
# Docker Compose Konfiguration für Caddy Reverse Proxy
# Optional: Nur in Produktionsumgebung verwenden
#
# Starten: docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d
# Stoppen: docker compose -f docker-compose.yml -f docker-compose.caddy.yml down
version: '3.8'
services:
caddy:
# Verwende Custom-Image mit GoDaddy DNS-Plugin
build:
context: .
dockerfile: Dockerfile.caddy
# Alternativ: Verwende Standard-Caddy und manuelle DNS-Konfiguration
# image: caddy:2-alpine
container_name: hoerdle-caddy
restart: unless-stopped
ports:
# Standard HTTP/HTTPS Ports
- "80:80"
- "443:443"
- "443:443/udp" # Für HTTP/3 (QUIC)
environment:
# GoDaddy API-Credentials für DNS-01 Challenge
# Diese müssen in einer .env-Datei gesetzt werden:
# GODADDY_API_KEY=your_api_key
# GODADDY_API_SECRET=your_api_secret
- GODADDY_API_KEY=${GODADDY_API_KEY:-}
- GODADDY_API_SECRET=${GODADDY_API_SECRET:-}
# Optional: Email für Let's Encrypt Benachrichtigungen
- CADDY_EMAIL=${CADDY_EMAIL:-}
volumes:
# Caddyfile-Konfiguration
- ./Caddyfile:/etc/caddy/Caddyfile:ro
# Persistente Zertifikat-Speicherung
- caddy_data:/data
- caddy_config:/config
networks:
- default
# Health Check
healthcheck:
test: ["CMD", "caddy", "version"]
interval: 30s
timeout: 10s
retries: 3
# Nur starten, wenn ENABLE_CADDY=true gesetzt ist
profiles:
- production
volumes:
caddy_data:
driver: local
caddy_config:
driver: local
networks:
default:
# Netzwerk wird automatisch erstellt wenn beide Compose-Dateien zusammen verwendet werden
# Bei separater Verwendung: docker network create hoerdle_default und external: true setzen