Published

Mealie

Recipe manager and meal planner: you import recipes from any website by URL, organize them with tags and categories, plan meals on a calendar and build shared shopping lists. Fits households and small groups that want one private recipe library, with SQLite by default or PostgreSQL for more concurrent users.

Resources by load level

What the app itself needs at each level, next to what we recommend for a server that runs only this app.

LevelWhat it meansApp requirementsRecommended
LightEstimateOne household of up to 5 people, up to 500 recipes with images, weekly meal plans and shopping lists, a few URL imports a day; SQLite.1 vCPU · 1 GiB RAM · 3.023 GiB disk1.32 vCPU · 2.7 GiB RAM · 12.907 GiB disk
MediumEstimateUp to 20 users in a few households (the docs' SQLite range), up to 2,000 recipes with images, daily meal planning, shared shopping lists and imports.1 vCPU · 1 GiB RAM · 7.417 GiB disk1.32 vCPU · 2.7 GiB RAM · 17.96 GiB disk
HeavyEstimateUp to 50 users across several households, up to 5,000 recipes with images, frequent concurrent imports and backups; PostgreSQL recommended, one worker.2 vCPU · 2 GiB RAM · 16.206 GiB disk2.52 vCPU · 3.9 GiB RAM · 28.067 GiB disk

Recommended = app requirements + system baseline + safety headroom, under sizing policy 2026.10.0. Options stay at their defaults. “Estimate” means the sources give no number for that case, so it is worked out from them by the method stated under Components. How the numbers are built

Size it in the Stack Sizer

Ready-to-run files

Support level Supported

Compose template from the official sources; not yet verified by a run.

Create docker-compose

Components

What each component needs at each load level, before baseline and headroom.

vCPU / GiB RAM / GiB disk
ComponentLightMediumHeavySources
Mealie (web UI and API) (app)1 / 1 / 3.0231 / 1 / 7.4172 / 2 / 16.206[4][7][10][17][20][23][25]
PostgreSQL (database)———
How the estimates are worked out
  • Mealie (web UI and API) · Light: RAM: the 1000M memory limit of the docs' compose for the default single Uvicorn worker, rounded up to 1 GiB. vCPU: one Python process (UVICORN_WORKERS 1). Disk: image 1.521 GiB (0.398 compressed + 1.123 unpacked, both kept by the containerd image store) + 500 recipes × 1 MiB with images (ANAROQ's assumption) × 3 for live data and two backup zips in /app/data/backups = 1.465 + 0.037 GiB of rotated logs = 3.023.
  • Mealie (web UI and API) · Medium: RAM and vCPU as light: still one Uvicorn worker inside the docs' 1000M limit (rounded up to 1 GiB), which the docs pair with SQLite for 1-20 users. Disk: image 1.521 GiB (0.398 compressed + 1.123 unpacked, both kept by the containerd image store) + 2,000 recipes × 1 MiB with images (ANAROQ's assumption) × 3 for live data and two backup zips in /app/data/backups = 5.859 + 0.037 GiB of rotated logs = 7.417.
  • Mealie (web UI and API) · Heavy: Beyond the docs' 20-user SQLite range they give no figure; ANAROQ doubles the 1000M limit (2 GiB) and allows 2 vCPU for concurrent URL imports, image processing (ffmpeg) and backup zips beside requests, still with one worker. Disk: image 1.521 GiB (0.398 compressed + 1.123 unpacked, both kept by the containerd image store) + 5,000 recipes × 1 MiB with images (ANAROQ's assumption) × 3 for live data and two backup zips in /app/data/backups = 14.648 + 0.037 GiB of rotated logs = 16.206.
  • database · PostgreSQL: Mealie's database holds recipe text, plans and lists (images stay in /app/data), and SQLAlchemy's default pool opens at most 5 + 10 overflow connections, inside the sidecar's 20-connection envelope. Embedded metadata DB with the image's default config: equals the PostgreSQL profile's light preset (≤ 5 GB data, ≤ 20 concurrent connections) at every load level. Light preset method: shared_buffers 25% of RAM, worst-case work_mem/maintenance_work_mem budget, 0.5 GiB image + 5 GiB data + 1 GiB WAL.

Options that change resources

database

Database engine. SQLite (the default) lives in /app/data inside the Mealie container and fits 1-20 users; PostgreSQL adds a separate container for many concurrent users and enables fuzzy search. Don't put SQLite on network storage.

Default: sqlite

Ports

Public ports are meant to be reached from outside the stack, usually through a reverse proxy; internal ones stay on the stack's own network.

ComponentPortExposurePurposeSources
Mealie (web UI and API)9000/tcpPublic, through a proxyWeb UI and REST API (HTTP; put behind a TLS reverse proxy)[4][7][15]
PostgreSQL5432/tcpInternal onlyPostgreSQL connections from Mealie (database=postgres only)[5]

Every port in the catalog, with conflicts between apps

User and permissions (UID/GID)

The user each container's process runs as, and the paths it writes to. A bind mount for one of these paths must be writable by that UID:GID.

ComponentUID:GIDUserStarts as rootWrites toSources
Mealie (web UI and API)1000:1000abcYes, prepares its directories, then drops to this user/app/data[3][4][15]
PostgreSQL999:999postgresYes, prepares its directories, then drops to this user/var/lib/postgresql/var/run/postgresql[26][27][33]
  • Mealie (web UI and API): The image creates user abc (uid 911) and starts as root: entry.sh remaps abc to PUID/PGID (911 by default; 1000:1000 in the docs' compose and in this template), chowns /app to it and drops privileges with gosu. A bind mount of /app/data therefore needs no manual chown.

Storage growth

How much each component's data grows per month at each load level, on top of the disk in the profile. A value marked Assumption is ANAROQ's stated assumption, not a figure from the sources; the notes say what it rests on.

GiB per month
ComponentLightMediumHeavySources
Mealie (web UI and API)Assumption0.1220.4881.221[10][17]
PostgreSQLAssumption0.0010.0030.008
What the growth figures rest on
  • Mealie (web UI and API): Upstream gives no growth rate. Assumes the level's 500 recipes (1 MiB each with images) are added over 12 months, and that you keep two backup zips in /app/data/backups (Mealie deletes none on its own): 500 × 1 MiB × 3 / 12 = 0.122 GiB.
  • Mealie (web UI and API): Upstream gives no growth rate. Assumes the level's 2,000 recipes (1 MiB each with images) are added over 12 months, and that you keep two backup zips in /app/data/backups (Mealie deletes none on its own): 2,000 × 1 MiB × 3 / 12 = 0.488 GiB.
  • Mealie (web UI and API): Upstream gives no growth rate. Assumes the level's 5,000 recipes (1 MiB each with images) are added over 12 months, and that you keep two backup zips in /app/data/backups (Mealie deletes none on its own): 5,000 × 1 MiB × 3 / 12 = 1.221 GiB.
  • PostgreSQL: Only with database=postgres. No upstream figure; ANAROQ assumes 20 KiB of rows and indexes per recipe (images are files, not rows), with the level's 500 recipes added over 12 months: 500 / 12 × 20 KiB ≈ 0.001 GiB.
  • PostgreSQL: Only with database=postgres. No upstream figure; ANAROQ assumes 20 KiB of rows and indexes per recipe (images are files, not rows), with the level's 2,000 recipes added over 12 months: 2,000 / 12 × 20 KiB ≈ 0.003 GiB.
  • PostgreSQL: Only with database=postgres. No upstream figure; ANAROQ assumes 20 KiB of rows and indexes per recipe (images are files, not rows), with the level's 5,000 recipes added over 12 months: 5,000 / 12 × 20 KiB ≈ 0.008 GiB.

Upgrade and rollback

How to move to a new version safely, and how to go back if it fails.

Back up first

Create and download a backup from /admin/backups. With SQLite, also stop the container and copy the /app/data volume (the docs call this the best backup); with PostgreSQL, take a pg_dump too. Record the current image tag. [9][10]

Upgrade steps

  1. Read the release notes of every version you skip for breaking changes or manual actions, then create a backup at /admin/backups and download it. [9][10]
  2. Set the new pinned tag ghcr.io/mealie-recipes/mealie:vX.Y.Z in the Compose file, then run docker compose pull and docker compose up -d. The data volume is reattached, and pending Alembic migrations run when Mealie starts. [6][9][19]
  3. With database=postgres, keep the PostgreSQL major version when you upgrade Mealie: a new major needs a dump and restore (the docs point to docker-library/postgres#37). [5]

Roll back

Stop Mealie, put back the pre-upgrade copy of /app/data (and restore the pg_dump with PostgreSQL), then redeploy the previous tag. Don't run an older Mealie on data a newer one migrated; a UI backup restores only into the version that created it. [10][19]DerivedThe docs describe no downgrade. Derived from the Alembic migrations Mealie runs at startup and the docs' warning that a mismatched backup restore throws an error.

Known breaking changes

  • In 3.23.0: AI recipe import moved to /api/recipes/create/ai; /recipes/create/image still works but is hidden from the API docs. Custom prompt overrides of recipes/scrape-recipe.txt and parse-recipe-image.txt are ignored, replaced by compile-source.txt and build-recipe.txt. [14]
  • In 3.21.0: OIDC logins require the identity provider to send email_verified = true; if it doesn't emit the claim, logins fail until you configure it or set OIDC_REQUIRES_EMAIL_VERIFICATION=false. [13]
  • In 2.0.0: Households were added under groups, several recipe-creation endpoints moved (for example /recipes/create-url to /recipes/create/url) and updateAt became updatedAt; API integrations need updating. [14]

Limits

  • SQLite fits 1-20 users with limited concurrent writes. More concurrent users, or fuzzy search (PostgreSQL only), need database=postgres; you move between the two with a UI backup and restore. Never keep SQLite on network storage: it can corrupt or lock the database. [4][5][6][11]
  • Runs one Uvicorn worker. The docs warn that more workers (UVICORN_WORKERS) can leak memory, and the figures here assume one. Images on linux/amd64 and arm64 only, no 32-bit ARM. [6][7]
  • Recipe import by URL needs outbound internet access. The optional AI features call an external or self-hosted OpenAI-compatible API, which isn't part of these figures. [7][8]

Security

  • Sign in right after the first start with the built-in admin [email protected] / MyPassword and change its email and password at once: anyone who reaches the page first can log in with them. [6][16]
  • Keep ALLOW_SIGNUP=false (the default, set explicitly here) and invite users from the admin pages. Serve port 9000 only through an HTTPS reverse proxy, with BASE_URL set to the https address. [4][7][8]
  • The API isn't rate limited, and URL import makes the server fetch any address a user gives (SSRF and denial-of-service risk). Add rate limits at the proxy, and give accounts only to people you trust. [8]

Backup

  • Mealie's built-in backup (/admin/backups) writes a zip with the database as JSON and the data directory to /app/data/backups. It runs only when you start it, and the zips stay on the same disk: download them and store them off the server. [6][10][17]
  • Back up the /app/data volume too: with SQLite it holds the whole site (database, images, the .secret files), and the docs call stopping the container and copying it the best backup. With PostgreSQL, add a pg_dump; restoring a UI backup there needs a superuser (the sidecar's mealie user is one). [5][10][16][33]

Latest release

Newest upstream release
Mealie 3.28.0 [4][22]
This profile was checked against

Mealie 3.28.0

This profile was checked against the newest release.

Checked on
14 Oct 2026
State
Checked within the last 90 days
Where releases are published
GitHub Releases

Latest releases of every app

Version

Profile status
Published
Checked against release
Mealie 3.28.0
Profile version
1.0.0
Figures verified
14 Oct 2026
Catalog release
2026.10.10
Sizing policy
2026.10.0
Compose file
Unverified
Official site
mealie.io
Alternatives
Tandoor Recipes

Sources

  1. Docker Docs: Control startup order in Compose (pg_isready healthcheck, service_healthy) (Official docs · read 11 Oct 2026)
  2. mealie v3.28.0 docker/healthcheck.sh: curl -fsk http://127.0.0.1:${API_PORT:-9000}/api/app/about (Official repository · read 14 Oct 2026)
  3. mealie v3.28.0 docker/entry.sh: remaps user abc to PUID/PGID (default 911), chowns /app, then gosu (Official repository · read 14 Oct 2026)
  4. Mealie Docs: Installing with SQLite (compose: v3.28.0, 9925:9000, memory limit 1000M, /app/data, ALLOW_SIGNUP false, PUID/PGID, TZ, BASE_URL; 1-20 users) (Official Compose · read 14 Oct 2026)
  5. Mealie Docs: Installing with PostgreSQL (compose with postgres:17, DB_ENGINE and POSTGRES_* variables, many concurrent users) (Official Compose · read 14 Oct 2026)
  6. Mealie Docs: Installation Checklist (default credentials [email protected] / MyPassword, http://localhost:9925, UI backups, pin a vX.Y.Z tag) (Official docs · read 14 Oct 2026)
  7. Mealie Docs: Backend Configuration (PUID/PGID 911, BASE_URL, TZ, ALLOW_SIGNUP, DB_ENGINE, UVICORN_WORKERS 1, API_PORT 9000) (Official docs · read 14 Oct 2026)
  8. Mealie Docs: Security Considerations (API not rate limited, SSRF via URL import, disable sign-ups) (Official docs · read 14 Oct 2026)
  9. Mealie Docs: Updating Mealie (read the release notes, back up from the UI, change the tag, pull, up -d) (Official docs · read 14 Oct 2026)
  10. Mealie Docs: Backups and Restores (/admin/backups, copy /app/data for SQLite, Postgres restore needs a superuser) (Official docs · read 14 Oct 2026)
  11. Mealie Docs: FAQ (fuzzy search only on PostgreSQL; move by backup and restore) (Official docs · read 14 Oct 2026)
  12. Mealie Docs: Logs (written to /app/data/mealie.log and to stdout) (Official docs · read 14 Oct 2026)
  13. Mealie Docs: OpenID Connect (breaking change in v3.21.0: email_verified claim required) (Official docs · read 14 Oct 2026)
  14. Mealie Docs: Migration Guide (v3.23.0 AI import endpoint and prompt files; V1 to V2 households and endpoint moves) (Official docs · read 14 Oct 2026)
  15. mealie v3.28.0 docker/Dockerfile (user abc uid 911, VOLUME /app/data, APP_PORT 9000, HEALTHCHECK healthcheck.sh, curl and gosu installed) (Official repository · read 14 Oct 2026)
  16. mealie v3.28.0 core/settings/settings.py (ALLOW_SIGNUP false, default admin [email protected], .secret files in the data dir, UVICORN_WORKERS 1) (Official repository · read 14 Oct 2026)
  17. mealie v3.28.0 services/backups_v2/backup_v2.py (zip of database.json and the data dir, backups and .temp excluded, .secret restored) (Official repository · read 14 Oct 2026)
  18. mealie v3.28.0 db/db_setup.py (create_engine with SQLAlchemy's default pool; SQLite journal_mode MEMORY unless WAL) (Official repository · read 14 Oct 2026)
  19. mealie v3.28.0 db/init_db.py (Alembic upgrade to head at startup; CREATE EXTENSION pg_trgm on PostgreSQL) (Official repository · read 14 Oct 2026)
  20. mealie v3.28.0 core/logger/logconf.prod.json (mealie.log rotated at 10,000,000 B, 3 backups) (Official repository · read 14 Oct 2026)
  21. mealie v3.28.0 .github/workflows/test-backend.yml (backend tests on sqlite and on the untagged postgres service image) (Official repository · read 14 Oct 2026)
  22. mealie v3.28.0 pyproject.toml (version 3.28.0, license AGPL-3.0-only) (Official repository · read 14 Oct 2026)
  23. GHCR manifest of ghcr.io/mealie-recipes/mealie:v3.28.0 (linux/amd64, anonymous pull token): 427,358,439 B compressed; 14 layers decompressed and counted: 1,206,041,600 B (Measurement · read 14 Oct 2026)
  24. SQLAlchemy 2.0: Connection Pooling (QueuePool default pool_size 5, max_overflow 10) (Official docs · read 14 Oct 2026)
  25. Docker: the containerd image store keeps image layers both compressed and uncompressed (Official docs · read 14 Oct 2026)
  26. docker-library/postgres 18/trixie Dockerfile (postgres user 999:999, VOLUME /var/lib/postgresql) (Official repository · read 14 Oct 2026)
  27. docker-library/postgres 18/trixie docker-entrypoint.sh (chown, then gosu postgres) (Official repository · read 14 Oct 2026)
  28. PostgreSQL 18 documentation: 19.4 Resource Consumption (Official docs · read 10 Oct 2026)
  29. PostgreSQL 18 documentation: 19.3 Connections and Authentication (Official docs · read 10 Oct 2026)
  30. PostgreSQL 18 documentation: 19.10 Vacuuming (autovacuum settings) (Official docs · read 10 Oct 2026)
  31. PostgreSQL 18 documentation: 19.5 Write Ahead Log (max_wal_size) (Official docs · read 10 Oct 2026)
  32. PostgreSQL 18 documentation: 51.2 How Connections Are Established (Official docs · read 10 Oct 2026)
  33. Docker Official Image postgres: documentation (docker-library/docs) (Official docs · read 10 Oct 2026)
  34. Docker Hub: library/postgres tag 18.6 (compressed image sizes) (Official repository · read 10 Oct 2026)

All self-hosted apps