No description
  • Vue 51.3%
  • Python 40.9%
  • TypeScript 6.3%
  • CSS 0.9%
  • Dockerfile 0.3%
  • Other 0.3%
Find a file
L4stIdi0t 34493917cb
All checks were successful
Dev Build / build (push) Successful in 15m56s
Release Build / meta (push) Successful in 15s
Release Build / build-amd64 (push) Successful in 2m25s
Release Build / build-arm64 (push) Successful in 16m9s
Release Build / publish (push) Successful in 49s
feat(branding): replace chef-hat icon with Plateful logo and add favicon set
- Generate favicon.ico (16/32/48px), apple-touch-icon (180px), and PWA
  icons (192px, 512px) from plateful.png
- Replace i-lucide-chef-hat brand mark with <img src="/logo.png"> in
  auth/login, auth/signup, setup wizard (mobile + desktop), and AppTabletNav
- Wire favicon and apple-touch-icon into nuxt.config.ts head links
- Add CHANGELOG.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 13:25:30 +02:00
.claude chore(dx): add agentic setup — skills, standards, design language 2026-05-25 13:42:14 +02:00
.forgejo/workflows ci: rename dev-build.yml → snapshot.yml so it sorts after release.yml 2026-06-07 16:49:08 +02:00
backend feat(setup): instance config, validated step 2, animation fix 2026-06-07 14:57:44 +02:00
docker fix: use explicit venv python path and fix || true shell precedence bug 2026-06-07 16:47:41 +02:00
frontend feat(branding): replace chef-hat icon with Plateful logo and add favicon set 2026-06-08 13:25:30 +02:00
standards chore(dx): add agentic setup — skills, standards, design language 2026-05-25 13:42:14 +02:00
.dockerignore feat(setup): rich OpenAI key explainer + fix .env leaking into image 2026-06-07 15:12:55 +02:00
.gitignore chore: untrack seed .bak files and add to gitignore 2026-06-06 12:07:17 +02:00
AGENTS.md docs: always kill dev servers after testing 2026-06-06 18:34:21 +02:00
CHANGELOG.md feat(branding): replace chef-hat icon with Plateful logo and add favicon set 2026-06-08 13:25:30 +02:00
claude.md chore(dx): add agentic setup — skills, standards, design language 2026-05-25 13:42:14 +02:00
docker-compose.yml ci: build multi-platform images (amd64 + arm64) 2026-06-07 16:13:30 +02:00
Dockerfile ci: retry uv sync up to 3 times to handle transient EAGAIN errors 2026-06-07 16:51:13 +02:00
FEATURES.md docs: update feature checklist 2026-06-07 11:07:31 +02:00
pyproject.toml feat(docker): production Docker setup with SSR, icon bundling, and secure cookies 2026-06-07 14:14:15 +02:00
README.md docs: add README with quick-start, docker-compose, env reference 2026-06-07 15:23:20 +02:00
uv.lock feat(docker): production Docker setup with SSR, icon bundling, and secure cookies 2026-06-07 14:14:15 +02:00

Plateful

A self-hosted recipe library and meal planner. Import recipes from any website or video, organise them with tags and categories, plan your meals for the week, and share collections with household members.


Features

  • Recipe import — paste a URL from any recipe website; no AI key required
  • Video import — YouTube, TikTok, Instagram, Facebook (requires OpenAI API key)
  • Photo import — photograph a recipe from a book or screen (requires OpenAI API key)
  • Meal planner — drag recipes onto a weekly calendar
  • Groups — share recipe collections within a household
  • Discover — personalised recipe feed based on your taste
  • Ingredient database — nutritional info and unit conversion
  • Auth — local accounts, magic links, Google, GitHub, Discord, Apple Sign In
  • Single-container — nginx + FastAPI + Nuxt SSR in one image; no external services required

Quick start

services:
  plateful:
    image: code.letsnot.run/l4stidi0t/plateful:latest
    ports:
      - "8000:8000"
    volumes:
      - plateful-data:/app/backend/data
    environment:
      ENVIRONMENT: production
      JWT_SECRET_KEY: "change-me"          # generate: python -c "import secrets; print(secrets.token_hex(32))"
      NUXT_PUBLIC_API_BASE: "/api"
      NUXT_API_BASE: "http://127.0.0.1:8001"

volumes:
  plateful-data:
docker compose up -d

Open http://localhost:8000 — you'll be guided through the first-time setup wizard.


Docker run

docker run -d \
  --name plateful \
  -p 8000:8000 \
  -v plateful-data:/app/backend/data \
  -e ENVIRONMENT=production \
  -e JWT_SECRET_KEY="$(python3 -c 'import secrets; print(secrets.token_hex(32))')" \
  -e NUXT_PUBLIC_API_BASE="/api" \
  -e NUXT_API_BASE="http://127.0.0.1:8001" \
  code.letsnot.run/l4stidi0t/plateful:latest

Behind a reverse proxy (nginx / Caddy / Traefik)

Plateful auto-detects HTTPS from the X-Forwarded-Proto header, so cookies are set correctly as long as your proxy forwards it. If your proxy doesn't forward that header, add:

COOKIE_SECURE: "true"

Example Caddy config:

recipes.example.com {
    reverse_proxy localhost:8000
}

Configuration

All configuration is via environment variables. Settings entered in the setup wizard are stored in the database and used as fallbacks when the corresponding env var is not set.

Required

Variable Description
JWT_SECRET_KEY Secret used to sign auth tokens. Generate with python -c "import secrets; print(secrets.token_hex(32))"
NUXT_PUBLIC_API_BASE Client-side API base. Set to /api when using the bundled nginx.
NUXT_API_BASE Server-side (SSR) API base. Set to http://127.0.0.1:8001 inside the container.

Optional

Variable Description
OPENAI_API_KEY Enables video and photo recipe import
WEBSITE_URL Public base URL, used in password-reset and magic-link emails (e.g. https://recipes.example.com)
WEBSITE_NAME Display name shown in emails (default: Plateful)
ENVIRONMENT Set to production in production (affects CORS and logging)
COOKIE_SECURE Force true or false for the cookie Secure flag. Defaults to auto-detect via X-Forwarded-Proto.

SMTP (email)

Variable Description
SMTP_HOST SMTP server hostname
SMTP_PORT SMTP port (default: 587)
SMTP_USERNAME SMTP username
SMTP_PASSWORD SMTP password
SMTP_FROM_EMAIL From address for outgoing emails
SMTP_USE_TLS Use STARTTLS (default: true)
SMTP_USE_SSL Use SSL/TLS on connect (default: false)

OAuth (social login)

Variable Description
OAUTH2_GOOGLE_CLIENT_ID / _SECRET Google OAuth2 credentials
OAUTH2_GITHUB_CLIENT_ID / _SECRET GitHub OAuth2 credentials
OAUTH2_DISCORD_CLIENT_ID / _SECRET Discord OAuth2 credentials
OAUTH2_APPLE_CLIENT_ID, _TEAM_ID, _KEY_ID Apple Sign In credentials
OAUTH2_APPLE_PRIVATE_KEY Apple Sign In private key (PEM, newlines as \n)

Data

Everything is stored inside the volume mounted at /app/backend/data:

/app/backend/data/
  plateful.db      # SQLite database
  images/          # uploaded and imported images

To back up, copy that directory (or the named volume) while the container is running. To migrate to another host: stop the container, copy the volume, start on the new host.


Building from source

git clone https://code.letsnot.run/l4stidi0t/plateful.git
cd plateful
docker build -t plateful:local .
docker run -d -p 8000:8000 \
  -v plateful-data:/app/backend/data \
  -e NUXT_PUBLIC_API_BASE="/api" \
  -e NUXT_API_BASE="http://127.0.0.1:8001" \
  plateful:local

Stack

  • Backend — Python / FastAPI / SQLAlchemy async / SQLite (default) / PostgreSQL (optional)
  • Frontend — Nuxt 4 / Vue 3 / Nuxt UI v4 / Tailwind CSS
  • Container — nginx reverse proxy · FastAPI :8001 · Nuxt SSR :3000 · single exposed port