- TypeScript 96.8%
- Dockerfile 1.5%
- JavaScript 0.9%
- CSS 0.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
In-memory Rate-Limiter (ausreichend für eine einzelne App-Instanz): Login max. 5 Versuche pro Konto und 20 pro Besucher innerhalb von 15 Minuten, Registrierung max. 5 Versuche pro Besucher und Stunde. Schützt vor automatisiertem Durchprobieren von Passwörtern bzw. des Einladungscodes. Besucher werden über X-Forwarded-For identifiziert, den ein Reverse Proxy (Caddy/nginx) setzen muss. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
| prisma | ||
| public | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| eslint.config.mjs | ||
| next.config.ts | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| prisma7.config.ts | ||
| README.md | ||
| tsconfig.json | ||
Isis Rezepte
Eine private Rezeptsammlung: Rezepte per Foto (z.B. Instagram-Screenshot) einlesen lassen, in einer einheitlichen Form speichern, mit Tags versehen, bewerten und ausdrucken.
Was die App kann
- Login für mehrere Personen (Familie), gemeinsame Rezeptsammlung
- Rezept per Foto hochladen → KI liest Zutaten & Zubereitung automatisch aus
- Rezepte manuell anlegen/bearbeiten, mit Tags versehen
- Durchsuchbar nach Titel, Zutat und Tag
- 5-Sterne-Bewertung pro Person
- Saubere Druckansicht pro Rezept
Lokal entwickeln
Voraussetzung: Node.js 22+, Docker.
docker compose up -d db # lokale Postgres-Datenbank starten
npx prisma migrate dev # Datenbankschema anlegen
npm run dev # App unter http://localhost:3000
.env ist bereits für die lokale Postgres-Instanz aus docker-compose.yml vorkonfiguriert.
Foto-Erkennung: drei austauschbare Varianten
Gesteuert über RECIPE_AI_PROVIDER in .env:
| Wert | Wie es funktioniert | Braucht GPU? | Kosten |
|---|---|---|---|
ollama (lokaler Dev-Standard) |
Ein lokales Bild-Modell über Ollama liest das Foto direkt aus. Am genauesten der beiden kostenlosen Optionen. | Ja (oder zumindest viel RAM) | kostenlos |
tesseract (empfohlen für Server ohne GPU) |
Reine CPU-Texterkennung (Tesseract, kein KI-Modell) liest den Text aus dem Bild, danach bringt ein kleiner Text-KI-Schritt (RECIPE_STRUCTURE_PROVIDER) das Ergebnis in Form. Läuft auf jedem normalen Server. |
Nein | kostenlos (bei RECIPE_STRUCTURE_PROVIDER=ollama) oder Cent-Bereich (bei =anthropic) |
anthropic |
Die Claude API liest das Foto direkt aus. Am zuverlässigsten, aber kostenpflichtig. | Nein | Cent-Bereich pro Rezept |
Für lokale Entwicklung auf diesem Rechner ist ollama voreingestellt, da hier bereits eine passende GPU/Ollama-Installation vorhanden ist – das funktioniert aber nur, solange die App auch auf diesem Rechner läuft.
Sobald die App auf einem fremden Server ohne GPU läuft (z.B. bei deinem Freund), auf tesseract umstellen:
RECIPE_AI_PROVIDER="tesseract"
RECIPE_STRUCTURE_PROVIDER="ollama"
OLLAMA_BASE_URL="https://ai.fidefi.de" # oder eine andere erreichbare eigene Ollama-Instanz
OLLAMA_TEXT_MODEL="gemma4:e4b"
Der Text-Strukturierungsschritt (RECIPE_STRUCTURE_PROVIDER) kann dabei entweder auf eine eigene, öffentlich erreichbare Ollama-Instanz zeigen (kostenlos, aber nur verfügbar solange dieser Rechner läuft und erreichbar ist) oder auf die Claude API:
RECIPE_STRUCTURE_PROVIDER="anthropic"
ANTHROPIC_API_KEY="..."
ANTHROPIC_TEXT_MODEL="claude-haiku-4-5-20251001"
(Kostenloses Anthropic-Konto unter https://console.anthropic.com/. Da hier nur Text statt Bild verarbeitet wird, sind die Kosten pro Rezept noch geringer als bei RECIPE_AI_PROVIDER="anthropic".)
Deployment (für Hosting durch Dritte)
Die App ist komplett in Docker verpackt und braucht nur:
cp .env.example .env
# .env ausfüllen: NEXTAUTH_SECRET, POSTGRES_PASSWORD, ANTHROPIC_API_KEY, NEXTAUTH_URL
docker compose up -d --build
Das startet zwei Container:
db: PostgreSQL, Daten liegen dauerhaft im Docker-Volumedb_dataapp: Die Next.js-App, wendet beim Start automatisch alle Datenbank-Migrationen an
Hochgeladene Rezeptfotos landen im Docker-Volume uploads.
Wichtig für den Betrieb hinter einer echten Domain:
NEXTAUTH_URLmuss auf die öffentliche URL zeigen (z.B.https://rezepte.example.com)- Am besten einen Reverse Proxy (z.B. Caddy oder nginx) mit TLS vor den
app-Container schalten, Port 3000 muss dann nicht mehr nach außen offen sein. Caddy und nginx setzen denX-Forwarded-For-Header standardmäßig – darauf verlässt sich das eingebaute Rate-Limiting (siehe unten), um Anmelde-/Registrierungsversuche pro Besucher statt pauschal zu begrenzen REGISTRATION_CODEsetzen (siehe unten), sonst kann sich jede/r im Internet ein Konto anlegen
Umgebungsvariablen
| Variable | Zweck |
|---|---|
DATABASE_URL |
Verbindung zur Postgres-Datenbank |
NEXTAUTH_URL |
Öffentliche URL der App |
NEXTAUTH_SECRET |
Geheimer Schlüssel für Sessions, erzeugen mit openssl rand -base64 32 |
REGISTRATION_CODE |
Code, den man bei /register zusätzlich eingeben muss. Frei wählbar, nur an die Familie weitergeben. Leer = offene Registrierung für alle im Internet |
RECIPE_AI_PROVIDER |
tesseract (CPU-OCR, für Server ohne GPU empfohlen), ollama (lokales Bild-Modell) oder anthropic (Cloud, kostenpflichtig) |
TESSERACT_LANG |
Nur bei RECIPE_AI_PROVIDER=tesseract: Sprachen für die Texterkennung, z.B. deu+eng |
RECIPE_STRUCTURE_PROVIDER |
Nur bei RECIPE_AI_PROVIDER=tesseract: ollama oder anthropic für den Text-Strukturierungsschritt |
OLLAMA_BASE_URL / OLLAMA_VISION_MODEL / OLLAMA_TEXT_MODEL |
Für RECIPE_AI_PROVIDER=ollama bzw. RECIPE_STRUCTURE_PROVIDER=ollama relevant |
ANTHROPIC_API_KEY / ANTHROPIC_TEXT_MODEL |
Nötig bei RECIPE_AI_PROVIDER=anthropic oder RECIPE_STRUCTURE_PROVIDER=anthropic. Kostenloses Konto unter https://console.anthropic.com/ |
POSTGRES_PASSWORD |
Passwort der Datenbank (nur für docker-compose) |
Neue Nutzer anlegen
Es gibt keine Einladungs-Verwaltung mit Admin-Oberfläche: Jede/r, der/die den REGISTRATION_CODE kennt, kann sich unter /register selbst ein Konto anlegen. Den Code also nur privat weitergeben (z.B. per WhatsApp), nicht öffentlich posten.
Sicherheit beim Betrieb im Internet – Checkliste
REGISTRATION_CODEgesetzt (siehe oben) – sonst kann sich jede/r registrierenNEXTAUTH_SECRETeinzigartig und lang (mitopenssl rand -base64 32erzeugt, nicht das Beispiel aus dieser Anleitung wiederverwenden)POSTGRES_PASSWORDein echtes, langes Passwort (nichtrezepte)- Zugriff nur über HTTPS (Reverse Proxy mit TLS, siehe oben) – sonst werden Passwörter und Sessions unverschlüsselt übertragen
- Reverse Proxy setzt
X-Forwarded-Forweiter (bei Caddy/nginx Standard) – sonst wirkt das Rate-Limiting für alle Besucher wie eine einzige Person .envwird nicht öffentlich geteilt/committed (ist bereits in.gitignore)
Was die App bereits automatisch absichert: Passwörter werden gehasht gespeichert (nie im Klartext), alle Rezept-Seiten verlangen Login, Sessions laufen über signierte, httpOnly-Cookies. Anmeldung ist zusätzlich pro Konto auf 5 und pro Besucher auf 20 Versuche innerhalb von 15 Minuten begrenzt, Registrierung auf 5 Versuche pro Stunde und Besucher – beides schützt vor automatisiertem Durchprobieren von Passwörtern bzw. des Einladungscodes.