Automation guide

Mealie Docker Compose: A Private Recipe Library You Can Restore

Build a private Mealie recipe server with local SQLite, persistent storage, disabled signup, verified household access, and recoverable backups.

Published and reviewed by OpenAlt · October 4, 2026

Close-up view of a complex industrial gear mechanism in black and white.
Photo by Pixabay on Pexels

Start Mealie with the current project image, persistent application data and public signup disabled. For a small household, use local SQLite unless your storage or concurrency requirements call for PostgreSQL. Before moving a treasured recipe collection, prove that a backup restores the recipes, images and accounts you expect.

The useful outcome is a dependable private library, not another container to maintain. If nobody in the household wants responsibility for updates and recovery, resolve that before investing time in imports and customization.

Table of contents

What should you decide before installation?

Decide who operates the service, where its data lives and how the household will reach it. Those choices matter more than customizing the first screen.

Mealie's installation checklist directs users to the project's GitHub container registry and identifies supported amd64 and arm64 architectures. Old search results may refer to previous images or deployment layouts. Use current project documentation as the starting point, especially when following a NAS tutorial written for an earlier release.

Write down the host, storage location, administrator and backup destination. Decide whether the library should be LAN-only, reachable through a private VPN or available behind authenticated HTTPS. Do not let the first successful router port-forward become an accidental long-term access policy.

The OpenAlt self-hosted directory helps you evaluate the broader operating tradeoff: controlling an application also means owning its maintenance. Mealie is a useful small example of that tradeoff because its data can become valuable long before anyone remembers to test restoration.

Should you use SQLite or PostgreSQL?

Local SQLite is the simplest starting point for a small household. Choose PostgreSQL when the project's documented requirements or your operating environment justify the extra database service.

The SQLite installation page describes a 1–20 user use case and warns against placing SQLite storage on a network-mounted filesystem. This is guidance about the database's location, not a ban on running Mealie on a NAS that provides suitable local storage.

SituationStarting decision
Small household, local application storageConsider the documented SQLite setup
Database files would live on a remote shareChange the storage design or follow the PostgreSQL path
Higher concurrent write activityReview PostgreSQL requirements
No operator for either database modelReconsider self-hosting before migration

Do not add PostgreSQL simply to make the architecture look more serious. It introduces another component to patch, back up and restore. Conversely, do not force SQLite onto unsuitable storage merely to preserve a single-container diagram.

How do you create the Compose service?

Use a persistent volume for /app/data and expose the interface only to the audience you intend. This private trial binds the host port to loopback; use the host browser or an SSH tunnel to reach it.

services:
  mealie:
    image: ghcr.io/mealie-recipes/mealie:v3.28.0
    ports:
      - "127.0.0.1:9925:9000"
    environment:
      ALLOW_SIGNUP: "false"
      PUID: "1000"
      PGID: "1000"
      TZ: America/Detroit
      BASE_URL: http://localhost:9925
    volumes:
      - mealie-data:/app/data
    mem_limit: 1000m
    restart: unless-stopped
volumes:
  mealie-data:

The image version matches the official SQLite example checked on October 4, 2026. It is a dated reference, so review the project's current release before a later installation. The explicit memory limit is a starting configuration, not a claim that every workload fits within it.

Save the file as compose.yaml, run docker compose up -d, and inspect docker compose logs --tail=100. Open http://localhost:9925 through the chosen private route. Verify the intended user and group can access persistent storage rather than broadly relaxing permissions after a startup failure.

Close-up of server racks in a data center highlighting modern technology infrastructure.
Photo by panumas nikhomkhai on Pexels
Detailed view of a server rack with a focus on technology and data storage.
Photo by panumas nikhomkhai on Pexels

What should you test before importing everything?

Test a small library containing manual and imported recipes, an image and a normal household user. Bulk imports can conceal problems that are obvious in a small, inspectable sample.

Follow the first-login and account steps in the installation checklist. Replace initial credentials promptly. Keep the administrator account for administration and use a normal account to verify day-to-day behavior.

A practical acceptance sequence is:

  1. Enter a short recipe manually and save an image.
  2. Import a recipe from a publicly accessible source you are entitled to use.
  3. Check ingredients, quantities, instructions and source attribution after import.
  4. Open the recipe from the household's actual phone or tablet.
  5. Restart the container and confirm the recipe and account remain.

An import failure does not automatically mean the deployment is broken. A source site can change markup, block automated retrieval or require a login. Compare manual entry with another permitted source before changing network or database settings. Do not promise that every website will import perfectly.

How do you keep household access private?

Treat signup, user permissions and public sharing as separate controls. Disabling new registrations does not automatically establish the visibility policy for every existing recipe, household or share link.

Mealie's backend configuration reference documents settings such as ALLOW_SIGNUP and BASE_URL. When moving from the local trial to a real hostname, update the external base URL and verify links through that exact address.

Use a separate browser session without an account to inspect what is publicly visible. Then test a normal user and the administrator. Keep a short record of what each can read or change; that is more useful than assuming that a private-looking dashboard enforces the intended access rules.

For remote use, choose a private VPN or maintain an HTTPS proxy with a deliberate authentication arrangement. A proxy in another container must reach Mealie through a suitable shared network, not its own loopback address. Verify login and navigation from the actual remote client before telling the household that access is ready.

How do you back up and rehearse recovery?

Keep a completed backup away from the Docker host, and restore it into a separate test instance before relying on it. Recovery testing should never start by overwriting the household's only working library.

The backup and restore guide provides an administration workflow at /admin/backups. For SQLite, it also documents stopping the container and backing up the complete /app/data directory. Choose a consistent method and record which files it protects.

Preserve the Compose configuration, image version and any separately managed secrets. Copy backups to independently protected storage. A file inside the same named volume remains vulnerable to losing that volume or its underlying disk.

During rehearsal, restore a matching backup to an isolated instance. Verify recipes, images, user access and a representative shopping list. The project explicitly describes restoring through its backup interface as destructive to the destination database, which is why the destination must be disposable.

Use the backup storage calculator with actual backup sizes and retention periods. Record how long the rehearsal took and where the recovery instructions live. Another household member should be able to find them if the usual operator is unavailable.

How should updates work?

Read the release notes, make a current recovery copy and update the pinned version deliberately. Automatic image replacement is a poor bargain when nobody is available to investigate an incompatible migration.

The updating documentation explains the project's update path. After replacement, repeat the small-library checks and confirm that backups still complete. Keep the old image reference and matching data backup together; an old executable may not safely use data changed by a newer release.

If you later connect household automation, begin only after the recipe service is stable. Our Home Assistant guide explains that system's separate operating responsibilities. The automation guide hub helps keep those dependencies understandable rather than combining every household service into one fragile deployment.

FAQ

Is SQLite suitable for a household?

Usually, when the documented workload fits and the database stays on appropriate local storage. Review PostgreSQL when those conditions change.

What if I cannot sign in after installation?

Check the current first-login instructions, startup logs and persistent-data ownership. Do not delete the data volume as an initial fix.

Why does one recipe URL fail to import?

The source may block retrieval or use unsupported markup. Test manual entry and another permitted source before blaming the database.

Does a named volume protect against data loss?

It preserves data during ordinary container replacement. Separate backups and a successful restore rehearsal protect against broader failures.