Il debug è una fase essenziale nel ciclo di sviluppo del software in quanto consente di individuare e correggere gli errori e i difetti presenti nel codice. Grazie al debugging, gli sviluppatori possono migliorare la qualità del software, rendendolo più affidabile, performante e sicuro. Identificare e risolvere i bug in modo tempestivo non solo ottimizza il processo di sviluppo, ma riduce anche i costi associati alla manutenzione e al supporto post-lancio. Inoltre, il debug favorisce una comprensione più approfondita del funzionamento del software, permettendo agli sviluppatori di acquisire competenze più avanzate e di implementare soluzioni più efficaci in futuro.
Perchè Docker
Come ho già avuto modo di scrivere nel precedente articolo presente su questo blog, Docker permette di creare ambienti coerenti e consistenti nei vari contesti: sviluppo, collaudo e produzione, a prescindere dall’architettura di esecuzione.
Questo strumento è entrato prepotentemente nel ciclo di sviluppo grazie alla sua semplicità di installazione ed utilizzo sia da parte dei professionisti più esperti quanto dei neofiti che si stanno avvicinando alla programmazione.
Anche i DevOps ne decantano le lodi considerando che anche il processo di scaling dei container è stato semplificato, ma non banalizzato, attraverso due distinti ma entrambi validi orchestratori: Swarm e Kubernetes.
Perchè XDebug
PHP è uno dei linguaggi di programmazione server side più usati al mondo, lo dicono le statistiche, non io.
E come ogni buon linguaggio di programmazione che si rispetti, tra croce e delizie, ha i propri tool di debug del codice.
Per progetti semplici o script stand-alone, il classico print_r, var_dump e gli error_log, possono bastare, ma quando si lavora su progetti più complessi, questi comandi non sono più sufficienti. Quindi ci vengono in soccorso i debugger. I due più conosciuti appunto sono XDebug e ZendDebugger.
Per qualche tempo, circa 15 anni fa ho usato Zend Debugger ma, come accade ad ogni professionista, ho scelto XDebug con cui mi sento di più a mio agio in quanto l’ho visto maturare nel tempo e diventare uno strumento sempre più diffuso.
Perchè VSCode
Ho utilizzato per tanti anni Eclipse con numerose estensioni per programmare nei più disparati linguaggi di programmazione, poi sono passato per quasi una decina di anni ad IntelliJ Idea con il quale non mi trovavo affatto male, anzi di tanto in tanto mi manca, infine sono passato a VSCode per allinearmi alle abitudini del team con il quale quotidianamente lavoro in Axio Studio.
Base di partenza
In questo articolo non spiegherò le basi di Docker o della programmazione PHP ma semplicemente come installare, configurare e integrare XDebug con Visual Studio Code. Per farlo si deve partire comunque da una base.
La base di partenza quindi sarà un Dockerfile
già esistente:
FROM php:8.2.10-apache
USER www-data
COPY . .
EXPOSE 80
CMD ["apache2-foreground"]
Per chi ha avuto l’occasione di leggere il mio articolo su Docker comprenderà buona parte dei comandi qui sopra.
In pratica, ho creato un’immagine docker basata su php versione 8.2.10 in esecuzione su Apache copiando tutto il contenuto della directory di contesto nella /var/www/html
del container che espone il servizio httpd sulla porta 80 con diritti dell’utente www-data
del container.
Ecco non potevo essere più sintetico!
Installare XDebug nel Dockerfile
La prima azione da svolgere è aggiungere i comandi opportuni per consentire al’immagine descritta sopra di ospitare anche XDebug.
FROM php:8.2.10-apache
USER root
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
USER www-data
COPY . .
EXPOSE 80
CMD ["apache2-foreground"]
Per installare XDebug, eleviamo i diritti di esecuzione nell’immagine in fase di creazione a livello di utente root
.
Quindi installiamo l’estensione di xdebug tramite PECL (Libreria delle Estensioni per PHP manutenuta dalla Community, è esattamente il significato di PECL).
E la abilitiamo attraverso il comando integrato nell’immagine docker di PHP docker-php-ext-enable
.
Già provando a fare la build del container xdebug sarà disponibile, seppur con una configurazione di default e quasi inutilizzabile.
Per verificare quanto scrivo è sufficiente creare un file php nella root e riportare il codice mostrato di seguito:
<?php
xdebug_info();
Nota che il codice sopra non funzionerà se l’estensione xdebug non è installata.
Altrimenti il risultato sarà una pagina simile all’output del metodo php_info()
per chi ha confidenza con questo linguaggio di programmazione.
Configurare XDebug
La configurazione di xdebug è altrettanto semplice ma richiede degli accorgimenti.
Il primo passo è creare un file di configurazione per XDebug nella root del progetto, accanto al Dockerfile
.
zend_extension=xdebug
[xdebug]
xdebug.remote_enable=on
xdebug.remote_autostart = 1
xdebug.mode=develop,debug
xdebug.client_host=host.docker.internal
xdebug.start_with_request=yes
xdebug.log=/var/www/html/xdebug.log
xdebug.idekey=VSCODE
xdebug.client_port=9003
error_reporting=E_ALL
Spiegazione delle singole chiavi
Se sei un appassionato di Stack Overflow e del Copia & Incolla, puoi saltare questo paragrafo, altrimenti, fidati, è tutta conoscenza che accrescerà il tuo bagaglio di competenze professionali.
zend_extension=xdebug
Abilita l’estensione xdebug. Per chi si domandasse cosa sia quello zend in testa alla riga, riduco il concetto al solo far presente che Zend è la società che ha inventato PHP, quando ancora significava Personal Home Page.
xdebug.remote_enable=on
Questa chiave è fondamentale, quando si tira su un’immagine Docker è come se il codice fosse eseguito nel Cloud, quindi in remoto. Solo se impostato a on
, potrà permettere il debug da remoto.
xdebug.remote_autostart = 1
Grazie a questo comando il debugger si attiverà ad ogni richiesta ricevuta dal nostro container.
Nota importante: per questioni di performance, questo valore va impostato a 0
in ambiente di stage. Inutile evidenziare che in ambiente di produzione XDebug non deve essere installato.
xdebug.mode=develop,debug
È la modalità con cui si vuole attivare xdebug, ci sono diverse modalità, tutte combinabili tra di loro.
La configurazione proposta permette il debug passo-passo ed una serie di agevolazioni per gli sviluppatori con dei messaggi di errore più ricchi di dettagli.
xdebug.client_host=host.docker.internal
È l’indirizzo IP o il nome host dal quale può essere stabilita la connessione, se non si sa bene come cambiarlo ed il tutto deve funzionare su una macchina locale, lasciarlo esattamente con questo valore.
xdebug.start_with_request=yes
Se impostato a yes, il processo xdebug parte prima che la prima riga di codice PHP venga eseguita.
xdebug.log=/var/www/html/xdebug.log
Tutti i log di xdebug saranno prodotti nel file menzionato, per lo scopo di questo articolo va bene che venga generato nella root applicativa, solitamente va messo in una directory temporanea.
xdebug.idekey=VSCODE
Eseguendo il debug da VSCode, come obiettivo di questo articolo, è necessario che questo valore sia lasciato intatto.
xdebug.client_port=9003
Per una configurazione ancora più spinta si può consultare la documentazione ufficiale molto ricca e altrettanto chiara.
Applicazione della configurazione di XDebug
Aggiungiamo al Dockerfile
il comando per copiare il file di configurazione nel percorso in cui sono applicate anche tutte le altre configurazioni di PHP.
Ed esponiamo la porta 9000.
FROM php:8.2.10-apache
USER root
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
COPY ./xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
USER www-data
COPY . .
EXPOSE 80, 9000
CMD ["apache2-foreground"]
Possiamo a questo punto aprire VSCode e configurare l’ambiente per cominciare con il debug del codice.
Configurare VSCode
Dalla barra degli strumenti principale di VSCode bisogna accedere alla sezione di debug ed aggiungere una nuova configurazione.
Sarà aperto un file JSON con le varie configurazioni.
Nel blocco configurations
innestare il seguente codice:
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
}
},
Premere il tasto F5 e l’editor è pronto per una completa sessione di debug, dall’inizio alla fine!
Conclusioni
Con l’installazione di XDebug in un container Docker e l’integrazione con VS Code, abbiamo esplorato un approccio potente ed efficiente per eseguire il debug del codice PHP. Questa combinazione non solo ottimizza il flusso di lavoro degli sviluppatori, ma consente anche un ambiente di sviluppo flessibile e replicabile.
Ora che sono stati coperti i passaggi fondamentali per configurare questo setup, mi piacerebbe conoscere le vostre esperienze e opinioni.
Quali sono le vostre migliori pratiche per il debugging in ambienti containerizzati?
Avete riscontrato sfide specifiche e come le avete superate?
Condividete i vostri suggerimenti e trucchi nei commenti, così possiamo continuare a migliorare e innovare insieme.