SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-08-13

Mealie su VPS: installazione con Docker Compose

Installa Mealie su un VPS con Docker Compose: importa ricette da un link, crea piani pasti e liste della spesa, configura nginx, TLS e backup.

Cosa fa un gestore di ricette self-hosted

Un gestore di ricette self-hosted conserva le ricette in un database su un server di tua proprietà e Mealie è la soluzione scelta dalla maggior parte delle famiglie. Incolli l'indirizzo di una pagina di ricette e Mealie ne legge ingredienti, passaggi, quantità e tempo di cottura, ignorando il testo descrittivo e la pubblicità. Nella tua raccolta finisce solo la ricetta.

Il resto dell'applicazione è essenziale. Puoi trascinare le ricette in un piano settimanale dei pasti e generare una lista della spesa a partire da quel piano. Ogni persona che cucina ha il proprio account. L'intera applicazione viene eseguita in un unico container e resta inattiva tra una richiesta e l'altra, quindi un VPS di dimensioni contenute la gestisce senza problemi.

Questa guida usa Docker Compose. Se i termini services: e volumes: non ti sono familiari, leggi prima come sono strutturati i file Docker Compose, perché tutto ciò che segue consiste in un unico file Compose e quattro comandi.

Installare Mealie con Docker Compose

Mealie pubblica le proprie immagini nel registro dei container di GitHub. A luglio 2026 il tag stabile corrente è v3.22.0. Fissa una versione invece di usare latest: con latest, un docker compose pull in un giorno qualsiasi può portarti a una migrazione del database per la quale non eri pronto.

sudo mkdir -p /srv/mealie
cd /srv/mealie
sudo nano docker-compose.yml
services:
  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:

Prima di avviarlo, controlla due righe.

La porta è indicata come 127.0.0.1:9925:9000, non come 9925:9000. Il container è in ascolto sulla porta interna 9000 e l'host mappa la porta 9925 su quella porta. Associare questa mappatura all'indirizzo di loopback consente a nginx di raggiungere Mealie, impedendo l'accesso da Internet. Docker aggiunge le proprie regole al packet filter, quindi un semplice 9925:9000 è raggiungibile dall'esterno anche quando il firewall indica la porta come chiusa. È importante capire una volta questa particolarità: consulta perché le porte Docker pubblicate ignorano ufw.

BASE_URL deve essere l'indirizzo pubblico esatto che userai, con lo schema e senza slash finale. Mealie genera da questo valore i link per la reimpostazione delle password e gli inviti. Impostalo su http://localhost:9925: l'invito che invierai al tuo partner conterrà un link funzionante soltanto sul server stesso.

Avvialo e monitora il primo boot.

sudo docker compose up -d
sudo docker compose logs -f mealie

Il primo avvio crea il database SQLite ed esegue le migrazioni, operazione che richiede alcuni secondi. Quando il log si stabilizza e non stampa più righe relative alle migrazioni, verifica localmente l'applicazione.

curl -I http://127.0.0.1:9925

Un 200 OK indica che l'applicazione è attiva. Connection refused indica che il container non è in esecuzione: esegui sudo docker compose ps e leggi il codice di uscita. Un container terminato con il codice 137 è stato arrestato perché ha superato il limite di memoria di 1000M, una situazione possibile nei piani con meno risorse.

Primo accesso e disattivazione delle registrazioni aperte

L'account predefinito è changeme@example.com e la password è MyPassword. Accedi con questi dati, quindi modifica subito entrambi, perché la coppia è riportata nella documentazione ed è quindi presente in ogni scanner.

ALLOW_SIGNUP: "false" nel file compose è intenzionale. Con le registrazioni aperte, chiunque trovi l'indirizzo può creare un account nel tuo archivio di ricette. Con le registrazioni disattivate, aggiungi gli utenti dall'area di amministrazione, che genera un link di invito da inviare personalmente. Il link viene creato usando BASE_URL, perciò questo valore è importante. Se in seguito esegui più applicazioni sullo stesso server e vuoi usare una sola password per tutte, Mealie può delegare l'autenticazione a un identity provider esterno, ad esempio un'istanza Authentik self-hosted.

Mealie raggruppa gli utenti in un nucleo familiare. Tutti gli utenti dello stesso nucleo condividono la raccolta di ricette, il piano dei pasti e la lista della spesa, come è utile in famiglia. Nuclei familiari separati sullo stesso server mantengono raccolte distinte, una configurazione adatta a una casa condivisa quando nessuno concorda sulle acciughe.

L’importatore, il motivo per cui lo esegui

Apri la raccolta di ricette, scegli di creare una ricetta da un URL e incolla un collegamento. Mealie recupera la pagina e cerca i dati strutturati della ricetta, cioè il blocco leggibile dalle macchine che la maggior parte dei siti di ricette incorpora per i motori di ricerca. Quando il blocco è presente, l’importazione è rapida e senza interventi manuali.

Puoi anche importare un’immagine o del testo normale incollato, ad esempio la fotografia di una pagina di un ricettario. Questi contenuti seguono un percorso più lento e devono essere verificati in seguito, perché una frazione scritta a mano può essere interpretata facilmente in modo errato.

Le importazioni in blocco vengono eseguite dalla stessa schermata: incolla un elenco di indirizzi, uno per riga, e Mealie li elabora in background. Puoi trasferire una raccolta di duecento segnalibri in una sola sessione.

Piani dei pasti e lista della spesa

Il pianificatore dei pasti è un calendario. Trascina una ricetta su un giorno per inserirla nel piano. La lista della spesa raccoglie quindi gli ingredienti delle ricette pianificate in un'unica lista e unifica i duplicati: se due ricette richiedono cipolle, viene visualizzata una sola voce invece di due.

La lista è una pagina aggiornata in tempo reale sul telefono mentre fai la spesa. Poiché è ospitata sul tuo server, tutte le persone della famiglia visualizzano la stessa lista contemporaneamente. Quando una persona spunta il latte, la voce scompare anche dallo schermo dell'altra.

Metti nginx e TLS davanti a Mealie

Mealie usa HTTP in chiaro e non gestisce direttamente i certificati. Termina TLS in nginx, configurato davanti a Mealie. Prima punta un record DNS A al server, perché la procedura di emissione del certificato verifica quel nome.

sudo apt update && sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/mealie
server {
    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 nginx

nginx -t, syntax is ok e test is successful sono il controllo decisivo. Esegui il reload solo dopo che il controllo è riuscito, perché il reload di una configurazione non valida lascia in esecuzione quella precedente e nasconde l'errore fino al riavvio successivo.

client_max_body_size 64M è necessario perché il valore predefinito di nginx è 1 MB. Il caricamento di una foto di una ricetta o il ripristino di un backup tramite browser invia un body più grande. Senza questa direttiva, nginx restituisce 413 Request Entity Too Large, non Mealie, quindi nei log dell'applicazione non compare nulla.

Poi emetti il certificato. La procedura e il relativo timer per il rinnovo sono descritti in emettere un certificato Let's Encrypt per nginx con certbot.

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d recipes.example.com

Certbot modifica il server block per metterlo in ascolto sulla porta 443 e aggiunge un redirect dalla porta 80. Carica il sito tramite https:// e verifica che il browser accetti il certificato. Se Mealie viene caricato, ma i relativi link reindirizzano a http://, allora BASE_URL contiene ancora http. Correggilo, quindi esegui sudo docker compose up -d per ricreare il container con il nuovo valore.

Pubblicare Mealie in un sottopercorso, ad esempio example.com/recipes, non funziona, perché il frontend non può essere servito da un sottopercorso. Usa un sottodominio.

Backup e operazioni di ripristino

Tutti i dati gestiti da Mealie si trovano in /app/data/ all’interno del container, che corrisponde al volume mealie-data. Copiando quel volume si copiano insieme ricette, immagini e database.

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 mealie

Il nome del volume usa il nome del progetto come prefisso. Il nome del progetto corrisponde alla directory che contiene il file compose. Da /srv/mealie, il volume è mealie_mealie-data. Per questo il primo comando è docker volume ls: usa il nome visualizzato dal comando, non quello riportato in questa guida. È importante arrestare prima il container, perché SQLite esegue spesso operazioni di scrittura e una copia a caldo può produrre un ripristino illeggibile.

Mealie dispone anche di una propria pagina di backup nell'area di amministrazione. Questa pagina crea un archivio portabile che contiene il database in formato JSON insieme alle immagini. Usalo per trasferire l'installazione tra server, perché rimane compatibile anche dopo un cambio di versione, cosa che una copia dei file grezzi potrebbe non garantire. Il ripristino è distruttivo per progettazione: elimina il database corrente prima di caricare l'archivio e non può essere annullato. Al termine, la sessione viene disconnessa.

Nessuna delle due copie è un backup se rimane sullo stesso server. Trasferisci l'archivio altrove secondo una pianificazione. È questo lo scopo dei backup cifrati su un server remoto con restic.

Aggiornamento di Mealie

cd /srv/mealie
sudo nano docker-compose.yml
sudo docker compose pull
sudo docker compose up -d
sudo docker compose logs -f mealie

Aumenta la versione fissata nel file, quindi esegui il pull e ricrea il container. Le migrazioni vengono eseguite al primo avvio della nuova immagine. Crea una copia del volume prima di passare a una nuova versione principale, perché una migrazione interrotta a metà può lasciare un database che l'immagine precedente non riesce più ad aprire. Leggi le note di rilascio relative a tutte le versioni comprese tra quella attuale e la nuova.

Quando l’importazione non riesce

Alcuni siti non pubblicano alcun dato strutturato per le ricette. Mealie importa quindi il titolo, ma lascia vuoto l’elenco degli ingredienti. Non è un comportamento che si possa correggere tramite configurazione. Inserisci manualmente il testo della ricetta.

Altri errori dipendono dalla protezione anti-bot del sito della ricetta. In questi casi il sito risponde a Mealie con una pagina di verifica invece della ricetta. Mealie simula già il comportamento di un browser e ruota lo user agent per ridurre il problema. Se il sito continua a rifiutare le richieste, le opzioni documentate sono inviare lo scraper tramite un proxy con una reputazione dell’indirizzo migliore oppure eseguire un’istanza di FlareSolverr che risolva la verifica in un browser reale. Entrambe le opzioni sono facoltative e si configurano tramite variabili d’ambiente sul container.

Un’importazione che non riesce perché il server non può raggiungere il sito è un problema diverso. Esegui il test dal server con curl -I https://the-site.example/recipe e leggi la riga di stato prima di attribuire il problema allo scraper.

Dove si colloca

Mealie è una buona prima applicazione self-hosted per una famiglia, perché le persone con cui vivi la useranno senza che tu debba chiederglielo. Svolge un compito simile a gestire una libreria fotografica personale con Immich, anche se in modo molto più leggero, e rientra nell'elenco più ampio delle applicazioni che vale la pena usare in self-hosting quest'anno. Un piccolo server può ospitare entrambe. Immich non è l'unica opzione per il secondo compito e, se non hai ancora deciso, i requisiti minimi di memoria e i comandi di backup di PhotoPrism e Immich sono abbastanza diversi da meritare una lettura prima di destinare il resto del disco.

FAQ

Perché l'importazione dell'URL di una ricetta non riesce?

Le cause comuni sono due. La pagina non pubblica dati strutturati sulla ricetta, quindi lo scraper non trova nulla e viene restituito un titolo senza ingredienti, oppure davanti al sito è presente un livello di protezione contro i bot che restituisce una pagina di verifica invece della ricetta. Nel secondo caso è possibile configurare Mealie per usare un proxy con una reputazione dell'indirizzo migliore oppure un'istanza self-hosted di FlareSolverr, che risolve la verifica in un browser reale. Prima di modificare qualsiasi impostazione, verifica con curl -I che il server riesca almeno a raggiungere la pagina.

PostgreSQL è necessario o SQLite è sufficiente?

SQLite è sufficiente per un uso domestico ed è l'impostazione predefinita. Passa a PostgreSQL quando la directory dei dati si trova su uno storage collegato alla rete, perché SQLite su un filesystem di rete produce errori relativi al database bloccato e può danneggiare il file. Per i ripristini con PostgreSQL, l'utente del database deve essere un superuser, poiché il ripristino elimina tutto prima di caricare l'archivio.

Posso eseguire Mealie senza un nome di dominio?

Sì, sulla tua rete. Imposta BASE_URL sull'indirizzo che digiterai realmente, ad esempio http://192.168.1.20:9925, e non configurare nginx. I link per gli inviti e il ripristino della password vengono creati a partire da BASE_URL, quindi un valore errato produce link che nessun altro può aprire. Non esporre il servizio a Internet tramite HTTP non cifrato, perché in tal caso le credenziali di accesso vengono trasmesse in chiaro.

Come posso assegnare alla mia famiglia account personali?

Lascia ALLOW_SIGNUP impostato su "false" e aggiungi le persone dall'area di amministrazione. Verrà generato un link di invito da inviare loro. Inserisci nello stesso nucleo familiare tutte le persone che condividono una cucina, così potranno condividere le ricette, il piano dei pasti e la lista della spesa. Più nuclei familiari sullo stesso server mantengono raccolte separate.

Cosa succede alle mie ricette se smetto di eseguire Mealie?

Vengono esportate. Il backup dell'area di amministrazione salva i dati in formato JSON. Mealie può anche esportare le ricette come file markdown semplici, leggibili con qualsiasi editor di testo senza installare software aggiuntivo. Esegui un'esportazione prima di averne bisogno e verifica di riuscire ad aprirla.