Docker Compose: come orchestrare app di container
Docker Compose contribuisce a semplificare la scalabilità e la distribuzione delle applicazioni in Docker automatizzando la gestione dei contenitori. In questo tutorial, esamineremo approfonditamente la configurazione e l’uso di Docker Compose, per permetterti di sfruttarlo al meglio nel tuo ambiente di produzione.
Che cos’è Docker Compose?
Docker Compose serve a gestire le applicazioni e ad aumentare l’efficienza nello sviluppo dei container. Gli elementi di configurazione vengono impostati in un singolo file YAML, rendendo le applicazioni facili da creare e da scalare. Docker Compose si utilizza soprattutto per configurare un ambiente locale. Può però anche far parte di un flusso di lavoro di Continuous Integration / Continuous Delivery (CI/CD). Chi lavora con Docker Compose può definire una versione specifica dei container per i test o per una fase specifica della pipeline. In questo modo è più facile identificare i problemi e risolvere i bug prima che entrino in produzione.
Docker Compose: requisiti di sistema
Per l’orchestrazione di container sono necessari sia Docker Engine che Docker Compose. Pertanto, occorre che il sistema disponga di uno dei seguenti elementi:
- Docker Engine e Docker Compose: possono essere installati come programmi binari autonomi.
- Docker Desktop: ambiente di sviluppo con interfaccia grafica che include già Docker Engine e Docker Compose.
Scopri come installare Docker Compose su diversi sistemi operativi nei nostri tutorial:
Come utilizzare Docker Compose: procedura guidata
Di seguito, dimostriamo i concetti di Docker Compose con una semplice applicazione web Python nella quale le visite vengono conteggiate con un contatore. Per farlo, ricorriamo al framework Python Flask e al database in-memory Redis. Non occorre installare Python o Redis, dato che vengono forniti come immagini Docker.
Primo passaggio: creare un file di progetto
Apri il terminale e crea una nuova cartella per il progetto.
$ mkdir composedemo
shellPassa quindi alla directory.
$ cd composedemo
shellIn questa cartella crea il file app.py e inserisci il seguente codice:
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I was here {} times.\n'.format(count)
pythonCome nome host utilizziamo “Redis” e la porta predefinita “6379”. Specifichiamo inoltre che la funzione get_hit_count()
deve fare diversi tentativi di connessione al servizio. È una scelta consigliata, perché Redis potrebbe non essere ancora disponibile all’avvio dell’applicazione o potrebbero verificarsi problemi di connessione nel corso dell’esecuzione.
Definisci ora il file requirements.txt con le dipendenze:
flask
redis
plaintextSecondo passaggio: configurare il Dockerfile
Il Dockerfile è usato per l’immagine Docker. Tutte le dipendenze di cui l’applicazione Python ha bisogno sono specificate qui.
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
shellDocker viene così istruito a utilizzare l’immagine di Python 3.7. Impostiamo anche le variabili d’ambiente per il comando flask. Con apk add
installiamo gcc e altre dipendenze. EXPOSE
specifica che il contenitore deve monitorare la porta 5000. Mediante COPY
il contenuto della cartella corrente viene copiato nella cartella di lavoro /code. Come comando predefinito per il contenitore impostiamo flask run
.
Verifica che il file Docker sia stato salvato senza estensione, perché alcuni editor aggiungono automaticamente il suffisso .txt.
Terzo passaggio: generare il file YAML
Configuriamo i servizi “redis” e “web” in docker-compose.yml.
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
yamlIl servizio web utilizza l’immagine creata dal Dockerfile. Associa il contenitore e il computer host alla porta 8000, mentre il server web Flask opera sulla porta 5000. L’immagine di Redis, invece, proviene semplicemente dall’hub ufficiale di Docker.
Quarto passaggio: eseguire l’applicazione per mezzo di Compose
Avvia l’applicazione a partire dalla cartella del progetto.
docker compose up
shellDigita http://localhost:8000 nel browser. Puoi immettere anche http://127.0.0.1:8000.
Dovrebbe apparire il seguente messaggio:
Ricarica la pagina. Ora le visite dovrebbero essere aumentate a 2.
Interrompi l’applicazione in questo modo:
$ docker compose down
shellIn alternativa, usa la combinazione Ctrl
+ C
nel terminale in cui hai avviato l’applicazione.
Quinto passaggio: aggiungere un bind mount
È possibile aggiungere un bind mount al servizio web servendosi di docker-compose.yml.
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
environment:
FLASK_DEBUG: "true"
redis:
image: "redis:alpine"
yamlIn volumes specifichiamo che la cartella del progetto corrente deve essere collegata alla cartella /code all’interno del contenitore. Ciò consente di modificare il codice senza dover ricreare l’immagine. La variabile di ambiente FLASK_DEBUG
indica a flask run
di operare in modalità di sviluppo.
Sesto passaggio: creare ed eseguire una nuova applicazione
Immetti il seguente comando nel terminale per ricostruire il file Compose:
docker compose up
shellSettimo passaggio: aggiornare l’applicazione
Dal momento che stai utilizzando un bind mount per la tua applicazione, puoi modificare il tuo codice e vedere automaticamente le modifiche senza dover ricreare l’immagine.
Scrivi un nuovo test di benvenuto in app.py.
return ‘Hello from Docker! I was here {} times.\n’.format(count)
pythonAggiorna il browser per verificare che le modifiche siano state adottate.
Ottavo passaggio: ulteriori comandi
L’opzione --help
mostra un elenco di comandi disponibili per Docker Compose:
docker compose --help
shellPer eseguire Docker Compose in background, è possibile aggiungere l’argomento -d
:
docker compose up -d
shellCon down
vengono rimossi tutti i contenitori. L’opzione --volumes
cancella anche i volumi utilizzati dal contenitore Redis.
docker compose down --volumes
shellPer imparare a usare Docker puoi avvalerti di alcuni nostri articoli della Digital Guide, quali il tutorial su Docker e la panoramica sui comandi Docker.