Deploy / validate-dispatch (push) Successful in 43s
Deploy / scheduled-rebuild-dev (push) Skipped
Deploy / scheduled-rebuild-master (push) Skipped
Deploy / rollback-dev (push) Skipped
Deploy / rollback-master (push) Skipped
Deploy / changes (push) Successful in 13s
Deploy / secret-scan (push) Successful in 9s
Deploy / app-quality (push) Successful in 11m21s
Deploy / security-deps (push) Successful in 14s
Deploy / context (push) Failing after 1s
Deploy / app-image (push) Skipped
Deploy / deploy-dev (push) Skipped
Deploy / deploy-master (push) Skipped
144 lines
7.3 KiB
Markdown
144 lines
7.3 KiB
Markdown
# Next.js Website Starter
|
||
|
||
Neutrale, wiederverwendbare technische Basis für eine neue Website. Das Repository enthält eine produktionsfähige Next.js-Anwendung mit Kalender-API, Bildpipeline, Tests, Containerisierung sowie CI/CD, aber bewusst keine fachlichen Inhalte oder produktiven Daten.
|
||
|
||
## Technologie-Stack
|
||
|
||
- Node.js 24 und npm
|
||
- Next.js 16 App Router mit React 19 und TypeScript
|
||
- Standalone-Serverausgabe für Docker
|
||
- ICS-Kalender mit `ical.js`, `rrule` und Temporal
|
||
- Zod für Runtime-Konfiguration
|
||
- Vitest sowie ein produktionsnaher E2E-Smoke-Test
|
||
- ESLint, Husky und lint-staged
|
||
- Sharp für responsive Bildvarianten und Metadatenbereinigung
|
||
- Docker Compose, Traefik und Trivy
|
||
- Gitea-Actions-kompatible Workflows unter `.gitea/workflows/`
|
||
|
||
Eine Datenbank und eine Authentifizierung sind nicht Bestandteil dieser Vorlage, weil das technische Ausgangsprojekt keine solchen Systeme verwendet.
|
||
|
||
## Struktur
|
||
|
||
- `src/app/`: Seiten, Metadaten-, API- und Health-Routen
|
||
- `src/components/`: wiederverwendbare Server- und Client-Komponenten
|
||
- `src/server/calendar/`: ICS-Abruf, Parser, Cache, Fehlerbehandlung und Readiness
|
||
- `src/trip-reports/`: registrierbare TSX-Beitragsmodule; im Starter leer
|
||
- `src/data/`: neutrale Datenregistries für Downloads, Galerien und Inhaltskarten
|
||
- `.media-source/`: Originalbilder für die Bildpipeline
|
||
- `public/`: generierte Bilder, lokale Schriften und öffentliche Dateien
|
||
- `scripts/`: Build-, Medien-, E2E-, Security- und Deploy-Hilfen
|
||
- `.gitea/workflows/`: CI, Deployment, Rollback und geplante Rebuilds
|
||
|
||
Die vorhandenen deutschsprachigen Routen bleiben aus Kompatibilitätsgründen erhalten: `/`, `/ueber-uns`, `/informationen`, `/kalender`, `/fahrten`, `/fahrten/[slug]`, `/bilder`, `/impressum` und `/datenschutz`.
|
||
|
||
## Lokale Installation
|
||
|
||
Voraussetzungen sind Node.js gemäß `.node-version`, npm und für Container-Workflows Docker.
|
||
|
||
```bash
|
||
npm ci
|
||
cp .env.example .env.local
|
||
npm run dev
|
||
```
|
||
|
||
Die Anwendung ist anschließend standardmäßig unter `http://localhost:3000` erreichbar. Für echte Kalenderdaten muss `CALENDAR_URL` auf eine erreichbare HTTPS-ICS-Datei zeigen.
|
||
|
||
## Environment-Variablen
|
||
|
||
Alle Werte in `.env.example` sind ungefährliche Beispiele.
|
||
|
||
| Variable | Zweck |
|
||
| --- | --- |
|
||
| `APP_NAME` | Öffentlicher Name der Website |
|
||
| `APP_URL` | Kanonische Basis-URL für SEO, Sitemap, Hostprüfung und CORS-Default |
|
||
| `COMPANY_NAME` | Betreiber-/Organisationsname |
|
||
| `CONTACT_EMAIL` | Öffentliche Kontaktadresse |
|
||
| `CONTACT_PHONE` | Öffentliche Telefonnummer |
|
||
| `CONTACT_ADDRESS` | Öffentliche Anschrift |
|
||
| `PRIMARY_DOMAIN` | Hostname für Traefik |
|
||
| `CALENDAR_URL` | HTTPS-URL des ICS-Kalenders; zur Laufzeit erforderlich |
|
||
| `CORS_ORIGIN` | Kommagetrennte erlaubte Origins; Standard ist `APP_URL` |
|
||
| `TRUSTED_PROXIES` | JSON-Liste oder CSV vertrauenswürdiger Proxy-Netze |
|
||
| `CALENDAR_CACHE_DURATION_MS` | Cache-Dauer für Kalenderdaten |
|
||
| `CALENDAR_FETCH_TIMEOUT_MS` | Timeout für den ICS-Abruf |
|
||
| `DEFAULT_CALENDAR_TIMEZONE` | IANA-Zeitzone für schwebende ICS-Zeitangaben |
|
||
| `MAX_RECURRENCE_WINDOW_MONTHS` | Maximales Vorschaufenster wiederkehrender Termine |
|
||
| `MAX_ICS_BYTES` | Maximale Größe der Kalenderdatei |
|
||
| `MAX_OCCURRENCES_PER_EVENT` | Obergrenze je wiederkehrendem Termin |
|
||
| `ROUTINE_EVENT_TITLES` | Titel regulärer Termine, die nicht hervorgehoben werden |
|
||
|
||
`CALENDAR_URL` ist ein Runtime-Secret und wird nicht als Docker-Build-Argument verwendet. Öffentliche Identitätswerte werden beim Container-Build gesetzt, da Next.js Metadaten statisch erzeugen kann, und zusätzlich zur Laufzeit an den Container übergeben.
|
||
|
||
## Befehle
|
||
|
||
```bash
|
||
npm run dev
|
||
npm run lint
|
||
npm run typecheck
|
||
npm run test
|
||
npm run build
|
||
npm run test:e2e
|
||
```
|
||
|
||
`npm run build` bereinigt öffentliche Dateien, erzeugt beziehungsweise entfernt Bildvarianten, entfernt Bildmetadaten, prüft PDF-Metadaten und führt `next build` aus. Der E2E-Test baut die Standalone-Ausgabe, startet eine lokale ICS-Fixture und prüft Seiten, API, ETag sowie Health-Routen.
|
||
|
||
Mit `npm run content:new` kann ein neues TSX-Beitragsmodul samt optionalen Originalbildern angelegt werden.
|
||
|
||
## Bilder und Dateien
|
||
|
||
Originalbilder gehören in die Unterverzeichnisse von `.media-source/`. `npm run images` erzeugt responsive JPEG-, WebP- und AVIF-Varianten in `public/images/`; `npm run images:prune` entfernt Varianten ohne Quelle. Neue Alt-Texte werden projektspezifisch in der Medienkonfiguration oder im erzeugten Manifest gepflegt.
|
||
|
||
Downloads werden in `public/downloads/` abgelegt und in `src/data/downloads.ts` registriert. Keine personenbezogenen, produktiven oder vertraulichen Dateien committen.
|
||
|
||
## Docker
|
||
|
||
Für einen lokalen Start über den vorhandenen Traefik-Stack:
|
||
|
||
```bash
|
||
CALENDAR_URL=https://example.com/calendar.ics docker compose up --build
|
||
```
|
||
|
||
Das externe Netzwerk heißt standardmäßig `traefik-external` und kann mit `TRAEFIK_NETWORK_NAME` geändert werden. Für einen isolierten Test ohne vorhandenes Traefik-Netz kann die Compose-Datei projektspezifisch überschrieben werden.
|
||
|
||
Das Runtime-Image läuft ohne Root-Rechte, mit read-only Dateisystem, entfernten Linux-Capabilities, Healthcheck und Ressourcenlimits.
|
||
|
||
## CI/CD und Deployment
|
||
|
||
Die Workflows bleiben vollständig erhalten:
|
||
|
||
- `.gitea/workflows/ci.yml` führt Lint, Tests, Typecheck, Build, E2E sowie Secret- und Schwachstellenscans aus.
|
||
- `.gitea/workflows/deploy.yml` baut und scannt Images, deployt `dev` und `master`, prüft die laufende Anwendung, unterstützt Rollbacks und führt wöchentliche Rebuilds aus aktuellen Basis-Images aus.
|
||
|
||
CI ist für den lokalen Start nicht technisch erforderlich. Für gemeinsame Branches und Deployments sollte sie aktiv bleiben, weil sie reproduzierbar Build, Tests, Secret-Scans und Container prüft. Auf einem warmen Runner ist für die reine App-Prüfung typischerweise mit etwa 2–5 Minuten zu rechnen; ein kalter Runner mit LFS-, Container- und Trivy-Downloads kann etwa 5–15 Minuten benötigen. Die Security-Jobs laufen parallel. Die tatsächliche Dauer hängt von Runner, Cache, Medienumfang und Netzwerk ab; die Job-Timeouts liegen je nach Aufgabe bei 5–45 Minuten.
|
||
|
||
Vor dem ersten Deployment sind mindestens folgende Repository-Variablen zu setzen:
|
||
|
||
- `CI_RUNNER`, optional `PROD_RUNNER`
|
||
- `CONTAINER_REGISTRY`
|
||
- `APP_IMAGE_REPOSITORY`
|
||
- `APP_NAME`, `COMPANY_NAME`, `CONTACT_EMAIL`, `CONTACT_PHONE`, `CONTACT_ADDRESS`
|
||
- `DEV_PRIMARY_DOMAIN`, `PROD_PRIMARY_DOMAIN`
|
||
- optional `DEV_APP_URL`, `PROD_APP_URL`, `DEV_CORS_ORIGIN`, `PROD_CORS_ORIGIN`
|
||
- optional Stack- und Netzwerkwerte `*_DEPLOY_STACK_NAME`, `*_TRAEFIK_NETWORK_NAME`
|
||
|
||
Benötigte Secrets:
|
||
|
||
- `CALENDAR_URL`
|
||
- `PACKAGES_USERNAME`, `PACKAGES_TOKEN`
|
||
- `DEV_TRAEFIK_CERTRESOLVER`, `PROD_TRAEFIK_CERTRESOLVER`
|
||
|
||
Runner benötigen Docker, Zugriff auf das Zielnetzwerk und bei produktiven Deployments Zugriff auf den Zielhost.
|
||
|
||
## Für ein neues Projekt anpassen
|
||
|
||
1. Alle Werte aus `.env.example` für die neue Installation festlegen.
|
||
2. Texte und Navigation in `src/app/` und `src/components/Header.tsx` ersetzen.
|
||
3. Rechtstexte fachlich und rechtlich erstellen lassen.
|
||
4. Neues Logo, Farbschema, Schriften und Medien einpflegen.
|
||
5. Kalenderquelle und Titel regulärer Termine konfigurieren.
|
||
6. Beitrags-, Download- und Galerie-Registries befüllen.
|
||
7. Registry, Runner, Domains, Traefik und Secrets in CI/CD konfigurieren.
|
||
8. Alle Qualitätsprüfungen und den finalen Secret-Scan ausführen.
|
||
|
||
Die Beispielwerte sind nicht für eine produktive Veröffentlichung bestimmt.
|