If your current recipe system is screenshots in your phone, saved reels, random browser bookmarks, notes from relatives, and one excellent soup recipe nobody can find when it matters, Mealie solves a very normal household problem. It gives you one place for recipes, meal planning, shopping lists, and shared access. This guide shows you how to install it on a VPS step by step, even if you are not already deep into self-hosting.

The goal here is not to build a clever demo container that looks impressive for two days. The goal is to build a small private family service that stays easy to open, easy to trust, and easy to keep. If you do that right, people actually use it.

What you are building

By the end of this guide, you will have:

  • a Mealie instance running on your VPS
  • a proper public URL such as recipes.example.com
  • HTTPS working automatically
  • signups disabled so random people cannot create accounts
  • a starting recipe library you can share with your household
  • a simple backup routine so your family cookbook does not disappear one bad day

For most families, this does not need a big server. If the VPS is mainly for Mealie and a lightweight reverse proxy, a small ServerSpan KVM VPS is already enough. If you plan to add more family apps later, step up one size and save yourself a migration.

Who this guide is for

This guide is for you if:

  • you want a private recipe manager your family can actually open and use
  • you are comfortable following terminal commands, even if you are not a full-time Linux admin
  • you want one predictable setup, not five optional deployment patterns

This guide is not trying to cover every possible advanced architecture. It chooses the least annoying stack for a normal household setup: Ubuntu or Debian on a VPS, Docker Compose, Mealie with SQLite, and Caddy for automatic HTTPS.

What you need before you start

  • a VPS running Ubuntu 24.04 or Debian 12
  • a domain name you control
  • a subdomain you can point to the VPS, such as recipes.example.com
  • SSH access to the server
  • Docker and Docker Compose working on the VPS

If you do not have the server part ready yet, start with Complete Linux VPS Setup Guide for Beginners. If you want the short version, provision a virtual server, log in over SSH, update the system, and make sure docker compose version returns a real result before you come back to this guide.

Step 1: point your subdomain to the VPS

In your DNS panel, create an A record for your recipe subdomain and point it to your VPS IPv4 address.

Example:

Type: A
Name: recipes
Value: 203.0.113.10

If you use IPv6, add an AAAA record too.

Wait a minute or two, then verify from your own machine:

dig recipes.example.com A +short
dig recipes.example.com AAAA +short

If the subdomain does not resolve to your VPS yet, stop here and fix DNS first. Do not continue and expect HTTPS to magically work later.

Step 2: connect to the VPS and create a clean project folder

Log in over SSH:

ssh youruser@your-server-ip

Then create a clean working directory for the Mealie stack:

mkdir -p ~/docker/mealie
cd ~/docker/mealie

That is where your Compose file, reverse proxy config, and persistent data will live. Keeping each app in its own directory saves you from future confusion.

Step 3: create the Mealie and Caddy stack

Create a file called docker-compose.yaml:

nano docker-compose.yaml

Paste this:

services:
  mealie:
    image: ghcr.io/mealie-recipes/mealie:v3.14.0
    container_name: mealie
    restart: unless-stopped
    expose:
      - "9000"
    volumes:
      - ./mealie-data:/app/data
    environment:
      ALLOW_SIGNUP: "false"
      PUID: 1000
      PGID: 1000
      TZ: Europe/Bucharest
      BASE_URL: https://recipes.example.com
      DEFAULT_EMAIL: changeme@example.com
      DEFAULT_GROUP: Family
      DEFAULT_HOUSEHOLD: Home

  caddy:
    image: caddy:2
    container_name: mealie-caddy
    restart: unless-stopped
    depends_on:
      - mealie
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./caddy-data:/data
      - ./caddy-config:/config

Save the file and exit.

This stack does three useful things:

  • it runs Mealie with persistent data in ./mealie-data
  • it turns signups off
  • it puts Caddy in front so you get automatic HTTPS without fighting certbot on day one

Mealie’s own documentation recommends SQLite for small deployments in the 1 to 20 user range, which fits a family setup perfectly well. That is why this guide keeps the database choice simple instead of dragging you into PostgreSQL for no good reason.

Step 4: create the reverse proxy config

Create a file called Caddyfile:

nano Caddyfile

Paste this:

recipes.example.com {
    encode gzip
    reverse_proxy mealie:9000
}

Replace recipes.example.com with your real subdomain.

This tells Caddy to accept traffic for your recipe domain and send it to the Mealie container. Caddy handles the HTTPS certificate automatically as long as DNS is correct and ports 80 and 443 are reachable from the internet.

Step 5: start the stack

From inside ~/docker/mealie, run:

docker compose up -d

Then check that both containers are up:

docker compose ps

You want to see both mealie and mealie-caddy running.

If something looks wrong, read the logs before doing anything else:

docker compose logs --tail 100 mealie
docker compose logs --tail 100 caddy

Do not start editing random settings if the real problem is just that DNS still has not propagated or port 80 is blocked.

Step 6: open Mealie in your browser and sign in

Now open your browser and visit:

https://recipes.example.com

If everything is working, you should see the Mealie login screen.

If you left the default credentials unchanged, Mealie’s installation checklist documents the initial login as:

Username: changeme@example.com
Password: MyPassword

Log in once, then change the password immediately. After that, go to the admin area and validate the site settings page so you can catch any configuration warnings early.

This is also the right moment to change the email address away from the placeholder account if you kept the defaults for first boot.

Step 7: make it usable for real life, not just technically “installed”

A lot of self-hosted apps fail right here. They install correctly, then nobody uses them because the owner never turned them into a service that fits actual life.

Do these things next:

  • change the admin password immediately
  • set the instance name to something your family will recognize
  • check that the default group and household names make sense
  • turn the recipe homepage into something clean instead of a test pile
  • import a small starting set of recipes you genuinely cook

Do not dump 500 internet recipes into it on day one. That is just screenshot chaos with better search.

Step 8: import your first real recipes

This is where Mealie becomes useful instead of theoretical.

Start with 10 to 20 recipes you actually return to:

  • the weeknight meals you repeat
  • the holiday recipes people always ask for
  • the family recipes that currently live in chat threads or notebooks
  • the web recipes that everyone in the house already uses

Import from URLs where it makes sense. For handwritten or family recipes, add them manually and clean them up once instead of searching through photos forever.

A good early structure is enough. You do not need a perfect taxonomy. Start with a few human categories such as Weeknight, Soup, Bake Again, Guests, Family Classics, and Dessert. The point is retrieval, not academic purity.

Step 9: build the one workflow that makes the app actually stick

Mealie becomes genuinely useful when recipes turn into planning and shopping instead of staying an archive.

Use it like this once a week:

  • pick 5 to 7 meals for the coming days
  • add them to the meal planner
  • generate or build the shopping list from those meals
  • clean up duplicates and pantry items
  • let the list live in one shared place

That sounds almost too ordinary to be worth writing down. That is exactly why it matters. Household tools are only valuable when they reduce friction in ordinary life.

Step 10: add family access without making a mess

Mealie supports groups and households for a reason. Recipes can be shared more broadly, while meal planning and shopping-list behavior can stay household-specific. For a small family, one household is usually enough. Keep it simple unless you have a real reason not to.

For day one, the easiest path is this:

  • keep one admin account for setup
  • add one more normal user for the other adult who will actually plan or shop
  • wait before adding everyone else

If your family uses it for two weeks without friction, then expand. If you invite six people into a half-empty recipe app on day one, you are creating homework, not usefulness.

SMTP is worth adding later if you want proper invitations and password resets. Mealie’s install checklist explicitly calls SMTP out as important for those features. But if your goal today is getting the service online and usable, you do not need to block the whole project on email first.

Step 11: back it up before it starts to matter emotionally

Mealie has built-in backup and restore support. Use it. But be honest: a backup that lives only on the same VPS is not enough. That is just a slightly better-organized single point of failure.

At minimum, do this:

  • use the built-in Mealie backup from the web interface
  • back up the ~/docker/mealie/mealie-data directory at the VPS level
  • store a copy off the server too
  • test restoration once before you actually need it

Family recipe data looks casual until it disappears. Then suddenly it matters a lot.

If you want the broader backup mindset around this, read The Ultimate Guide to VPS Backups: Strategies, Tools, and Best Practices.

Step 12: update it the boring way

Once Mealie is live and people are using it, stop treating updates casually. Keep the image pinned and update deliberately.

cd ~/docker/mealie
docker compose pull
docker compose up -d

Before you update, take a backup. Do not float on latest and hope nothing breaks during the one hour people want to plan dinner.

That sounds obvious. Good. A lot of self-hosting pain comes from ignoring obvious things repeatedly.

When SQLite stops being the right answer

For a family cookbook, SQLite is the right choice most of the time. PostgreSQL becomes worth it when one of these becomes true:

  • you want fuzzy search
  • you expect heavier concurrent use
  • you are folding Mealie into a bigger internal stack
  • you plan to store data on NAS and want to avoid SQLite’s obvious risks there

Do not over-engineer the app just because you can. But do not cling to SQLite if the use case clearly moves beyond the small-household sweet spot either.

Which VPS plan makes sense for Mealie

Mealie is a very good self-hosting project partly because it is not heavy. You do not need a giant server to run a private family cookbook well.

For most households, vm.Entry is enough if the box mainly runs Mealie and a reverse proxy. vm.Ready is the more comfortable option if you also want backups, another family app, or simply more breathing room. That is the honest sell here. The reason to put Mealie on a proper VPS is not raw power. It is ownership, clean networking, proper HTTPS, and the ability to keep the service under your control long term.

If you want a household app stack that stays private and predictable, ServerSpan VPS hosting is the correct parent service for this article.

The setup checklist that matters more than the install command

  • use a dedicated subdomain
  • set BASE_URL correctly before you invite anyone else
  • turn signups off
  • use SQLite unless you have a real reason not to
  • do not put SQLite on NAS
  • back up both the application and the data directory
  • start with a curated recipe library, not an internet dump
  • get one weekly meal-planning routine working before adding complexity

That checklist matters more than the Docker command. Most self-hosted apps do not fail because the install command was wrong. They fail because the operator never decided what “used successfully” should look like.

If you want adjacent reading before or after the install, Managing Docker and Containers on a VPS covers the container-discipline side, and Complete Linux VPS Setup Guide for Beginners covers the wider host setup logic that still applies here.

The practical answer

If you are tired of screenshotting recipes, losing grocery lists in chat threads, and forgetting where the good meals are, self-hosting Mealie on a VPS is one of the most practical family self-hosting projects you can do. It solves a human problem, not just a technical one. The right setup is small, private, boring, and well-kept: one VPS, one proper domain, HTTPS, signups closed, backups in place, and a recipe library built for reuse instead of clutter.

The goal is not to build the world’s most advanced recipe platform. The goal is to build the one your household actually opens on a Tuesday night when someone needs to decide dinner and make a shopping list in under two minutes. That is what Mealie is good at, and that is exactly why it belongs on a ServerSpan VPS instead of inside your camera roll and your memory.

Source & Attribution

This article is based on original data belonging to serverspan.com blog. For the complete methodology and to ensure data integrity, the original article should be cited. The canonical source is available at: Stop Screenshotting Recipes: self-host Mealie and build a family cookbook that actually gets used.