Mealie is a self-hosted recipe manager that lets you import recipes from URLs, plan meals, and share a recipe library with your household. This tutorial covers adding Mealie to an existing Unraid server that already runs Docker Compose stacks with a shared PostgreSQL container on a custom Docker network.
Executive Summary#
Mealie runs as a Docker container connected to your existing PostgreSQL instance over a shared Docker network. The setup involves creating a dedicated database, adding the service to your compose file, and configuring the environment variables. First login uses default credentials that you change immediately after setup.
If you are starting from scratch without an existing PostgreSQL setup, the Mealie documentation covers a standalone SQLite install that may be simpler for your situation.
Prerequisites#
- Unraid with Docker Compose Manager installed
- A running PostgreSQL container accessible on a shared Docker network (this tutorial uses
core_net) - SSH access to your Unraid server
- Basic familiarity with editing files over SSH
Implementation#
Step 1: Create the Mealie Database#
SSH into your Unraid server and create a dedicated database for Mealie inside your existing PostgreSQL instance:
docker exec -it postgres psql -U postgres -c "CREATE DATABASE mealie;"You should see CREATE DATABASE in the response confirming it worked.
Step 2: Back Up Your Existing Compose File#
If you are adding Mealie to an existing stack, back up the compose file before editing it:
cp /mnt/user/compose/productivity/docker-compose.yml \
/mnt/user/compose/productivity/docker-compose.yml.bakStep 3: Add Mealie to Your Compose File#
Open your compose file and add the following service block. This assumes your PostgreSQL container is named postgres and is reachable on core_net:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.13.1
container_name: mealie
restart: unless-stopped
ports:
- "${HOST_IP}:${PORT_MEALIE:-9925}:9000"
deploy:
resources:
limits:
memory: 1000M
volumes:
- ${APPDATA_ROOT}/mealie:/app/data/
environment:
TZ: ${TZ}
PUID: 1000
PGID: 1000
ALLOW_SIGNUP: "false"
BASE_URL: http://${HOST_IP}:${PORT_MEALIE:-9925}
DB_ENGINE: postgres
POSTGRES_USER: ${MEALIE_DB_USER}
POSTGRES_PASSWORD: ${MEALIE_DB_PASSWORD}
POSTGRES_SERVER: ${POSTGRES_HOST}
POSTGRES_PORT: 5432
POSTGRES_DB: ${MEALIE_DB}
networks: [core_net]
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:9000/api/app/about >/dev/null 2>&1 || exit 1"]
start_period: 60s
interval: 30s
timeout: 5s
retries: 5
labels:
diun.enable: "true"
net.unraid.docker.icon: ${ICON_MEALIE}
net.unraid.docker.webui: http://${HOST_IP}:${PORT_MEALIE:-9925}
net.unraid.docker.shell: ${SHELL_DEFAULT}A few notes on this configuration:
- The
1000Mmemory limit is recommended by the Mealie docs. Python can pre-allocate more RAM than necessary on machines with a lot of memory and the cap keeps idle usage reasonable. ALLOW_SIGNUP: "false"prevents anyone from creating their own account. You will create users manually through the admin panel.- Port
9925on the host maps to port9000inside the container. Change the host port to anything available on your server.
Step 4: Update Your .env File#
Add the Mealie variables to your .env file, replacing the password with your actual PostgreSQL password:
# Mealie
MEALIE_DB=mealie
MEALIE_DB_USER=postgres
MEALIE_DB_PASSWORD=your-postgres-password
PORT_MEALIE=9925
ICON_MEALIE=https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/mealie.pngStep 5: Start the Stack#
cd /mnt/user/compose/productivity
docker compose up -dDocker will pull the Mealie image and start the container. A warning about swap limit capabilities on Unraid is harmless and just means the memory cap applies to RAM only.
Step 6: Verify It Is Running#
Check the container logs to confirm Mealie started cleanly:
docker logs mealie --tail 50Look for 200 OK responses in the output. Once you see those, the app is up and serving requests.
Step 7: First Login#
Open your browser and go to your Unraid IP on the port you configured:
http://YOUR-UNRAID-IP:9925Log in with the default credentials:
- Email:
[email protected] - Password:
MyPassword
Change your email and password immediately after logging in. Go to your profile settings in the top right corner to update them.
Step 8: Add Household Users#
- Open the left sidebar and go to Admin > Users
- Click + Create
- Set the User Group to
Homeand User Household toFamily - Fill in the username, full name, email, and a temporary password
- Leave all permission checkboxes unchecked for a standard user
- Click + Create
Share the temporary password with the user and have them change it on first login.
Step 9: Create a Backup#
Go to Admin > Backups and click + Create A Backup. The backup file is saved to /mnt/user/appdata/mealie/backups/ on your Unraid server and can also be downloaded directly from the Backups page.
Lab Notes & Troubleshooting#
Container fails to start with a database connection error. Confirm your PostgreSQL container is running and reachable on core_net. Double check MEALIE_DB_USER, MEALIE_DB_PASSWORD, and POSTGRES_HOST in your .env file match your actual PostgreSQL setup.
Mealie shows a blank page or 502 after starting. The container may still be initializing. Wait 60 seconds and refresh. Check docker logs mealie for errors if it does not come up.
Recipe import returns empty fields. Not every site structures its data the same way. Fill in missing fields manually in the edit view and save. Mealie improves site support regularly so a failing site may work after an update.
Memory usage is high. The 1000M limit in the compose file caps container memory. If you are seeing out-of-memory errors, increase the limit slightly. If idle usage is too high on a low-RAM server, the limit is working as intended.
Summary#
You now have Mealie running on Unraid with data stored in your shared PostgreSQL instance. Recipe data and uploads are persisted to your appdata directory, household users are set up, and a manual backup is ready to restore from. Import a recipe from a URL to confirm everything is working end to end.