Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Next.JS app to track family recipes and meal planning. Includes Kroger API for searching and add to cart.

Notifications You must be signed in to change notification settings

byronwall/recipes-modern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

262 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Family Recipes

A modern Next.js 14 app for creating and managing recipes, planning meals, and maintaining a shopping list. Optional Kroger integration lets you search products and add items to your Kroger cart.

Features

  • Recipes: create, view, edit, and delete recipes with grouped ingredients and step groups
  • Meal planning: schedule recipes on a calendar; mark as made; add plan to shopping list
  • Shopping list: add loose items, add all ingredients from a recipe, mark bought, bulk clear
  • Auth: email/password via NextAuth (Credentials provider)
  • Kroger (optional): OAuth connect, product search, add-to-cart from shopping list

Tech Stack

  • Next.js 14 (App Router), React 18
  • tRPC, Prisma (PostgreSQL)
  • NextAuth (credentials), Zod
  • Tailwind CSS, Radix UI, Lucide Icons

Running on Coolify

  • Build = docker compose --profile prod build
  • Deploy = docker compose --profile prod up -d
    • The -d is critical to detach once deployed. Otherwise, Coolify will keep the container "In Progress" indefinitely.
  • Ensure the Escape special characters in labels? is UNCHECKED. We need to expand an ENV in the label

There are hard coded traefik labels in the docker-compose.yaml file. These are set to work with Coolify's Traefik setup. Specifically, the endPoints are http and https for the app.

Setup (Images & Object Storage)

This app supports recipe images using an S3-compatible bucket (MinIO in Docker by default).

  1. Copy envs

    • Duplicate .env.example to .env and adjust values if needed (DB, media host, etc.).
  2. Start services

    • Using Docker Compose (app, Postgres, MinIO):
    docker compose up --build
    • minio-init auto-creates the bucket and applies CORS driven by env (APP_ORIGINS).
  3. Database

    • If running without Compose DB helper, ensure Postgres is up, then:
    npm run db:push
  4. Run the app

    npm run dev
  5. Uploading images

    • Open a recipe page and use the file input under "Images".
    • Files upload directly to the bucket via a pre-signed URL, then the server records metadata and links to the recipe.

Notes

  • For local dev via Compose, the app talks to MinIO at http://minio:9000 inside the Docker network.
  • To serve images over HTTPS in prod, set NEXT_PUBLIC_MEDIA_BASE_URL to your public S3/MinIO endpoint plus bucket (e.g. https://media.example.com/recipes-media). next.config.js derives image remotePatterns from this value.

Environment variables

Create a .env file in the project root.

Required (core app):

  • DB_URL = Postgres connection string (e.g. postgresql://user:password@localhost:5432/recipes-modern)
  • NEXTAUTH_URL = Base URL of the app (e.g. http://localhost:3000)
  • NEXTAUTH_SECRET = Any random string in production

Required (images & object storage):

  • NEXT_PUBLIC_MEDIA_BASE_URL = Public base URL to your bucket (e.g. http://localhost:9000/recipes-media)
  • S3_BUCKET = Bucket name (e.g. recipes-media)
  • S3_ACCESS_KEY_ID = Access key (used for both MinIO root and S3 client)
  • S3_SECRET_ACCESS_KEY = Secret
  • S3_REGION = Region label (default us-east-1)
  • Endpoints (choose one of the following setups):
    • Provide both:
      • S3_ENDPOINT_PUBLIC = Public browser-reachable endpoint (e.g. http://localhost:9000)
      • S3_ENDPOINT_INTERNAL = Server-reachable endpoint (e.g. http://minio:9000 in Docker)
    • Or provide a single legacy:
      • S3_ENDPOINT = Used as a fallback if the above are not set

Optional:

  • OPENAI_API_KEY = Enables AI recipe generation
  • KROGER_CLIENT_ID, KROGER_CLIENT_SECRET, NEXT_REDIRECT_URI = Kroger integration
  • NEXT_SKIP_ADD_TO_CART = Set to true to disable pushing items to Kroger cart
  • APP_ORIGINS = Comma-separated origins to allow in MinIO CORS (Compose defaults this to APP_URL)

Notes:

  • Env vars are validated at startup. To bypass during Docker builds, set SKIP_ENV_VALIDATION=1.
  • Kroger and AI are optional; omit those vars if you’re not using those features.

Verify MinIO setup

Use the MinIO client container to verify bucket, policy, and CORS:

# List buckets (should include your S3_BUCKET)
docker compose run --rm --entrypoint /bin/sh minio-init -lc \
  'mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"; mc ls local'

# Show anonymous policy and CORS for the bucket
docker compose run --rm --entrypoint /bin/sh minio-init -lc \
  'mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"; mc anonymous get local/"$S3_BUCKET"; mc cors get local/"$S3_BUCKET"'

# Quick write test to the internal endpoint from the app container
docker compose exec -T web-app node -e "const {S3Client,PutObjectCommand}=require('@aws-sdk/client-s3');(async()=>{const endpoint=(process.env.S3_ENDPOINT_INTERNAL||process.env.S3_ENDPOINT||'').replace(/\/$/,'');const s3=new S3Client({region:process.env.S3_REGION,endpoint,forcePathStyle:true,credentials:{accessKeyId:process.env.S3_ACCESS_KEY_ID,secretAccessKey:process.env.S3_SECRET_ACCESS_KEY}});await s3.send(new PutObjectCommand({Bucket:process.env.S3_BUCKET,Key:'healthcheck/test.txt',ContentType:'text/plain',Body:'ok'}));console.log('PUT_OK')})()"

Using Docker Compose

A docker-compose.yaml is provided to run the app and Postgres together.

docker compose up --build
  • Ensure .env contains DB_URL, NEXTAUTH_*, NEXT_PUBLIC_MEDIA_BASE_URL, required S3_* values, and optionally Kroger/AI variables.
  • The app will be available on http://localhost:3000.

Production build

npm run build
npm run start

In Docker (multi-step handled in the Dockerfile):

docker build -t recipes-modern .
docker run -p 3000:3000 --env-file .env recipes-modern

The container entrypoint runs npx prisma migrate deploy before next start.

Kroger integration

  • Go to /kroger and click “Sign in to Kroger” to connect your account.
  • You must configure KROGER_CLIENT_ID, KROGER_CLIENT_SECRET, and NEXT_REDIRECT_URI (must match the OAuth app’s redirect).
  • After connecting, you can search Kroger products and add items to your cart from the shopping list.

Project scripts

  • dev: start Next.js dev server
  • build: build the app
  • start: start the built app
  • start-prod: run Prisma migrate deploy, then start (used in Docker)
  • db:push: push Prisma schema to DB
  • db:studio: open Prisma Studio
  • lint: run Next.js ESLint

Directory overview

  • src/app — App Router pages (recipes, plan, list, auth, kroger)
  • src/server — tRPC routers, Prisma, NextAuth config
  • prisma/schema.prisma — database schema and migrations

Troubleshooting

  • Env validation errors: confirm required variables in .env match the names above

  • DB connection issues: ensure Postgres is running and DB_URL credentials are correct

  • Auth errors: confirm NEXTAUTH_URL matches the URL you’re visiting and NEXTAUTH_SECRET is set in production

  • Kroger errors: check OAuth app config and NEXT_REDIRECT_URI exact match

  • Images:

    • If uploads fail with 403/NoSuchBucket, ensure the bucket exists. Re-run:

      docker compose up -d minio-init
    • If browser PUT is blocked by CORS, set APP_ORIGINS in .env and re-run the init job:

      docker compose up -d minio-init
    • For private buckets, replace public policy with:

      docker compose run --rm --entrypoint /bin/sh minio-init -lc 'mc alias set local http://minio:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"; mc anonymous set none local/"$S3_BUCKET"'

About

Next.JS app to track family recipes and meal planning. Includes Kroger API for searching and add to cart.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published