Addio FTP: automatizzare il deploy di applicazioni Laravel su server Linux (Hetzner, OVH) con Deployer

È venerdì pomeriggio. Hai appena finito di sviluppare una nuova, attesissima funzionalità per la tua applicazione Laravel. Ora arriva il momento della verità: il deploy in produzione su quel server dedicato Hetzner o su quel VPS OVH. Se questa prospettiva ti provoca un'immediata sensazione di ansia, non sei solo. Per troppe aziende, il processo di rilascio è un rituale arcaico, manuale e terrificante.

La scena è fin troppo familiare: apri il tuo client FTP, trascini i file modificati sperando di non dimenticarne nessuno. Poi ti colleghi via SSH al server, lanci a mano comandi come git pull, composer install, e incroci le dita sperando che Composer non esaurisca la memoria. Metti il sito in manutenzione, esegui le migrazioni del database, e poi lo riattivi, solo per essere accolto da un gelido 500 Internal Server Error perché hai dimenticato di aggiornare i permessi di una cartella o di pulire la cache di configurazione. I minuti che seguono sono una corsa frenetica per sistemare il problema mentre i clienti iniziano a chiamare.

Se questo scenario ti suona anche solo vagamente familiare, è il momento di dire basta. Nel 2025, questo modo di lavorare non è solo inefficiente, è un rischio operativo che nessuna attività seria può permettersi. Fortunatamente, esiste un approccio moderno, affidabile e sorprendentemente accessibile. In questa guida, ti mostrerò come abbandonare per sempre l'era dell'FTP e automatizzare i tuoi deploy Laravel usando uno strumento potente e PHP-nativo: Deployer.

Stai cercando un Consulente Informatico esperto per la tua Azienda? Nel mio profilo professionale trovi la mia esperienza e le competenze specifiche per aiutarti a risolvere qualsiasi problematica tecnica. Contattami per una consulenza.

L'anatomia di un deploy manuale: perché è un pericolo per il tuo business

Prima di esplorare la soluzione, è fondamentale capire perché il "vecchio modo" è così problematico. Un processo di deploy manuale non è solo lento, è una collezione di anti-pattern che introduce rischi a ogni passo.

Il rituale del rischio

Un tipico deploy manuale su un server Linux (Debian o Ubuntu) assomiglia a questo:

  1. Login SSH: Accedi al server di produzione come utente root o con privilegi elevati. (Primo allarme di sicurezza).
  2. Manutenzione: Metti l'applicazione in modalità manutenzione (php artisan down). Il tuo sito è ufficialmente offline.
  3. Aggiornamento codice: Esegui git pull direttamente nella root del progetto. Se ci sono conflitti, devi risolverli sul server live. (Secondo allarme).
  4. Dipendenze: Esegui composer install. Questo scarica e installa le dipendenze in produzione, consumando preziose risorse del server e potenzialmente installando pacchetti di sviluppo (--no-dev viene spesso dimenticato).
  5. Migrazioni: Esegui php artisan migrate, sperando che non ci siano errori.
  6. Cache: Esegui una serie di comandi per pulire e ricreare le cache: config:cache, route:cache, view:clear.
  7. Permessi: Aggiusti manualmente i permessi delle cartelle storage e bootstrap/cache con chmod e chown.
  8. Fine manutenzione: Riattivi l'applicazione (php artisan up).

Questo processo può durare da 5 a 30 minuti, durante i quali il tuo sito è offline o in uno stato inconsistente.

I rischi concreti che stai correndo

Questo "rituale" non è solo scomodo, è dannoso per il business:

  • Downtime: Ogni deploy comporta un'interruzione del servizio, anche se breve. In un e-commerce, questo significa vendite perse.
  • Errore umano: Il processo dipende interamente dalla memoria e dall'attenzione di una persona. Dimenticare un singolo comando può compromettere l'intera applicazione.
  • Inconsistenza: Due deploy diversi, eseguiti da due persone (o dalla stessa persona in giorni diversi), potrebbero non essere identici, portando a bug difficili da replicare.
  • Assenza di rollback: Se qualcosa va storto dopo il deploy, come si torna indietro? Il processo è un altro intervento manuale, stressante e ad alto rischio, da eseguire sotto la pressione dell'emergenza.
  • Rischi di sicurezza: Eseguire comandi come composer o npm sul server di produzione può esporre a vulnerabilità. Il codice sorgente e la cronologia .git sono esposti sul server.

Questo approccio è un enorme cumulo di debito tecnico operativo. Come spiego nella mia pagina chi sono, il mio ruolo è aiutare le aziende a estinguere questo debito per costruire processi solidi e scalabili.

La soluzione: deploy atomici con Deployer

La filosofia moderna del deploy si basa su un concetto chiave: il rilascio deve essere un'operazione prevedibile, ripetibile, automatizzata e quasi istantanea. Deployer è uno strumento open-source, scritto in PHP, che ci permette di raggiungere questo obiettivo con eleganza.

Cos'è Deployer e perché è perfetto per l'ecosistema PHP?

A differenza di strumenti più complessi come Ansible o Jenkins, Deployer ha una curva di apprendimento molto dolce per gli sviluppatori PHP.

  • È scritto in PHP: La sua configurazione (chiamata "ricetta") è un semplice file PHP. Non devi imparare un nuovo linguaggio come YAML.
  • È agentless: Non richiede l'installazione di alcun software speciale sul server di produzione, a parte PHP, Git, e SSH.
  • Ha ricette pre-confezionate: Fornisce ricette pronte all'uso per i framework più comuni, incluso Laravel, che gestiscono il 90% delle operazioni standard.

Il concetto rivoluzionario di "Deploy Atomico"

Il cuore della magia di Deployer è il modo in cui gestisce la struttura delle cartelle sul server. Invece di modificare i file direttamente nella cartella di produzione (es. /var/www/my-app), Deployer crea una struttura di questo tipo:

/var/www/my-app/
├── releases/
│ ├── 20250610153000/  (vecchio rilascio)
│ └── 20250610160000/  (nuovo rilascio, in preparazione)
├── shared/
│ ├── .env
│ └── storage/
└── current -> /var/www/my-app/releases/20250610153000/ (symlink)

Il deploy avviene così:

  1. Deployer si collega via SSH e crea una nuova cartella in releases/ con un timestamp.
  2. Clona il tuo progetto da Git in questa nuova cartella.
  3. Esegue tutti i task necessari ( composer install, php artisan optimize, etc.) all'interno di questa nuova cartella. Il sito live non è minimamente influenzato.
  4. Crea dei link simbolici (symlink) dalla cartella shared/ alla nuova cartella di rilascio. Questo assicura che file persistenti come il .env o la cartella storage (con i file caricati dagli utenti) siano condivisi tra i rilasci e non vengano sovrascritti.
  5. Quando tutto è pronto, Deployer esegue un'unica, istantanea operazione: cambia il symlink current per farlo puntare alla nuova cartella di rilascio.

Questo switch è atomico: avviene in una frazione di secondo. Per il web server (Nginx o Apache), il passaggio dalla vecchia alla nuova versione è istantaneo. Il downtime è zero.

Guida pratica all'implementazione su un server Hetzner/OVH

Vediamo i passi pratici per implementare questo sistema.

1. Preparare il server Linux (Debian/Ubuntu)

Sul tuo server, dobbiamo preparare il terreno.

  • Crea un utente deployer: Mai usare root. Crea un utente dedicato (es. deployer) che sarà il proprietario dei file dell'applicazione.
  • Imposta l'autenticazione a chiave SSH: Copia la tua chiave pubblica SSH nel file ~/.ssh/authorized_keys dell'utente deployer. Questo permette a Deployer di connettersi senza password.
  • Installa il software necessario: Assicurati che sul server siano installati git, php-cli (della versione corretta), composer, e le estensioni PHP necessarie alla tua applicazione (es. php-xml, php-mysql).
  • Prepara la struttura delle cartelle: Crea la cartella principale (es. /var/www/my-app) e assegna la proprietà all'utente deployer.

2. Creare la ricetta deploy.php

Nella root del tuo progetto Laravel sul tuo computer locale, installa Deployer via Composer e crea un file deploy.php. Questo è un esempio semplificato:

<?php
namespace Deployer;

require 'recipe/laravel.php'; // Usa la ricetta base di Laravel

// Configurazione del progetto
set('application', 'Mia App Laravel');
set('repository', '[email protected]:tuo-utente/tuo-progetto.git'); // Il tuo repo
add('shared_files', ['.env']);
add('shared_dirs', ['storage']);
add('writable_dirs', ['bootstrap/cache', 'storage']);

// Configurazione dell'Host (il tuo server)
host('produzione')
    ->set('hostname', 'IP_DEL_TUO_SERVER_HETZNER') // IP o hostname
    ->set('remote_user', 'deployer') // L'utente creato prima
    ->set('deploy_path', '/var/www/my-app'); // La cartella creata prima

// Task personalizzati se necessario

// Hook per eseguire task specifici
after('deploy:failed', 'deploy:unlock'); // Sblocca il deploy se fallisce
?>

3. Eseguire il deploy e il rollback

Una volta configurata la ricetta, il processo diventa di una semplicità disarmante. Dal tuo terminale locale, nella cartella del progetto, esegui:

dep deploy produzione

Deployer si connetterà al server ed eseguirà tutti i passaggi definiti nella ricetta. Vedrai un output colorato che ti mostra ogni task in esecuzione.

E se qualcosa va storto dopo il rilascio? Niente panico. Esegui semplicemente:

dep rollback produzione

Deployer cambierà istantaneamente il symlink current per farlo puntare al rilascio precedente. Il tuo sito tornerà esattamente com'era prima, in pochi secondi. Se ti senti sopraffatto dalla configurazione iniziale e vuoi un partner che implementi questo flusso di lavoro per te, contattami per una consulenza operativa.

Automatizzare i deploy non è un lusso per grandi aziende. È una pratica fondamentale per qualsiasi attività che dipenda dal proprio software. Elimina il rischio, azzera il downtime e libera te e il tuo team dallo stress dei rilasci, permettendovi di concentrarvi su ciò che conta davvero: costruire valore per i vostri clienti.

Ultima modifica: Mercoledì 11 Giugno 2025, alle 09:08