services: ############################################ # Mealie ############################################ mealie: image: ghcr.io/mealie-recipes/mealie:latest container_name: recipellm-mealie restart: always ports: - "8080:9001" - "9000:9000" deploy: resources: limits: memory: 1000M # volumes: - mealie-data:/app/data/ - "/etc/localtime:/etc/localtime:ro" - "/etc/timezone:/etc/timezone:ro" environment: # Set Backend ENV Variables Here ALLOW_SIGNUP: "true" ############################################ # MCP Server ############################################ mcp: build: context: ./mcp dockerfile: Dockerfile container_name: recipellm-mcp volumes: - "/etc/localtime:/etc/localtime:ro" - "/etc/timezone:/etc/timezone:ro" - mcp-data:/app/data ports: - "8000:8000" environment: NTFY_SERVER: http://recipellm-ntfy MEALIE_BASE_URL: http://recipellm-mealie:9000 LETTA_BASE_URL: http://recipellm-letta:8283 RECIPELLM_MCP_SERVER_URL: http://recipellm-mcp:8000/sse/ # chat model to use when the chef-agent is created. #LETTA_CHAT_MODEL: "anthropic/claude-sonnet-4-20250514" LETTA_CHAT_MODEL: $LETTA_CHAT_MODEL TAVILY_API_KEY: $TAVILY_API_KEY depends_on: letta: condition: service_healthy mealie: condition: service_healthy restart: on-failure command: > sh -c " /app/.venv/bin/python /app/main.py & sleep 10 && curl -X POST http://localhost:8000/setup && wait " ############################################ # MCP Server ############################################ # Letta is an agent building framework with built-in memory/vectordb support. # https://docs.letta.com/quickstart/docker letta: image: letta/letta:0.9.0 container_name: recipellm-letta ports: - 8283:8283 - 5432:5432 #volumes: # This lets you see pgdata in the home directory and use it from Letta Desktop # It _does_ mean that letta's memory persists even if you use docker compose down -v though # This is less reliable for me than just using TCP/IP over port 5432 so I usually don't. # - ~/.letta/.persist/pgdata:/var/lib/postgresql/data environment: LETTA_DEBUG: "${LETTA_DEBUG:-false}" # https://docs.letta.com/guides/server/providers/anthropic ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY # https://docs.letta.com/guides/server/providers/google GEMINI_API_KEY: $GEMINI_API_KEY # Setting this up means we can do postgresql://letta:letta@localhost:5432/letta in Letta Desktop # https://docs.letta.com/guides/desktop/install LETTA_PG_DB: ${LETTA_PG_DB:-letta} LETTA_PG_USER: ${LETTA_PG_USER:-letta} LETTA_PG_PASSWORD: ${LETTA_PG_PASSWORD:-letta} TAVILY_API_KEY: ${TAVILY_API_KEY} restart: on-failure healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8283/v1/health/"] interval: 5s timeout: 5s retries: 18 start_period: 1s # Open WebUI is the front-end UI to Letta open-webui: image: ghcr.io/open-webui/open-webui:0.6.18 container_name: recipellm-open-webui volumes: - open-webui:/app/backend/data ports: - 3000:8080 environment: # https://docs.openwebui.com/getting-started/env-configuration/ - GLOBAL_LOG_LEVEL=INFO # Disable admin login - WEBUI_AUTH=false # Enable the /docs endpoint for OpenAPI viewing #- ENV=dev # Prevent a langchain warning - USER_AGENT=openwebui # Set tags and titles explictly - ENABLE_TAGS_GENERATION=false - ENABLE_TITLE_GENERATION=false #- TASK_MODEL=$TASK_MODEL #- TASK_MODEL_EXTERNAL=$TASK_MODEL_EXTERNAL # Disable some meaningless options - ENABLE_EVALUATION_ARENA_MODELS=false - ENABLE_AUTOCOMPLETE_GENERATION=false - ENABLE_RETRIEVAL_QUERY_GENERATION=false - ENABLE_FOLLOW_UP_GENERATION=false # OpenAI selection should go to Hayhooks to show agents - ENABLE_OPENAI_API=true - OPENAI_API_BASE_URL=http://recipellm-letta-openai-proxy:1416 - OPENAI_API_KEY=no_key_required # Ollama Options - ENABLE_OLLAMA_API=false # RAG options can be transformers, ollama, or openai - RAG_EMBEDDING_ENGINE=openai # Tavily Web Search in Open WebUI - ENABLE_WEB_SEARCH=false - WEB_SEARCH_ENGINE=tavily - TAVILY_API_KEY=$TAVILY_API_KEY # Audio options #- AUDIO_STT_ENGINE=$AUDIO_STT_ENGINE restart: unless-stopped # https://docs.openwebui.com/getting-started/advanced-topics/monitoring/#basic-health-check-endpoint # healthcheck: # test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/health"] # interval: 10s # timeout: 5s # retries: 18 # start_period: 5s ntfy: image: binwiederhier/ntfy:latest container_name: recipellm-ntfy restart: always ports: - "80:80" volumes: - ntfy-cache:/var/cache/ntfy - ntfy-data:/var/lib/ntfy environment: - NTFY_BASE_URL=http://localhost - NTFY_CACHE_FILE=/var/cache/ntfy/cache.db - NTFY_AUTH_FILE=/var/lib/ntfy/user.db - NTFY_BEHIND_PROXY=true - NTFY_UPSTREAM_BASE_URL=https://ntfy.sh deploy: resources: limits: memory: 512M command: serve ############################################ # Letta OpenAI Proxy ############################################ letta-openai-proxy: build: context: ./openai-proxy dockerfile: Dockerfile container_name: recipellm-letta-openai-proxy restart: always ports: - "1416:1416" environment: LETTA_BASE_URL: http://recipellm-letta:8283 HAYHOOKS_HOST: "0.0.0.0" HAYHOOKS_PORT: "1416" depends_on: letta: condition: service_healthy deploy: resources: limits: memory: 512M volumes: mealie-data: mcp-data: ntfy-data: ntfy-cache: open-webui: