Ogni pochi anni, nell'industria dello sviluppo software, si verifica un cambiamento di paradigma. Uno di questi fenomeni è l'aumento dell'interesse per il concetto di microservizi. Sebbene i microservizi non siano una tecnologia nuovissima, la loro popolarità è letteralmente esplosa solo di recente.
I grandi servizi monolitici vengono oggi sostituiti da microservizi autonomi e indipendenti. Un microservizio può essere considerato come un'applicazione che serve un unico scopo specifico. Ad esempio, può essere un database relazionale, un'applicazione Express, o un servizio Solr.
Oggi è difficile immaginare lo sviluppo di un nuovo sistema software senza l'uso di microservizi. Questa situazione, a sua volta, ci porta alla piattaforma Docker.
Docker
Piattaforma , nella progettazione e distribuzione dei microservizi, è diventata praticamente uno standard industriale. Sul sito del progetto si può scoprire che Docker è l'unica piattaforma di containerizzazione indipendente che permette alle organizzazioni di creare facilmente qualsiasi applicazione, oltre a distribuirla e avviarla in qualsiasi ambiente, dai cloud ibridi ai sistemi edge.
Docker Compose
Tecnologia è progettato per configurare applicazioni multi-contenitore. In un progetto Docker Compose possono essere inclusi tanti contenitori Docker quanti richiesti dal creatore di questo progetto.
Quando si lavora con Docker Compose, viene utilizzato un file YAML per configurare i servizi dell'applicazione e organizzare la loro interazione l'uno con l'altro. Docker Compose è quindi uno strumento per descrivere e avviare applicazioni Docker multi-contenitore.

Due contenitori che operano su un sistema host
GNU Make
Programma make, è fondamentalmente uno strumento per automatizzare la compilazione di programmi e librerie a partire dal codice sorgente. In generale, si può dire che make si applica a qualsiasi processo che coinvolga l'esecuzione di comandi arbitrari per trasformare materiali di input in una forma o in un risultato finale. Nel nostro caso, i comandi docker-compose verranno trasformati in obiettivi astratti ().
Per indicare al programma make cosa vogliamo da esso, avremo bisogno di un file Makefile.
Nel nostro Makefile conterranno comandi normali docker e docker-compose, destinati a risolvere molteplici compiti. In particolare, si tratta dell'assemblaggio di un contenitore, del suo avvio, arresto, riavvio, dell'organizzazione dell'accesso dell'utente al contenitore, della gestione dei log del contenitore e della risoluzione di altre problematiche simili.
Esempi tipici di utilizzo di Docker Compose
Immaginiamo un'applicazione web comune con i seguenti componenti:
- Database TimescaleDB (Postgres).
- Applicazione Express.js.
- Ping (semplicemente un contenitore che non fa nulla di speciale).
Questa applicazione avrà bisogno di 3 contenitori Docker e di un file docker-compose, contenente istruzioni per gestire questi contenitori. Ognuno dei contenitori avrà punti di interazione diversi. Ad esempio, con il contenitore timescale si potrà interagire come si fa con i database. In particolare, permette di eseguire le seguenti operazioni:
- Accesso alla shell di Postgres.
- Importazione ed esportazione di tabelle.
- Creazione
pg_dumptabelle o database.
Il contenitore per l'applicazione Express.js, expressjs, può avere le seguenti funzionalità:
- Fornitura di dati freschi dal registro di sistema.
- Accesso alla shell per eseguire determinati comandi.
Interazione con altri contenitori.
Dopo aver configurato la connessione tra i container utilizzando Docker Compose, è giunto il momento di stabilire l'interazione con questi container. All'interno del sistema Docker Compose è disponibile un comando docker-compose, che supporta l'opzione -f, che consente di passare al sistema un file docker-compose.yml.
Sfruttando le funzionalità di questa opzione, è possibile limitare l'interazione con il sistema solo ai container menzionati nel file docker-compose.yml.
Esaminiamo come appare l'interazione con i container utilizzando i comandi docker-compose. Se immaginiamo di dover entrare nella shell psql, i comandi corrispondenti possono apparire così:
docker-compose -f docker-compose.yml exec timescale psql -Upostgres Lo stesso comando, per cui non si utilizza docker-compose, e docker, può apparire così:
docker exec -it edp_timescale_1 psql -Upostgres Si noti che in questi casi è sempre preferibile utilizzare non il comando docker, ma il comando docker-compose, poiché questo evita di dover ricordare i nomi dei container.
Entrambi i comandi sopra riportati non sono così complessi. Ma se utilizzassimo un "wrapper" sotto forma di Makefile, che ci fornirebbe un'interfaccia tramite comandi semplici e che richiamerebbe autonomamente comandi lunghi simili, allora si potrebbero ottenere gli stessi risultati in questo modo:
make db-shell È evidente che l'uso Makefile semplifica notevolmente il lavoro con i contenitori!
Esempio pratico
Sulla base dello schema di progetto considerato sopra, creeremo il seguente file docker-compose.yml:
version: '3.3'
services:
api:
build: .
image: mywebimage:0.0.1
ports:
- 8080:8080
volumes:
- /app/node_modules/
depends_on:
- timescale
command: npm run dev
networks:
- webappnetwork
timescale:
image: timescale/timescaledb-postgis:latest-pg11
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
command: ["postgres", "-c", "log_statement=all", "-c", "log_destination=stderr"]
volumes:
- ./create_schema.sql:/docker-entrypoint-initdb.d/create_schema.sql
networks:
- webappnetwork
ping:
image: willfarrell/ping
environment:
HOSTNAME: "localhost"
TIMEOUT: 300
networks:
webappnetwork:
driver: bridge Per gestire la configurazione di Docker Compose e interagire con i contenitori che essa descrive, creeremo il seguente file Makefile:
THIS_FILE := $(lastword $(MAKEFILE_LIST))
.PHONY: help build up start down destroy stop restart logs logs-api ps login-timescale login-api db-shell
help:
make -pRrq -f $(THIS_FILE) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
build:
docker-compose -f docker-compose.yml build $(c)
up:
docker-compose -f docker-compose.yml up -d $(c)
start:
docker-compose -f docker-compose.yml start $(c)
down:
docker-compose -f docker-compose.yml down $(c)
destroy:
docker-compose -f docker-compose.yml down -v $(c)
stop:
docker-compose -f docker-compose.yml stop $(c)
restart:
docker-compose -f docker-compose.yml stop $(c)
docker-compose -f docker-compose.yml up -d $(c)
logs:
docker-compose -f docker-compose.yml logs --tail=100 -f $(c)
logs-api:
docker-compose -f docker-compose.yml logs --tail=100 -f api
ps:
docker-compose -f docker-compose.yml ps
login-timescale:
docker-compose -f docker-compose.yml exec timescale /bin/bash
login-api:
docker-compose -f docker-compose.yml exec api /bin/bash
db-shell:
docker-compose -f docker-compose.yml exec timescale psql -Upostgres La maggior parte dei comandi descritti qui si applica a tutti i contenitori, ma l'utilizzo dell'opzione c= consente di limitare il campo di applicazione del comando a un solo contenitore.
Una volta che Makefile è pronto, può essere utilizzato così:
make help— per ottenere un elenco di tutti i comandi disponibili permake.

Guida ai comandi disponibili
make build— creazione dell'immagine daDockerfile. Nel nostro esempio abbiamo utilizzato immagini esistentitimescaleeping. Ma l'immagineapiche vogliamo creare localmente. Esattamente questo sarà fatto dopo aver eseguito questo comando.

Creazione del container Docker
make start— avvio di tutti i container. Per avviare solo un container, è possibile utilizzare un comando del tipomake start c=timescale.

Avvio del container timescale

Avvio del container ping
make login-timescale— accesso a una sessione bash del containertimescale.

Avvio di bash nel container timescale
make db-shell— accesso apsqlin un containertimescaleper eseguire query SQL sul database.

Avvio di psql nel container timescaledb
make stop— arresto dei container.
![]()
Arresto del container timescale
make down— arresto ed eliminazione dei container. Per eliminare un container specifico, è possibile utilizzare questo comando specificando il container desiderato. Ad esempio —make down c=timescaleomake down c=api.

Arresto ed eliminazione di tutti i container
Risultati
Nonostante il sistema Docker Compose ci offra un ampio set di comandi per gestire i container, a volte questi comandi diventano lunghi e quindi è difficile memorizzarli.
Metodologia di utilizzo Makefile ci ha aiutato a instaurare un'interazione rapida e semplice con i container dal file docker-compose.yml. In particolare, si tratta di quanto segue:
- Lo sviluppatore interagisce solo con i container del progetto descritti in
docker-compose.yml, senza che altri container in esecuzione interferiscano con il lavoro. - Nel caso in cui un comando venga dimenticato, è possibile eseguire il comando
make helpe ottenere assistenza sui comandi disponibili. - Non è necessario memorizzare lunghe liste di argomenti per eseguire operazioni come ottenere registrazioni aggiornate o accedere al sistema. Ad esempio, un comando del tipo
docker-compose -f docker-compose.yml exec timescale psql -Upostgressi trasforma inmake db-shell. - File
Makefilepuò, man mano che il progetto cresce, essere adattato in modo flessibile. Ad esempio, non è difficile aggiungere un comando per creare un backup del database o per eseguire qualsiasi altra azione. - Se un grande team di sviluppatori utilizza lo stesso
Makefile, questo organizza la collaborazione e riduce il numero di errori.
P.S. Nel nostro è disponibile un'immagine , che può essere installata con un clic. Potete controllare il funzionamento dei container su . A tutti i nuovi clienti sono offerti 3 giorni di prova gratuita.
Gentili lettori! Come automatizzate il lavoro con Docker Compose?
Fonte: habr.com
