Skip to main content

How to Self-Host Tandoor Recipes: Full-Featured Recipe Manager 2026

·OSSAlt Team
tandoorrecipesnutritionmeal-planningself-hostingdocker2026

TL;DR

Tandoor Recipes (MIT, ~5K GitHub stars, Python/Django) is a feature-rich self-hosted recipe manager with detailed nutritional information. While Mealie focuses on simplicity, Tandoor goes deeper: built-in nutritional database (OpenFoodFacts integration), barcode scanning for ingredients, detailed shopping list with supermarket aisle mapping, and full-text recipe search. If you care about nutrition tracking alongside recipes, Tandoor is the better choice.

Key Takeaways

  • Tandoor: MIT, ~5K stars, Python/Django — recipes + nutrition + shopping + barcode scan
  • OpenFoodFacts: Integration with the open food database for nutritional info
  • Barcode scanning: Scan ingredient barcodes to add to shopping lists
  • Supermarket mapping: Map ingredients to your store's aisles for efficient shopping
  • Meal planning: Weekly planner with nutritional summary
  • Full-text search: Search inside recipes (not just titles)

Tandoor vs Mealie

FeatureTandoorMealie
LicenseMITAGPL 3.0
GitHub Stars~5K~7K
UI ComplexityHigherSimpler
Nutrition dataYes (OpenFoodFacts)Limited
Barcode scanYesNo
Shopping listYes (advanced)Yes (basic)
Supermarket mappingYesNo
Recipe scrapingYesYes (better)
Meal planningYesYes
OCR importYesYes
APIYesYes

Part 1: Docker Setup

# docker-compose.yml
services:
  db_recipes:
    restart: always
    image: postgres:16-alpine
    volumes:
      - postgresql_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
      POSTGRES_USER: djangodb
      POSTGRES_DB: djangodb

  web_recipes:
    image: vabene1111/recipes:latest
    container_name: tandoor
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - staticfiles:/opt/recipes/staticfiles
      - mediafiles:/opt/recipes/mediafiles
    depends_on:
      - db_recipes
    environment:
      SECRET_KEY: "${SECRET_KEY}"    # openssl rand -hex 64
      DB_ENGINE: django.db.backends.postgresql
      POSTGRES_HOST: db_recipes
      POSTGRES_PORT: "5432"
      POSTGRES_USER: djangodb
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
      POSTGRES_DB: djangodb
      ALLOWED_HOSTS: "meals.yourdomain.com"
      GUNICORN_MEDIA: "0"
      TIMEZONE: "America/Los_Angeles"
      ACCOUNT_EMAIL_SUBJECT_PREFIX: "[Tandoor]"
      DEBUG: "0"

  nginx_recipes:
    image: nginx:mainline-alpine
    restart: always
    ports:
      - "80:80"
    volumes:
      - staticfiles:/static:ro
      - mediafiles:/media:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
    depends_on:
      - web_recipes

volumes:
  postgresql_data:
  staticfiles:
  mediafiles:
# nginx/conf.d/recipes.conf
server {
    listen 80;
    server_name _;
    
    client_max_body_size 16M;
    
    location /static/ {
        alias /static/;
    }
    
    location /media/ {
        alias /media/;
    }
    
    location / {
        proxy_pass http://web_recipes:8080;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
# Generate secret key:
openssl rand -hex 64

docker compose up -d

Part 2: HTTPS with Caddy

Replace the nginx container with Caddy for automatic HTTPS:

meals.yourdomain.com {
    handle /static/* {
        file_server {
            root /path/to/staticfiles
        }
    }
    handle /media/* {
        file_server {
            root /path/to/mediafiles
        }
    }
    reverse_proxy web_recipes:8080
}

Or simply proxy through Caddy to the nginx container:

meals.yourdomain.com {
    reverse_proxy localhost:80
}

Part 3: Initial Setup

  1. Visit https://meals.yourdomain.com
  2. Create admin account
  3. Admin Panel → Household → Create Your Household
  4. Invite other users to the household

Part 4: Import Recipes

From URL

  1. Recipes → + New → Import From URL
  2. Paste recipe URL
  3. Tandoor extracts ingredients, instructions, images
  4. Review and save

Manual Entry

  1. Recipes → + New → Manual
  2. Add ingredients (search by name → Tandoor suggests from food database)
  3. Add steps with photos
  4. Set servings, time, difficulty

From OCR (Photo)

  1. Recipes → + → Create From Image
  2. Upload photo of printed/handwritten recipe
  3. Tandoor uses OCR to extract text
  4. Review and correct

Part 5: Nutrition Information

When you add ingredients, Tandoor looks up nutrition data:

  1. Type ingredient name → Tandoor suggests matches from OpenFoodFacts
  2. Select the correct product → nutrition data auto-filled
  3. Recipe shows: calories, protein, carbs, fat per serving

Manual Nutrition Lookup

  1. Foods → Search or Create Food
  2. Type name or scan barcode
  3. Enter or import nutrition data per 100g

Part 6: Shopping Lists

Generate shopping lists from recipes:

  1. Add to Shopping List from any recipe (adjust servings)
  2. Multiple recipes → shopping list auto-combines quantities
  3. Shopping → Lists → My List

Supermarket Mapping

Map ingredients to your supermarket's sections:

  1. Supermarkets → Create Supermarket
  2. Add sections: Produce, Dairy, Meat, Canned Goods, Frozen, Bakery
  3. Foods → Edit Food → assign to supermarket section

Shopping list sorts by supermarket section → efficient shopping path through the store.

Barcode Scanning

  1. Shopping → Scan Barcode
  2. Scan product barcode with your phone camera
  3. Tandoor looks up the product → adds to shopping list

Part 7: Meal Planning

  1. Meal Plan → Weekly View
  2. Click any day → Add Recipe
  3. Set servings (for the family)
  4. Nutritional summary shown for the week
  5. Generate Shopping List from the meal plan

Part 8: Recipe Scraping Sites

Tandoor supports 700+ recipe websites including:

  • allrecipes.com
  • seriouseats.com
  • food52.com
  • BBC Good Food
  • NYT Cooking
  • Bon Appétit
  • Epicurious

Part 9: API

# Get API token from Settings → API → Create Token

# List recipes:
curl https://meals.yourdomain.com/api/recipe/ \
  -H "Authorization: Token YOUR_API_TOKEN"

# Search recipes:
curl "https://meals.yourdomain.com/api/recipe/?query=pasta" \
  -H "Authorization: Token YOUR_API_TOKEN"

# Create a shopping list:
curl -X POST https://meals.yourdomain.com/api/shopping-list/ \
  -H "Authorization: Token YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"recipes": [{"recipe_id": 42, "servings": 4}]}'

Maintenance

# Update Tandoor:
docker compose pull
docker compose up -d

# Run migrations:
docker exec tandoor python manage.py migrate

# Backup:
# Database:
docker exec db_recipes pg_dump -U djangodb djangodb | gzip \
  > tandoor-db-$(date +%Y%m%d).sql.gz

# Media files (uploaded photos):
tar -czf tandoor-media-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect tandoor_mediafiles --format '{{.Mountpoint}}')

# Logs:
docker compose logs -f web_recipes

See all open source food and lifestyle tools at OSSAlt.com/categories/lifestyle.

Comments