Oggi vorrei spendere due parole a proposito di qualcosa a cui tengo molto: l’ambiente di sviluppo in cui lavoriamo ai nostri progetti. Sembra una cosa scontata ma non è assolutamente così: non avete idea di quante app vedo, ancora oggi, costruite in ambienti che non aiutano minimamente lo sviluppatore… anzi!
Qualche giorno fa vengo a sapere che hanno rilasciato una piccola perla: Laravel Sail, come package ufficiale! Sail configurare, con uno sforzo minimo, un ambiente di sviluppo chiavi in mano, dockerizzato, personalizzabile ma comunque facilissimo da usare. Il tutto con uno strumento da linea di comando a corredo.
(Sail prende spunto da una mia vecchia conoscenza: Laravel Vessel.)
Oggi vi dirò:
- perché bisognerebbe usare sempre un buon ambiente di sviluppo, magari dockerizzato;
- come installare ed usare Laravel Sail con un progetto Laravel;
Perché l’ambiente di lavoro (con Docker) è importante?
Non partirò con la solita filippica accademica sugli ambienti di sviluppo, quindi mi limiterò ad un paio di considerazioni sul perché è molto meglio usarne uno ben fatto (e magari con il supporto di Docker).
- Installare il software in locale è scomodo e noioso: onestamente trovo una rottura di scatole incredibile pensare di dover installare, per ogni progetto su cui lavoro, tutto il software che mi serve. La versione giusta di PHP, MySQL, Redis e bla bla bla… noioso. Fossero anche quattro ore, sono quattro ore potenzialmente sprecate, se ho un’alternativa migliore. E in effetti, questa alternativa c’è;
- Installare il software in locale porta quasi sempre a problemi di compatibilità: il grande classico. In locale ho Ubuntu, e poi su staging e produzione no. O magari un’altra versione. Qualsiasi piccola variazione tra gli ambienti può potenzialmente portare a problemi, per cui… meglio standardizzare tutto, no?
Bonus: ultimamente uso molto Kubernetes per alcune mie applicazioni Laravel. Un ambiente di lavoro “standard” basato su Docker mi è utilissimo, perché ho già un punto di partenza su cui lavorare per creare un’immagine per la mia app.
Vabbè basta, ora vediamo come…
Installare Laravel Sail
Installare Laravel Sail è semplicissimo e, soprattutto, (questa cosa mi piace tanto) si può agevolmente aggiungerlo ad un progetto già esistente.
Non bisogna fare altro, infatti, che aggiungerlo come dipendenza con
1 |
composer require laravel/sail --dev |
e via. A quel punto, basterà eseguire
1 |
php artisan sail:install |
che si occuperà di preparare tutto il necessario: copia del file docker-compose.yml nella root del nostro progetto e sostituzione delle variabili nel file .env. Ecco, queste sono quelle piccole cose che amo, perché mi sollevano da task ripetitivi e noiosi… soprattutto quando lavoro con tanti progetti.
Lavorare con Laravel Sail
A questo punto, Sail può essere usato digitando
1 |
vendor/bin/sail |
nel terminale. Può essere una buona idea configurare un alias, come
1 |
alias sail='bash vendor/bin/sail' |
per evitare di dover scrivere tutto il percorso tutte le volte.
Fatto? Bene. Non rimane che avviare Laravel Sail con
1 |
sail up |
che provvederà a preparare tutto il necessario. Dopo pochi secondi (qualche minuto se è il primo avvio, dato che Docker dovrà scaricare le immagini necessarie) sarà possibile iniziare a lavorarci.
Eseguire i Comandi in Laravel Sail
Ora, non è mia intenzione fare un lungo elenco dei comandi con le relative banali spiegazioni. Siete intelligenti, non ne avete bisogno, ed è scritto tutto magnificamente qui.
Quello che dovete sapere e tenere a mente (specialmente se siete “nuovi” su Docker e/o Laravel Sail) è che state lavorando con un ambiente di sviluppo “dockerizzato” e non più con qualcosa di installato direttamente sulla vostra macchina locale.
Quindi, se prima eseguivate:
1 |
php artisan queue:work |
adesso dovrete usare:
1 |
sail artisan queue:work |
Ma… cosa significa? Andiamo a spulciare il codice di Sail e vediamo a cosa corrisponde il comando “sail artisan”:
1 2 3 4 |
docker-compose exec \ -u sail \ "$APP_SERVICE" \ php artisan "$@" |
In poche parole, stiamo chiedendo a docker…
- di eseguire (prima riga, comando exec);
- nel container dell’app (terza riga);
- il comando “php artisan” (quarta riga);
- usando l’utente “sail” (seconda riga);
Il nostro ambiente di lavoro locale non esiste più. Esattamente come accade per gli altri comandi di Sail, che trovate nella documentazione, viene tutto eseguito tramite Docker e Docker Compose.
La trovo una cosa meravigliosa. Perché a parte i vantaggi di cui ho già parlato prima, significa che non devo più installare niente sulla mia macchina in locale. Avrò bisogno SOLO di Docker e Docker Compose.
Vediamo che c’è Sotto…
Prima di concludere questo articolo vediamo cosa c’è nel file docker-compose.yml che viene installato con Laravel Sail.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# For more information: https://laravel.com/docs/sail version: '3' services: laravel.test: build: context: ./vendor/laravel/sail/runtimes/8.0 dockerfile: Dockerfile args: WWWGROUP: '${WWWGROUP}' image: sail-8.0/app ports: - '${APP_PORT:-80}:80' environment: WWWUSER: '${WWWUSER}' LARAVEL_SAIL: 1 volumes: - '.:/var/www/html' networks: - sail depends_on: - mysql - redis # - selenium # selenium: # image: 'selenium/standalone-chrome' # volumes: # - '/dev/shm:/dev/shm' # networks: # - sail mysql: image: 'mysql:8.0' ports: - '${FORWARD_DB_PORT:-3306}:3306' environment: MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' MYSQL_DATABASE: '${DB_DATABASE}' MYSQL_USER: '${DB_USERNAME}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' volumes: - 'sailmysql:/var/lib/mysql' networks: - sail redis: image: 'redis:alpine' ports: - '${FORWARD_REDIS_PORT:-6379}:6379' volumes: - 'sailredis:/data' networks: - sail # memcached: # image: 'memcached:alpine' # ports: # - '11211:11211' # networks: # - sail mailhog: image: 'mailhog/mailhog:latest' ports: - 1025:1025 - 8025:8025 networks: - sail networks: sail: driver: bridge volumes: sailmysql: driver: local sailredis: driver: local |
Anche qui niente pippotti inutili, solo qualche osservazione:
- rispetto a tanti altri ambienti che ho visto in giro, c’è il minimo indispensabile. Personalmente avrei tenuto fuori Memcached (lasciando solo Redis come default) ma non è un gran problema;
- è possibile notare (commentato) anche un container molto comodo per eseguire i test di Laravel Dusk. Se non lo conoscete, si tratta di un’API comodissima per scrivere dei test end2end per la propria applicazione. Spero di scriverne presto, in caso aggiornerò questo articolo con un link;
- mi piace tantissimo l’uso del numero preciso di versione. Un sacco di progetti simili in passato usavano un generico “latest” e questo può portare dei problemi, soprattutto quando si è alle prime armi. Meglio decidere delle versioni specifiche e lavorare con quelle da subito;
Concludendo…
Vi consiglio di provarlo il prima possibile. Si tratta di un package ufficiale, quindi ci sono discrete possibilità che verrà supportato per molto tempo, anche perché non fa niente di complesso, è solo un “facilitatore”. In piena filosofia Laravel.
Iniziate DA OGGI a migliorare gli ambienti di sviluppo dei vostri progetti. Io personalmente ho fatto così:
- ho provato Laravel Sail su un nuovo progetto “pulito” creato ad hoc, per familiarizzarci e provare i vari comandi;
- come seconda prova, ho preso un progetto in stato più avanzato e ci ho messo sotto Sail, prendendo come riferimenti per il docker-compose.yml le varie versioni dei software in produzione (PHP, Redis, MySQL) per avere tutto allineato;
Ah, un ultimo consiglio! Per poter creare il progetto la prima volta avrai bisogno comunque di PHP installato in locale. Ora, per vari motivi può essere una buona idea avere a disposizione un tool che ti permette di avere diverse versioni di PHP installate contemporaneamente, non si può mai sapere. Io uso asdf (e relativo plugin PHP).
Bene, per oggi è tutto su Laravel Sail! Fatemi sapere nei commenti se l’avete provato, se volete provarlo o se avete avuto qualche problema!