Instalar Mealie en una VPS con Docker Compose
Instala Mealie en tu VPS con Docker Compose: extrae recetas desde enlaces, crea planes y listas de compra, y configura nginx, TLS y copias de seguridad.
Qué hace un gestor de recetas autoalojado
Un gestor de recetas autoalojado guarda tus recetas en una base de datos de un servidor que controlas, y Mealie es la opción que elige la mayoría de los hogares. Pegas la dirección de una página de recetas y Mealie extrae los ingredientes, los pasos, las raciones y el tiempo de cocción. Después descarta la historia y la publicidad. En tu colección sólo queda la receta.
El resto de la aplicación es sencillo. Incluye un plan semanal de comidas al que arrastras recetas y una lista de la compra que se genera a partir de ese plan. Cada persona que cocina tiene su propio inicio de sesión. Todo se ejecuta en un solo contenedor y permanece inactivo entre peticiones, por lo que una VPS modesta puede alojarlo sin problemas.
Esta guía usa Docker Compose. Si los términos services: y volumes: son nuevos para ti, lee primero cómo se estructuran los archivos de Docker Compose, porque todo lo que sigue consta de un archivo compose y cuatro comandos.
Instalar Mealie con Docker Compose
Mealie publica sus imágenes en el registro de contenedores de GitHub. En julio de 2026, la etiqueta estable actual es v3.22.0. Fije una versión en lugar de usar latest: con latest, un docker compose pull en un día cualquiera puede hacerle pasar a una migración de base de datos para la que aún no está preparado.
sudo mkdir -p /srv/mealie
cd /srv/mealie
sudo nano docker-compose.ymlservices:
mealie:
image: ghcr.io/mealie-recipes/mealie:v3.22.0
container_name: mealie
restart: always
ports:
- "127.0.0.1:9925:9000"
deploy:
resources:
limits:
memory: 1000M
volumes:
- mealie-data:/app/data/
environment:
ALLOW_SIGNUP: "false"
PUID: 1000
PGID: 1000
TZ: Europe/Amsterdam
BASE_URL: https://recipes.example.com
volumes:
mealie-data:Conviene revisar dos líneas antes de iniciarlo.
El puerto está escrito como 127.0.0.1:9925:9000 y no como 9925:9000. El contenedor escucha en 9000 internamente y el host asigna 9925 a ese puerto. Asociar esa asignación a la dirección de loopback permite que Nginx llegue a Mealie, pero impide el acceso desde Internet. Docker escribe sus propias reglas en el filtro de paquetes, por lo que un 9925:9000 simple queda accesible desde fuera aunque el firewall indique que el puerto está cerrado. Conviene entender esta particularidad una vez: consulte por qué los puertos publicados por Docker ignoran ufw.
BASE_URL debe ser la dirección pública exacta que utilizará, con el esquema y sin una barra final. Mealie genera a partir de ella los enlaces para restablecer contraseñas y los enlaces de invitación. Si la establece en http://localhost:9925, la invitación que envíe a su pareja contendrá un enlace que sólo funcionará en el propio servidor.
Inícielo y supervise el primer arranque.
sudo docker compose up -d
sudo docker compose logs -f mealieEl primer arranque crea la base de datos SQLite y ejecuta las migraciones, lo que tarda unos segundos. Cuando el registro se estabilice y deje de mostrar líneas de migración, compruebe la aplicación localmente.
curl -I http://127.0.0.1:9925Un 200 OK indica que la aplicación está activa. Connection refused indica que el contenedor no está en ejecución: ejecute sudo docker compose ps y lea el código de salida. Un contenedor que se detuvo con el código 137 terminó porque superó el límite de memoria de 1000M, algo que ocurre en los planes más pequeños.
Primer inicio de sesión y desactivación del registro abierto
La cuenta predeterminada es changeme@example.com y la contraseña es MyPassword. Inicie sesión con ellas y cambie ambas de inmediato, porque esa combinación aparece en la documentación y, por tanto, está incluida en todos los escáneres.
ALLOW_SIGNUP: "false" en el archivo compose es intencionado. Con el registro abierto, cualquiera que encuentre la dirección puede crear una cuenta en su recetario. Con el registro cerrado, puede añadir usuarios desde el área de administración. Esta acción genera un enlace de invitación que usted les envía directamente. El enlace se construye a partir de BASE_URL, por lo que este valor es importante. Si termina ejecutando varias aplicaciones en el mismo servidor y quiere usar una sola contraseña para todas, Mealie puede delegar el inicio de sesión en un proveedor de identidad externo, como una instancia de Authentik autoalojada.
Mealie agrupa a los usuarios en un hogar. Todas las personas de un mismo hogar comparten la colección de recetas, el plan de comidas y la lista de compras, que es lo que necesita una familia. Los hogares independientes del mismo servidor mantienen colecciones separadas. Esto resulta útil en un piso compartido cuando nadie se pone de acuerdo sobre las anchoas.
El importador, que es el motivo para ejecutar esto
Abra la colección de recetas, seleccione crear una receta a partir de una URL y pegue un enlace. Mealie descarga la página y busca datos estructurados de recetas, el bloque legible por máquinas que la mayoría de los sitios de recetas insertan para los motores de búsqueda. Si el bloque está presente, la importación es limpia e inmediata.
También puede importar desde una imagen o desde texto sin formato que pegue, por ejemplo, una fotografía de una página de un libro de cocina. Estos métodos siguen una ruta más lenta y requieren una comprobación posterior, porque una fracción escrita a mano se puede interpretar fácilmente de forma incorrecta.
Las importaciones masivas se ejecutan desde la misma pantalla: pegue una lista de direcciones, una por línea, y Mealie las procesa en segundo plano. Una colección de doscientas marcadores se puede transferir en una sola sesión.
Planes de comidas y lista de la compra
El planificador de comidas es un calendario. Arrastre una receta a un día para planificarla. La lista de la compra recopila los ingredientes de las recetas planificadas en una sola lista y combina los duplicados. Por ejemplo, si dos recetas necesitan cebollas, aparece una línea en lugar de dos.
La lista es una página actualizada en tiempo real en el teléfono mientras hace la compra. Como la aloja su propio servidor, todas las personas de la casa ven la misma lista al mismo tiempo. Cuando una persona marca la leche como comprada, desaparece de la pantalla de las demás.
Configurar nginx y TLS delante
Mealie usa HTTP sin cifrar y no gestiona certificados por sí mismo. Termina TLS en nginx, situado delante de Mealie. Primero, apunta un registro DNS A a tu servidor, ya que el paso de emisión del certificado verifica ese nombre.
sudo apt update && sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/mealieserver {
listen 80;
server_name recipes.example.com;
client_max_body_size 64M;
location / {
proxy_pass http://127.0.0.1:9925;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}sudo ln -s /etc/nginx/sites-available/mealie /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxnginx -t, syntax is ok y test is successful son la comprobación decisiva. Recarga nginx sólo después de que la comprobación se complete correctamente. Si recargas una configuración incorrecta, nginx mantiene la configuración anterior y el error queda oculto hasta el siguiente reinicio.
client_max_body_size 64M es necesario porque el valor predeterminado de nginx es 1 MB. Al cargar una foto de receta o restaurar una copia de seguridad desde el navegador, el cuerpo de la solicitud supera ese tamaño. Sin esa línea, nginx devuelve 413 Request Entity Too Large, no Mealie, y el registro de la aplicación no muestra nada.
A continuación, emite el certificado. Ese paso y su temporizador de renovación se explican en emitir un certificado de Let's Encrypt para nginx con certbot.
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d recipes.example.comCertbot modifica el bloque de servidor para escuchar en 443 y añade una redirección desde el puerto 80. Carga el sitio mediante https:// y confirma que el navegador acepta el certificado. Si Mealie carga, pero sus propios enlaces te envían a http://, entonces BASE_URL todavía indica http. Corrígelo y ejecuta sudo docker compose up -d para recrear el contenedor con el nuevo valor.
No es posible servir Mealie bajo una subruta como example.com/recipes, porque el frontend no puede servirse desde una subruta. Usa un subdominio.
Copias de seguridad y qué hace realmente una restauración
Todo lo que gestiona Mealie se encuentra en /app/data/ dentro del contenedor. Ese es el volumen mealie-data. Si copia ese volumen, copia las recetas, las imágenes y la base de datos al mismo tiempo.
sudo docker volume ls
sudo docker compose stop mealie
sudo docker run --rm -v mealie_mealie-data:/data -v "$PWD":/backup \
alpine tar czf /backup/mealie-data.tgz -C /data .
sudo docker compose start mealieEl nombre del volumen lleva el nombre del proyecto como prefijo. El nombre del proyecto es el directorio que contiene el archivo compose. Desde /srv/mealie, el volumen es mealie_mealie-data. Por eso el primer comando es docker volume ls: use el nombre que muestra, no el nombre de esta guía. Es importante detener primero el contenedor. SQLite puede estar escribiendo en ese momento y una copia en ejecución puede restaurar datos ilegibles.
Mealie también tiene su propia página de copias de seguridad en el área de administración. Esta página escribe un archivo portable que contiene la base de datos en formato JSON junto con las imágenes. Úselo para migrar entre servidores. Puede sobrevivir a un cambio de versión que una copia directa de los archivos no siempre soporta. Restaurar un archivo es destructivo por diseño. Elimina la base de datos actual antes de cargar el archivo y la operación no se puede deshacer. La sesión se cierra cuando finaliza.
Ninguna de las dos copias es una copia de seguridad mientras permanezca en el mismo servidor. Envíe el archivo a otra ubicación según un calendario. Para eso sirven las copias de seguridad cifradas fuera del servidor con restic.
Actualizar Mealie
cd /srv/mealie
sudo nano docker-compose.yml
sudo docker compose pull
sudo docker compose up -d
sudo docker compose logs -f mealieAumente la versión fijada en el archivo y después extraiga la imagen y vuelva a crear el contenedor. Las migraciones se ejecutan en el primer arranque de la nueva imagen. Haga una copia del volumen antes de cambiar de versión principal, porque una migración que falla a mitad de camino puede dejar una base de datos que la imagen anterior ya no podrá abrir. Lea las notas de la versión de todos los cambios comprendidos entre su versión actual y la nueva.
Cuando falla el importador
Algunos sitios no publican datos estructurados de recetas y Mealie importa sólo el título, con la lista de ingredientes vacía. No puede corregirlo mediante configuración. Pegue manualmente el texto de la receta.
Otros fallos se deben a la protección contra bots del sitio de recetas. El sitio responde a Mealie con una página de desafío en lugar de enviar la receta. Mealie ya se identifica como un navegador y rota su user agent para reducir este problema. Si el sitio sigue rechazando la solicitud, las opciones documentadas son enviar el scraper a través de un proxy con una mejor reputación de dirección IP o ejecutar una instancia de FlareSolverr que resuelva el desafío en un navegador real. Ambas opciones son optativas y se configuran mediante variables de entorno en el contenedor.
Un import que falla porque el servidor no puede acceder al sitio es un problema distinto. Pruébelo desde el servidor con curl -I https://the-site.example/recipe y lea la línea de estado antes de atribuir el fallo al scraper.
Dónde encaja
Mealie es una buena primera aplicación autohospedada para un hogar, porque las personas con las que vive la usarán sin que tenga que pedírselo. Cumple una función similar a su propia biblioteca de fotos con Immich, aunque es mucho más ligera, y forma parte de la lista más amplia de servicios que merece la pena autohospedar este año. Un solo servidor puede alojar ambas aplicaciones. Immich no es la única opción para esa segunda función y, si todavía está decidiendo, las necesidades mínimas de memoria y los comandos de copia de seguridad de PhotoPrism e Immich son lo bastante diferentes como para que convenga leer sobre ellos antes de asignarles el espacio restante del disco.
FAQ
¿Por qué falla la importación de una URL de receta?
Hay dos causas habituales. La página no publica datos estructurados de recetas, por lo que el scraper no encuentra nada y se obtiene un título sin ingredientes. O bien una capa de protección contra bots situada delante del sitio devuelve una página de desafío en lugar de la receta. En el segundo caso, puede configurar Mealie para usar un proxy con mejor reputación de dirección, o una instancia de FlareSolverr autoalojada que resuelva el desafío en un navegador real. Confirme que el servidor puede acceder a la página con curl -I antes de cambiar nada.
¿Necesito PostgreSQL o basta con SQLite?
SQLite basta para un hogar y es la opción predeterminada. Cambie a PostgreSQL cuando el directorio de datos esté en un almacenamiento conectado a la red, porque SQLite sobre un sistema de archivos de red produce errores de base de datos bloqueada y puede corromper el archivo. Las restauraciones con PostgreSQL requieren que el usuario de la base de datos sea superusuario, porque la restauración elimina todo antes de cargar el archivo.
¿Puedo ejecutar Mealie sin un nombre de dominio?
Sí, en su propia red. Establezca BASE_URL en la dirección que realmente vaya a escribir, como http://192.168.1.20:9925, y omita nginx. Los enlaces de invitación y restablecimiento de contraseña se generan a partir de BASE_URL, por lo que un valor incorrecto produce enlaces que nadie más puede abrir. No lo exponga a Internet mediante HTTP sin cifrado, porque las credenciales de inicio de sesión se enviarían sin cifrar.
¿Cómo doy a mi familia sus propias cuentas?
Deje ALLOW_SIGNUP establecido en "false" y añada a las personas desde el área de administración. Allí se genera un enlace de invitación que puede enviarles. Incluya en el mismo hogar a todas las personas que compartan una cocina para que compartan las recetas, el plan de comidas y la lista de la compra. Los hogares separados en un mismo servidor mantienen colecciones independientes.
¿Qué ocurre con mis recetas si dejo de ejecutar Mealie?
Puede conservarlas. La copia de seguridad del área de administración escribe los datos en formato JSON. Mealie también puede exportar las recetas como archivos markdown sin formato, que siguen siendo legibles en cualquier editor de texto sin necesidad de instalar ningún software. Realice una exportación antes de necesitarla y compruebe que puede abrirla.