Autodeploy con GitHub

Questo articolo spiega come fare un deploy automatico su un server di produzione del codice PHP scritto su un server di sviluppo locale utilizzando un repository privato (a pagamento) di GitHub e le chiavi ssh per l’autenticazione.

git è un bellissimo strumento, ma è anche molto complesso, per questa ragione questo articolo è tutto fuorché esaustivo in materia.

Prerequisiti:

  • un account su GitHub;
  • un server di sviluppo basato su Linux;
  • un server di produzione basato su Linux;
  • tanta pazienza per le prime volte.

I test sono stati fatti su Linux, ma esistono porting di git su altre piattaforme o integrazione di git in ambienti di sviluppo.

Innanzi tutto bisogna creare le chiavi ssh e caricarle su GitHub sia nel server di sviluppo sia in quello di produzione. Gli utenti sono quelli sotto il cui ID vengono eseguiti i comandi git: sul server di sviluppo è l’utente utilizzato per modificare i file, mentre su quello di produzione potrebbe essere l’utente sotto cui viene eseguito il server web.

Da qui in avanti il repository di GitHub si chiama testrepo e l’utente testuser. Il server di produzione si chiama acme.it.

Creare un repository testrepo su GitHub ed effettuare le configurazioni del caso.

Creare una directory testrepo sul server di sviluppo e dalla medesima eseguire questi comandi

git init
git remote add upstream git@github.com:testutente/testrepo.git

Se si esegue git remote -v il risultato dovrebbe essere qualcosa tipo

upstream git@github.com:testutente/testrepo.git (fetch)
upstream git@github.com:testutente/testrepo.git (push)

A questo punto si può eseguire la prima sincronizzazione con git fetch upstream che dovrebbe dare qualcosa tipo

remote: Counting objects: 10, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 10 (delta 1), reused 4 (delta 0), pack-reused 0
Unpacking objects: 100% (10/10), done.
From github.com:testutente/testrepo
* [new branch] master -> upstream/master

Quindi scaricare i file con

git pull git@github.com:testutente/testrepo.git

Una volta stabilito il collegamento tra il repository locale e quello online, provare ad aggiungere un file con git add oppure modificare i file scaricati.

Alla fine delle modifiche è ora di fare un commit su GitHub con il comando

git commit -a -m "Messaggio"
git push git@github.com:testutente/testrepo.git

Il messaggio è quello associato al commit, di solito contiene la descrizione delle modifiche effettuate.

Se si accede all’interfaccia web di GitHub si dovrebbero vedere le modifiche.

Quando la parte di caricamento è funzionante si può passare alla configurazione del server di produzione.

Innanzi tutto bisogna creare un file PHP su acme.it che verrà chiamato da GitHub, in questo esempio l’URL è http://acme.it/git-testrepo.php

Il file PHP ha un contenuto simile a questo:

<?php
try {
  $payload = json_decode($_POST['payload']);
}
catch(Exception $e) {
  exit(0);
}
file_put_contents('testrepo.txt', print_r($payload, true));
if ($payload->ref === 'refs/heads/master') {
  $o = array();
  exec('/path/di/testrepo.sh', $o);
  file_put_contents('testrepo_out.txt', print_r($o, true));
}

Il salvataggio dei due file di testo ha uno scopo puramente di debug e può essere disabilitato.

Il file testrepo.sh è questo:

#!/bin/sh
cd /path/di/testrepo
git pull git@github.com:testutente/testrepo.git

Il percorso /path/di/testrepo contiene un clone del repository di GitHub creato come quello del server di test.

Nel file PHP viene verificato solamente un campo dell’oggetto restituito da GitHub; per migliorare la sicurezza sarebbe il caso di testare campi diversi da quello; si può vedere l’elenco dei campi nel file testrepo.txt

Una volta approntata la parte sul server andare sulla pagina di GitHub relativa al repository e cliccare su Settings, su Webhooks & Services e quindi su Add webhook.

Il campo Payload URL è nel nostro caso http://acme.it/git-testrepo.php, come Content type selezionare application/x-www-form-urlencoded. I default degli altri campi possono andare bene, per il loro significato leggere la documentazione.

Premendo Add webhook viene creato il webhook necessario per scatenare l’aggiornamento del server di produzione.

A questo punto se nel server di sviluppo si modificano dei file e si esegue un commit, pochi secondi dopo le modifiche saranno online in produzione.

Se le modifiche vengono eseguite online, dal server di sviluppo è necessario eseguire il comando

git pull git@github.com:testutente/testrepo.git

per aggiornare i file locali con quelli di GitHub.

Il coordinamento tra gli sviluppatori e la gestione degli stessi esula dallo scopo di questo articolo: qui abbiamo visto l’esempio più semplice di un singolo sviluppatore che utilizza GitHub e pubblica su un server di produzione.

git è uno strumento molto complesso con tantissime opzioni e una terminologia che potrebbe non essere familiare. All’inizio sembra tutto confuso, ma dopo poco tempo la nebbia inizia a dissolversi: portate pazienza.

Un particolare ringraziamento ad Alessandro Rubini che la scorsa settimana ha tenuto un corso di git nella sede di comPVter.

Autore: Luigi Rosa

Consulente IT, sviluppatore, SysAdmin, cazzaro, e, ovviamente, geek.

Spazio per un commento