If you’ve outgrown basic recipe apps and want serious meal planning, Tandoor Recipes is the self-hosted answer. It’s a full-featured recipe manager built for people who actually cook — with meal plans, shopping lists, nutritional data, ingredient management, and multi-user support.
Where simpler tools like Mealie focus on quick recipe imports, Tandoor goes deeper with food databases, unit conversions, cookbooks, and a recipe editor that handles complex dishes with multiple steps.
What Tandoor Recipes Does
- Recipe management — full editor with ingredients, steps, images, and keywords
- Meal planning — calendar-based planning with drag-and-drop
- Shopping lists — auto-generated from meal plans, shareable in real-time
- Nutritional tracking — integrates with the Open Food Facts database
- Cookbooks — organize recipes into themed collections
- Multi-user — households with permissions and shared spaces
- Import/export — supports Nextcloud Cookbook, Mealie, Paprika, and more
- API access — full REST API for integrations and automation
- Mobile-friendly — responsive PWA that works offline
Prerequisites
- A Linux server (Ubuntu 22.04+ or Debian 12+)
- Docker and Docker Compose installed
- At least 1GB RAM and 2GB disk space
- A domain name (optional, for remote access)
- Basic terminal knowledge
Step 1: Create the Project Directory
mkdir -p ~/tandoor && cd ~/tandoor
Step 2: Set Up Environment Variables
Create the .env file with your configuration:
cat > .env << 'EOF'
# Database
POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_USER=tandoor
POSTGRES_PASSWORD=CHANGE_THIS_TO_A_STRONG_PASSWORD
POSTGRES_DB=tandoor
# Tandoor Settings
SECRET_KEY=CHANGE_THIS_TO_A_RANDOM_STRING
ALLOWED_HOSTS=*
TIMEZONE=America/New_York
# Features
ENABLE_SIGNUP=0
ENABLE_METRICS=0
ENABLE_PDF_EXPORT=1
FRACTION_PREF_DEFAULT=0
COMMENT_PREF_DEFAULT=1
SHOPPING_MIN_AUTOSYNC_INTERVAL=5
EOF
Generate a proper secret key:
sed -i "s/CHANGE_THIS_TO_A_RANDOM_STRING/$(openssl rand -base64 45)/" .env
Important: Change POSTGRES_PASSWORD to something strong. Never use the default in production.
Step 3: Create the Docker Compose File
# docker-compose.yml
version: "3.8"
services:
db:
image: postgres:16-alpine
container_name: tandoor-db
restart: unless-stopped
volumes:
- tandoor-db:/var/lib/postgresql/data
env_file:
- .env
networks:
- tandoor
web:
image: vabene1111/recipes:latest
container_name: tandoor
restart: unless-stopped
env_file:
- .env
volumes:
- tandoor-static:/opt/recipes/staticfiles
- tandoor-media:/opt/recipes/mediafiles
ports:
- "8080:8080"
depends_on:
- db
networks:
- tandoor
volumes:
tandoor-db:
tandoor-static:
tandoor-media:
networks:
tandoor:
Step 4: Deploy
docker compose up -d
Wait about 30 seconds for the database to initialize and migrations to run:
docker compose logs -f web
Look for Listening at: http://0.0.0.0:8080. Once you see that, Tandoor is ready.
Step 5: Create Your Admin Account
Open your browser to http://YOUR_SERVER_IP:8080 and you’ll see the setup screen. Create your superuser account — this is your admin login.
If the setup screen doesn’t appear, create the account via CLI:
docker compose exec web python manage.py createsuperuser
Step 6: Initial Configuration
Once logged in:
- Go to Settings → Space Settings — configure your default space name
- Set up food database — navigate to Admin → Open Data and import the food database for nutritional info
- Configure units — Tandoor comes with defaults, but you can customize unit conversions under Admin → Units
- Invite household members — go to Space Settings → Invite Links to generate invite URLs
Importing Existing Recipes
Tandoor can import from several formats. Go to Import/Export in the sidebar:
From URLs
Paste any recipe URL and Tandoor will scrape it:
It uses the Recipe Schema standard — most major cooking sites are supported.
From Other Apps
Tandoor supports importing from:
- Mealie — JSON export
- Nextcloud Cookbook — direct import
- Paprika — .paprikarecipes files
- Chowdown — markdown files
- RecipeSage — JSON export
Go to Import/Export → select your source format → upload.
Setting Up Meal Plans
This is where Tandoor really shines:
- Navigate to Meal Plan in the sidebar
- Click any day to add a meal
- Select the meal type (breakfast, lunch, dinner, snack — or create custom types)
- Search and pick a recipe
- Set servings to auto-scale ingredients
The meal plan view shows your entire week. Drag recipes between days to rearrange.
Auto-generating Shopping Lists
Once your meal plan is set:
- Go to Shopping List
- Click “From Meal Plan”
- Select the date range
- Tandoor generates a combined ingredient list, merging duplicates and converting units
The shopping list is real-time — share it with household members and check items off together from different devices.
Nutritional Tracking
To enable nutritional info:
- Go to Admin → Open Data
- Click Import to load the Open Food Facts database
- Now when editing recipes, you can link ingredients to food database entries
- Tandoor auto-calculates calories, macros, and micronutrients per serving
This works best when you link your commonly used ingredients once — after that, every recipe using those ingredients gets automatic nutritional data.
Reverse Proxy Setup (Optional)
For HTTPS access with Nginx:
server {
listen 443 ssl;
server_name recipes.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/recipes.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/recipes.yourdomain.com/privkey.pem;
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Update your .env to restrict the allowed host:
ALLOWED_HOSTS=recipes.yourdomain.com
Then restart: docker compose restart web
Backups
Back up the database and media files:
# Database dump
docker compose exec db pg_dump -U tandoor tandoor > backup-$(date +%Y%m%d).sql
# Media files
docker compose cp web:/opt/recipes/mediafiles ./media-backup/
Automate this with a cron job:
0 3 * * * cd ~/tandoor && docker compose exec -T db pg_dump -U tandoor tandoor > backups/tandoor-$(date +\%Y\%m\%d).sql
Troubleshooting
“502 Bad Gateway” after startup
The web container is still initializing. Wait 60 seconds and try again. Check logs with docker compose logs web.
Recipes not importing from URL
Some sites block scraping. Try:
- Using a different browser’s user agent
- Manually creating the recipe and pasting ingredients
- Check if the site uses Recipe Schema markup (most major sites do)
Images not loading
Check that the media volume is mounted correctly:
docker compose exec web ls -la /opt/recipes/mediafiles/
If empty, the volume mount may have failed. Recreate with docker compose down && docker compose up -d.
Database connection errors
Ensure the database container is healthy:
docker compose exec db pg_isready -U tandoor
If not ready, check logs: docker compose logs db
Tandoor vs Mealie
| Feature | Tandoor | Mealie |
|---|---|---|
| Recipe editing | Advanced (multi-step) | Simple |
| Meal planning | Calendar with drag-drop | Basic calendar |
| Nutritional data | Open Food Facts integration | Auto-calculated |
| Import formats | 6+ formats | URL import |
| Shopping lists | Real-time shared | Basic |
| Setup complexity | Moderate (PostgreSQL) | Easy (SQLite) |
| Resource usage | ~400MB RAM | ~200MB RAM |
Pick Mealie if you want quick setup and basic recipe storage. Pick Tandoor if you want serious meal planning, nutritional tracking, and multi-user kitchens.
Conclusion
Tandoor Recipes is the most feature-complete self-hosted recipe manager available. The PostgreSQL backend makes it solid for households, the nutritional integration helps with diet tracking, and the real-time shopping lists are genuinely useful.
Start with importing your existing recipes, build a week’s meal plan, and generate your first shopping list. Once the workflow clicks, you’ll wonder how you managed without it.
Useful links: