Deployment guide

Mealie

Mealie is an open-source, self-hosted recipe manager, meal planner and shopping list for the whole family. It imports recipes from any URL and automatically extracts the ingredients and instructions, organises recipes into cookbooks and categories, plans meals on a calendar, and generates consolidated shopping lists, all through a reactive web interface backed by a REST API.

This SecureAnyCloud VM image ships Mealie 3.19 fully installed and managed by systemd, served through an nginx reverse proxy on port 80. It is secure by default: a unique administrator password is generated for every VM on first boot, replacing Mealie's well-known default credentials.

Overview

Mealie is an open-source, self-hosted recipe manager, meal planner and shopping list for the whole family. It imports recipes from any URL and extracts the ingredients and instructions, organises recipes into cookbooks and categories, plans meals on a calendar, and generates consolidated shopping lists.

This SecureAnyCloud image ships Mealie 3.19 fully installed and managed by systemd, served through an nginx reverse proxy on port 80. It is secure by default: a unique administrator password is generated for every VM on first boot, replacing Mealie's well-known default credentials.

What you get:

  • Mealie 3.19.2, run from the official upstream container image (ghcr.io/mealie-recipes/mealie:v3.19.2) and managed as a systemd service.
  • nginx reverse proxy on port 80, forwarding to the application on loopback 127.0.0.1:9925 (container port 9000). The application is never exposed directly.
  • Secure first boot: a fresh administrator password is generated per VM and written to a root-only file.
  • Dedicated data volume: the SQLite database, recipe images and the token-signing key live on a separate, independently resizable EBS volume mounted at /var/lib/mealie, off the operating-system disk.
  • 24/7 SecureAnyCloud support.

Architecture at a glance

Mealie is officially a Docker-first deployment. The FastAPI backend serves the bundled prebuilt Vue frontend from a single official container image, and upstream does not support bare-metal installs. This image therefore runs that official, version-pinned image as a systemd-managed container.

You operate it entirely through systemctl and the standard configuration file, like any other service on theVM.

The main components are:

  • Application (container): 127.0.0.1:9925, forwarded to container port 9000
  • Reverse proxy: nginx on port 80
  • Configuration: /etc/mealie/mealie.env
  • Data (SQLite DB, recipe images, token secret): /var/lib/mealie, on its own EBS volume
  • Service units: mealie.service and nginx.service
  • Generated credentials: /root/mealie-credentials.txt, readable by root only

Connecting to your VM

Connect over SSH as the default login user for your image's operating system. For Ubuntu 24.04, the user is ubuntu:

ssh azureuser@<VM-public-ip>

Open the web interface in a browser at:

http://<VM-public-ip>/

First sign-in

A unique administrator password is generated on first boot. Retrieve it over SSH:

sudo cat /root/mealie-credentials.txt
MEALIE_URL=http://<VM-public-ip>/ MEALIE_ADMIN_EMAIL=admin@sac.local MEALIE_ADMIN_PASSWORD=<generated-on-first-boot>

Browse to http://<VM-public-ip>/ and sign in with the email and password shown. After your first sign-in, create your own user and change the administrator password under Settings, then Users.

Importing your first recipe

The fastest way to fill your library is to import a recipe from a URL:

  • In the sidebar, select Create, then Import with URL.
  • Paste a recipe URL from any supported recipe site and submit it.
  • Mealie scrapes the page and extracts the title, ingredients, instructions, image and metadata into a new recipe.

You can also add a family recipe by hand with the editor, or bulk-import from a Nextcloud Recipes, Paprika or other export under Settings, then Data Management.

Planning meals and shopping lists

Use Meal Planner in the sidebar to schedule recipes onto a calendar across the week.

From a meal plan, generate a consolidated Shopping List that aggregates the ingredients of the planned recipes.

Service management

The application and the proxy are ordinary systemd units:

# status systemctl status mealie.service systemctl status nginx.service
# restart the application (recreates the container)
sudo systemctl restart mealie.service
# follow application logs
sudo journalctl -u mealie.service -f
# or the container's own logs sudo docker logs -f mealie

Confirm both services are running with a quick scriptable check:

systemctl is-active mealie.service nginx.service

The health check is served without authentication through nginx and returns the running version:

curl -s http://localhost/api/app/about
{"production":true,"version":"v3.19.2","demoStatus":false,"allowSignup":false,...}

Configuration

Application configuration lives in /etc/mealie/mealie.env. After editing it, restart the service so the container picks up the new values:

sudo nano /etc/mealie/mealie.env
sudo systemctl restart mealie.service

Common settings include the timezone (TZ), the public base URL used for notifications (BASE_URL) and whether self-registration is allowed (ALLOW_SIGNUP, off by default).

For the full reference, see the Mealie backend configuration docs.

Backups

Mealie has a built-in backup feature under Settings, then Site Settings, then Backups. It snapshots the database and recipe data into an archive that you can download or restore.

For infrastructure-level backups, the data volume mounted at /var/lib/mealie holds all stateful data. Snapshot that EBS volume to capture the full application state.

Switching to PostgreSQL (optional)

SQLite is the default and is ample for a household or small team. For higher concurrency, point Mealie at PostgreSQL by editing /etc/mealie/mealie.env:

DB_ENGINE=postgres POSTGRES_USER=mealie POSTGRES_PASSWORD=<your-password> POSTGRES_SERVER=<db-host> POSTGRES_PORT=5432 POSTGRES_DB=mealie

Then restart the service with sudo systemctl restart mealie.service. Migrate your existing data with Mealie's backup and restore feature before you switch engines.

Enabling HTTPS

The image serves plain HTTP on port 80, so it works behind your own TLS terminator. For production, terminate TLS at an AWS Application Load Balancer or CloudFront in front of the VM. Alternatively, obtain a Let's Encrypt certificate directly on the VM:

sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com

Before you run the command, point a DNS record at the VM's public IP and make sure your security group allows inbound TCP 443.

Security notes

  • The application binds to loopback only (127.0.0.1:9925) and is reachable solely through the nginx reverse proxy on port 80.
  • The administrator password is generated per VM on first boot; no shared or default credentials ship in the image. The well-known default (changeme@example.com / MyPassword) is replaced before the VM is ready.
  • Restrict the VM's security group to the networks that need it, and put the VM behind TLS for any internet-facing deployment.

Support

This image is backed by 24/7 SecureAnyCloud technical support by email and chat. Support covers deployment, importing recipes, meal-plan configuration, backups, switching to PostgreSQL, TLS termination and scaling. Contact us at sales@secureanycloud.com.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Mealie on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure