La pila della LAMPADA
LAMP è lo stack software su cui probabilmente gira la maggior parte dei siti web. Linux rappresenta la base dello stack e l'implementazione tradizionale include Apache come server Web, database MySQL e PHP come linguaggio di programmazione lato server. Ci sono, tuttavia, molte varianti possibili:MariaDB, ad esempio, viene spesso utilizzato al posto di MySQL, di cui è un fork, e altri linguaggi di programmazione, come Python o Perl possono essere utilizzati al posto di PHP. In questo articolo vedremo come implementare uno stack LAMP di base utilizzando la finestra mobile e l'utilità di composizione mobile.
In questo tutorial imparerai:
- Come installare docker e docker-compose su Ubuntu 20.04
 - Come definire servizi e volumi utilizzando docker-compose
 - Come mappare le porte host alle porte container nel file di configurazione di composizione mobile
 - Come usare i mount di bind e i volumi denominati
 - Come creare un progetto con docker-compose
 
 Come creare uno stack LAMP basato su una finestra mobile utilizzando la finestra mobile su Ubuntu 20.04 
Requisiti e convenzioni software utilizzati
| Categoria | Requisiti, convenzioni o versione del software utilizzata | 
|---|---|
| Sistema | Installato Ubuntu 20.04 o aggiornato Ubuntu a 20.04 Focal Fossa | 
| Software | docker, docker-componi | 
| Altro | Autorizzazioni di root per creare contenitori docker e avviare il servizio docker | 
| Convenzioni | # – richiede che i comandi linux dati vengano eseguiti con i privilegi di root direttamente come utente root o usando sudo comando$ – richiede che i comandi linux dati vengano eseguiti come un normale utente non privilegiato  |  
-  
Installazione dei pacchetti e avvio del servizio Docker
Per creare uno stack LAMP basato su Docker su Ubuntu 20.04 Focal Fossa, la prima cosa che dobbiamo fare è installare il software di cui abbiamo bisogno:
dockerstesso edocker-compose, che è un'utilità che ci consente di organizzare facilmente applicazioni multi-container utilizzandoyamlfile di configurazione. Entrambi i pacchetti sono disponibili nei repository ufficiali di Ubuntu. Possiamo installarli tramiteapt:$ sudo apt install docker docker-compose
Dopo aver eseguito l'installazione, dobbiamo avviare la
dockerservice e abilitarlo all'avvio. Possiamo eseguire entrambe le operazioni con un unico comando:$ systemctl enable --now docker
 -  
Impostazione del progetto
Il primo passo del nostro percorso consiste nella creazione della directory che utilizzeremo come root del nostro progetto. Per il bene di questo articolo lo chiameremo
linuxconfig. All'interno di questa directory ne creeremo un'altra,DocumentRoot, che ospiterà i file del nostro sito web. Possiamo creare entrambe le directory contemporaneamente usando il-popzione dellamkdircomando:$ mkdir -p linuxconfig/DocumentRoot
All'interno di
linuxconfigdirectory, definiamo la configurazione docker-compose per il nostro progetto all'interno di un file yaml, che per impostazione predefinita dovrebbe essere chiamatodocker-compose.yml. Ci sono tre stanze principali che possiamo usare nel file di configurazione:servizi , volumi e reti .Ogni sezione viene utilizzata per configurare l'aspetto corrispondente di un progetto. In questo tutorial useremo solo i primi due. Implementeremo i componenti dello stack LAMP come servizi all'interno dei loro contenitori separati.
I container creati con docker-compose saranno membri della stessa rete e quindi potranno dialogare tra loro per impostazione predefinita. Nella rete, ogni container potrà fare riferimento agli altri con un hostname identico al proprio nome, oppure con il nome utilizzato per definire il servizio implementato dal container.
Per impostazione predefinita i contenitori verranno denominati utilizzando il nome della directory contenente il file di configurazione come prefisso. In questo caso, ad esempio, il contenitore utilizzato per un servizio chiamato php-httpd , sarà denominato linuxconfig_php-httpd_1 .
 -  
Definizione del servizio php + httpd
Il primo servizio che definiremo nel file di configurazione includerà PHP come modulo del server web Apache. Utilizzeremo una delle immagini PHP ufficiali disponibili su dockerhub come base per il nostro container, in particolare quello con il
-apachesuffisso, che fornisce la configurazione che abbiamo menzionato sopra. Iniziamo a scrivere la nostra configurazione:version: '3.7' services: php-httpd: image: php:7.3-apache ports: - 80:80 volumes: - "./DocumentRoot:/var/www/html"La prima cosa che abbiamo specificato nel file di configurazione è
version. Con questa istruzione dichiariamo quale versione specifica del file di composizione utilizzeremo. Al momento della scrittura, versione3.7è l'ultimo e consigliato. - Dopo aver dichiarato la versione del file di composizione, abbiamo iniziato a scrivere il servizio  stanza; al suo interno definiamo i servizi che andranno a comporre il nostro stack LAMP. Abbiamo chiamato il primo servizio 
php-httpd. Il nome del servizio è del tutto arbitrario, ma è sempre buona abitudine utilizzarne uno significativo nel contesto del progetto.L'
imagel'istruzione viene utilizzata per specificare su quale immagine deve essere basato il contenitore, in questo casophp:7.3-apache.Le
portsl'istruzione viene utilizzata per esporre le porte sul contenitore e per creare una mappa tra le porte host e le porte del contenitore. Tale mappa è definita separando le porte con un:. Sul lato sinistro specifichiamo la porta host e, a destra, la porta all'interno del container su cui dovrebbe essere mappata. In questo caso abbiamo mappato la porta80sull'host per portare80sul contenitore, poiché è la porta predefinita utilizzata dal server Web Apache.L'ultima istruzione che abbiamo usato è
volumes:con esso possiamo specificare una mappatura tra un volume denominato o un percorso (relativo o assoluto) sul sistema host a un percorso sul contenitore, su cui verrà montato.Nella nostra configurazione, il
./DocumentRootla directory ospiterà i file del sito:verrà montata sul/var/www/htmldirectory all'interno del contenitore, perché quest'ultimo è la radice del documento utilizzata dall'host virtuale Apache predefinito. Tale configurazione è chiamata bind mount ed è particolarmente utile durante lo sviluppo perché le modifiche che apportiamo ai file di progetto si riflettono immediatamente all'interno del contenitore. Lo svantaggio di questa configurazione è che stabilisce una dipendenza tra il contenitore e la struttura del file della macchina host, diminuendo uno dei principali vantaggi dell'utilizzo di Docker:la portabilità.La directory da montare all'interno del contenitore verrà creata automaticamente se non esiste quando il
docker-compose upviene lanciato il comando:in tal caso sarà di proprietà di root se non diversamente specificato.All'interno di
DocumentRootdirectory ora possiamo creare un file di indice e provare a costruire il nostro progetto per verificare che l'installazione funzioni:$ echo "<?php phpinfo();" > DocumentRoot/index.php $ sudo docker-compose up -d
Dopo aver eseguito il comando, le immagini docker necessarie verranno scaricate da dockerhub e i container verranno creati con le impostazioni che abbiamo fornito ed eseguiti in background (non bloccheranno il terminale), a causa del
-dopzione che abbiamo fornito adocker-composecomando. Con il progetto attivo e funzionante, se andiamo alocalhostcon il nostro browser, dovremmo vedere la seguente pagina:

La pagina phpinfoPer interrompere il progetto, dalla directory che ospita
docker-compose.ymlfile, possiamo eseguire:$ sudo docker-compose stop
Definizione del servizio MariaDB
Una parte essenziale dello stack LAMP è il livello del database. Nella nostra configurazione utilizzeremo MariaDB e la sua immagine docker ufficiale disponibile su dockerhub:
version: '3.7' services: php-httpd: image: php:7.3-apache ports: - 80:80 volumes: - "./DocumentRoot:/var/www/html" mariadb: image: mariadb:10.5.2 volumes: - mariadb-volume:/var/lib/mysql environment: TZ: "Europe/Rome" MYSQL_ALLOW_EMPTY_PASSWORD: "no" MYSQL_ROOT_PASSWORD: "rootpwd" MYSQL_USER: 'testuser' MYSQL_PASSWORD: 'testpassword' MYSQL_DATABASE: 'testdb' volumes: mariadb-volume:All'interno dei servizi stanza, abbiamo definito un altro servizio e lo abbiamo chiamato
mariadbe con l'imageistruzione che abbiamo specificato vogliamo usare il10.5.2versione dell'immagine ufficiale.Nella precedente definizione del servizio abbiamo usato un montaggio bind. Questa volta, invece, abbiamo utilizzato una finestra mobile adeguata volume denominato , da montare su
/var/lib/mysqlall'interno del contenitore (è la directory di dati predefinita utilizzata da MariaDB). A differenza di un montaggio vincolato, i volumi denominati non creano dipendenze del contenitore sulla struttura del filesystem host. Completamente gestiti da Docker, sono il metodo consigliato per la persistenza dei dati che altrimenti andrebbero persi con la distruzione dei container.I volumi con nome possono essere definiti nei
volumesprincipali stanza del file di configurazione e può essere referenziato daivolumessottosezione di ciascun servizio definito. In questo caso abbiamo chiamato il nostro volumemariadb-volume.Come passaggio successivo abbiamo definito il valore di alcune variabili d'ambiente utilizzato per influenzare il comportamento del contenitore. Le variabili d'ambiente sono definite nell'
environmentsezione di una definizione di servizio. Le variabili che abbiamo definito in questo caso hanno il seguente effetto:Variabile Effetto TZ Imposta il fuso orario utilizzato dal server MariaDB MYSQL_ALLOW_EMPTY_PASSWORD Abilita o disabilita l'uso della password vuota per l'utente root db MYSQL_ROOT_PASSWORD Questa è una variabile obbligatoria e viene utilizzata per impostare la password dell'utente root db MYSQL_DATABASE Utilizzato facoltativamente per specificare il nome del database da creare all'avvio dell'immagine MYSQL_USER Utilizzato facoltativamente per specificare il nome di un utente che verrà creato con i permessi di superutente per il database specificato con MYSQL_DATABASE MYSQL_PASSWORD Utilizzato per specificare la password per l'utente creato con il nome fornito da MYSQL_USER A questo punto dovremmo avere un web server funzionante in grado di lavorare con PHP e un database per memorizzare i nostri dati.
Bonus – phpMyAdmin
Il nostro stack LAMP di base ora dovrebbe essere completo. Come bonus, potremmo voler aggiungere phpMyAdmin ad esso, al fine di controllare facilmente il nostro database MariaDB da un'interfaccia web intuitiva. Aggiungiamo la relativa definizione del servizio alla nostra configurazione di composizione mobile:
version: '3.7' services: php-httpd: image: php:7.3-apache ports: - 80:80 volumes: - "./DocumentRoot:/var/www/html" mariadb: image: mariadb:10.5.2 volumes: - mariadb-volume:/var/lib/mysql environment: TZ: "Europe/Rome" MYSQL_ALLOW_EMPTY_PASSWORD: "no" MYSQL_ROOT_PASSWORD: "rootpwd" MYSQL_USER: 'testuser' MYSQL_PASSWORD: 'testpassword' MYSQL_DATABASE: 'testdb' phpmyadmin: image: phpmyadmin/phpmyadmin links: - 'mariadb:db' ports: - 8081:80 volumes: mariadb-volume:Abbiamo chiamato il nostro servizio
phpmyadmine configurato per utilizzare phpmyadmin/phpmyadmin immagine da DockerHub. Abbiamo anche usato ilinksparola chiave per la prima volta; a cosa serve? Come già sappiamo, per impostazione predefinita e senza particolari configurazioni necessarie, tutti i contenitori creati nella stessa configurazione di composizione mobile sono in grado di dialogare tra loro. L'immagine phpMyAdmin è configurata per fare riferimento a un contenitore di database in esecuzione tramite ildbname, quindi dobbiamo creare un alias con lo stesso nome per il nostro servizio mariadb. Questo è esattamente ciò chelinksviene utilizzato per:definire alias extra per raggiungere un servizio da un altro.All'interno della definizione del servizio abbiamo anche mappato la porta
8081della nostra macchina host, per portare80all'interno del contenitore (la porta 80 è già mappata sulla stessa porta all'interno del contenitore php-httpd). L'interfaccia di phpMyAdmin sarà quindi raggiungibile da localhost:8081 indirizzo. Ricostruiamo il nostro progetto e verifichiamolo:$ sudo docker-compose up -d --build

La pagina di accesso di PhpMyAdminPossiamo accedere con le credenziali che abbiamo definito per il nostro servizio di database e verificare che il
testdbil database è stato creato:

Homepage di PhpMyAdminUtilizzo di un'immagine personalizzata per un servizio
Negli esempi sopra abbiamo sempre usato le immagini vanilla nella definizione dei nostri servizi. Ci sono casi in cui potremmo voler utilizzare immagini docker personalizzate basate su di esse. Ad esempio, supponiamo di voler costruire il servizio php-httpd, ma di includere un'estensione php aggiuntiva:come possiamo farlo? Sulla radice del progetto, definiamo una nuova directory, e per comodità denominiamola dopo il servizio:
$ mkdir php-httpd
All'interno di questa directory creiamo un Dockerfile, utilizzato per estendere l'immagine di base, con il seguente contenuto:
FROM php:7.3-apache LABEL maintainer="[email protected]" RUN apt-get update && apt-get install -y libmcrypt-dev \ && pecl install mcrypt-1.0.2 \ && docker-php-ext-enable mcrypt
Torna nel nostro
docker-compose.ymlfile, modifichiamo la definizione delphp-httpdservizio. Non possiamo fare riferimento all'immagine direttamente come abbiamo fatto prima. Invece, specifichiamo la directory contenente il nostro Dockerfile personalizzato come contesto di compilazione:version: '3.7' services: php-httpd: build: context: ./php-httpd ports: - 80:80 volumes: - "./DocumentRoot:/var/www/html" [...]Nella
buildnella sezione definiamo le configurazioni che vengono applicate in fase di compilazione. In questo caso, abbiamo utilizzatocontextper fare riferimento alla directory contenente il Dockerfile:detta directory viene utilizzata come contesto di compilazione e il suo contenuto viene inviato al demone Docker quando viene compilato il contenitore. Per applicare la modifica dobbiamo ricostruire il progetto.A proposito, per saperne di più sulle estensioni aggiuntive nell'immagine della finestra mobile php, puoi dare un'occhiata alla documentazione ufficiale, e in particolare alle estensioni PECL sezione.
Conclusioni
In questo tutorial abbiamo visto come costruire uno stack LAMP di base utilizzando la tecnologia container con Docker e docker-compose. Abbiamo visto come definire i vari servizi all'interno del file di configurazione docker-compose.yml e come configurare bind mount, volumi denominati e mappatura delle porte host-container. Abbiamo anche visto come utilizzare le immagini personalizzate. Puoi dare un'occhiata al riferimento di composizione mobile per l'elenco dettagliato delle istruzioni che possono essere utilizzate all'interno del file di configurazione di composizione mobile.