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
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:
docker
stesso edocker-compose
, che è un'utilità che ci consente di organizzare facilmente applicazioni multi-container utilizzandoyaml
file 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
docker
service 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-p
opzione dellamkdir
comando:$ mkdir -p linuxconfig/DocumentRoot
All'interno di
linuxconfig
directory, 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
-apache
suffisso, 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'
image
l'istruzione viene utilizzata per specificare su quale immagine deve essere basato il contenitore, in questo casophp:7.3-apache
.Le
ports
l'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 porta80
sull'host per portare80
sul 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
./DocumentRoot
la directory ospiterà i file del sito:verrà montata sul/var/www/html
directory 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 up
viene lanciato il comando:in tal caso sarà di proprietà di root se non diversamente specificato.All'interno di
DocumentRoot
directory 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
-d
opzione che abbiamo fornito adocker-compose
comando. Con il progetto attivo e funzionante, se andiamo alocalhost
con il nostro browser, dovremmo vedere la seguente pagina:
La pagina phpinfoPer interrompere il progetto, dalla directory che ospita
docker-compose.yml
file, 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
mariadb
e con l'image
istruzione che abbiamo specificato vogliamo usare il10.5.2
versione 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/mysql
all'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
volumes
principali stanza del file di configurazione e può essere referenziato daivolumes
sottosezione 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'
environment
sezione 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
phpmyadmin
e configurato per utilizzare phpmyadmin/phpmyadmin immagine da DockerHub. Abbiamo anche usato ilinks
parola 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 ildb
name, quindi dobbiamo creare un alias con lo stesso nome per il nostro servizio mariadb. Questo è esattamente ciò chelinks
viene utilizzato per:definire alias extra per raggiungere un servizio da un altro.All'interno della definizione del servizio abbiamo anche mappato la porta
8081
della nostra macchina host, per portare80
all'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
testdb
il 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.yml
file, modifichiamo la definizione delphp-httpd
servizio. 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
build
nella sezione definiamo le configurazioni che vengono applicate in fase di compilazione. In questo caso, abbiamo utilizzatocontext
per 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.