Ogni pochi anni, il settore dello sviluppo software subisce un cambiamento di paradigma. Uno di questi fenomeni può essere riconosciuto come il crescente interesse per il concetto di microservizi. Sebbene i microservizi non siano la tecnologia più recente, solo di recente la loro popolarità è letteralmente salita alle stelle.
I grandi servizi monolitici vengono ora sostituiti da microservizi indipendenti e autonomi. Un microservizio può essere pensato come un'applicazione che ha uno scopo unico e molto specifico. Ad esempio potrebbe essere un DBMS relazionale, un'applicazione Express, un servizio Solr.
Al giorno d’oggi è difficile immaginare di sviluppare un nuovo sistema software senza utilizzare i microservizi. E questa situazione, a sua volta, ci porta alla piattaforma Docker.
docker
piattaforma
Docker Compose
Технология
Quando si lavora con Docker Compose, viene utilizzato un file YAML per configurare i servizi applicativi e organizzare la loro interazione reciproca. Docker Compose è quindi uno strumento per descrivere ed eseguire applicazioni Docker multi-contenitore.
Due contenitori in esecuzione su un sistema host
Crea GNU
Programma make
, è essenzialmente uno strumento per automatizzare la creazione di programmi e librerie dal codice sorgente. In generale possiamo dirlo make
si applica a qualsiasi processo che implica l'esecuzione di comandi arbitrari per trasformare alcuni materiali di input in qualche forma di output, verso qualche obiettivo. Nel nostro caso, i comandi docker-compose
saranno trasformati in obiettivi astratti (
Per raccontare il programma make
su ciò che vogliamo da esso, abbiamo bisogno di un file Makefile
.
Nel nostro Makefile
conterrà comandi regolari docker
и docker-compose
, che sono progettati per risolvere molti problemi. Vale a dire, stiamo parlando di assemblare un contenitore, di avviarlo, arrestarlo, riavviarlo, di organizzare l'accesso degli utenti al contenitore, di lavorare con i log del contenitore e di risolvere altri problemi simili.
Casi d'uso tipici per Docker Compose
Immaginiamo una normale applicazione web che abbia i seguenti componenti:
- Database TimescaleDB (Postgres).
- Applicazione Express.js.
- Ping (solo un contenitore, non fa nulla di speciale).
Questa applicazione avrà bisogno di 3 contenitori Docker e un file docker-compose
, che contiene istruzioni per la gestione di questi contenitori. Ogni contenitore avrà punti di contatto diversi. Ad esempio, con un contenitore timescale
sarà possibile lavorare più o meno nello stesso modo in cui lavorano con i database. Vale a dire, ti consente di eseguire le seguenti azioni:
- Accesso alla shell Postgres.
- Importazione ed esportazione di tabelle.
- creazione
pg_dump
tabelle o database.
Contenitore dell'applicazione Express.js, expressjs
, può avere le seguenti funzionalità:
- Fornire dati aggiornati dal registro di sistema.
- Accedi alla shell per eseguire determinati comandi.
Interazione con i contenitori
Una volta impostata la comunicazione tra i contenitori utilizzando Docker Compose, è il momento di comunicare con tali contenitori. All'interno del sistema Docker Compose c'è un comando docker-compose
, opzione di supporto -f
, che consente di trasferire un file nel sistema docker-compose.yml
.
Utilizzando le funzionalità di questa opzione, puoi limitare l'interazione con il sistema solo ai contenitori menzionati nel file docker-compose.yml
.
Diamo un'occhiata a come appaiono le interazioni con i contenitori quando si utilizzano i comandi docker-compose
. Se immaginiamo di dover accedere alla shell psql
, i comandi corrispondenti potrebbero assomigliare a questi:
docker-compose -f docker-compose.yml exec timescale psql -Upostgres
Lo stesso comando che non viene utilizzato per l'esecuzione docker-compose
E docker
, potrebbe assomigliare a questo:
docker exec -it edp_timescale_1 psql -Upostgres
Tieni presente che in questi casi è sempre preferibile utilizzare il comando docker
e la squadra docker-compose
, poiché ciò elimina la necessità di ricordare i nomi dei contenitori.
Entrambi i comandi precedenti non sono così difficili. Ma se usassimo un “involucro” nel modulo Makefile
, che ci fornirebbe un'interfaccia sotto forma di comandi semplici e chiamerebbe esso stesso comandi lunghi simili, gli stessi risultati potrebbero essere ottenuti in questo modo:
make db-shell
È abbastanza ovvio che l'uso Makefile
rende il lavoro con i contenitori molto più semplice!
Esempio funzionante
Sulla base del diagramma di progetto 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 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 qui descritti si applicano a tutti i contenitori, ma utilizzando l'opzione c=
consente di limitare l'ambito di un comando a un contenitore.
Dopo Makefile
pronto, puoi usarlo in questo modo:
make help
— emissione di un elenco di tutti i comandi disponibili permake
.
Aiuto sui comandi disponibili
make build
- assemblare un'immagine daDockerfile
. Nel nostro esempio abbiamo utilizzato immagini esistentitimescale
иping
. Ma l'immagineapi
vogliamo raccogliere localmente. Questo è esattamente ciò che verrà fatto dopo aver eseguito questo comando.
Costruire un contenitore Docker
make start
— lancio di tutti i contenitori. Per avviare un solo contenitore, puoi utilizzare un comando comemake start c=timescale
.
Esecuzione del contenitore della scala cronologica
Esecuzione di un contenitore ping
make login-timescale
- accedi alla sessione bash del contenitoretimescale
.
Esecuzione di bash in un contenitore di scala temporale
make db-shell
- ingresso apsql
in un contenitoretimescale
per eseguire query SQL sul database.
Esecuzione di psql in un contenitore DB con scala cronologica
make stop
— fermare i contenitori.
Arresto di un contenitore di scala cronologica
make down
— fermare e rimuovere i contenitori. Per rimuovere un contenitore specifico, è possibile utilizzare questo comando specificando il contenitore desiderato. Per esempio -make down c=timescale
omake down c=api
.
Arresto ed eliminazione di tutti i contenitori
Risultati di
Sebbene Docker Compose ci offra un ricco set di comandi per la gestione dei contenitori, a volte questi comandi possono diventare lunghi e difficili da ricordare.
Metodo d'uso Makefile
ci ha aiutato a stabilire un'interazione rapida e semplice con i contenitori da un file docker-compose.yml
. Vale a dire, stiamo parlando di quanto segue:
- Lo sviluppatore interagisce solo con i contenitori di progetto descritti in
docker-compose.yml
, il lavoro non viene interferito da altri contenitori in esecuzione. - Nel caso in cui un determinato comando venga dimenticato, è possibile eseguirlo
make help
e ottieni aiuto sui comandi disponibili. - Non è necessario ricordare lunghi elenchi di argomenti per eseguire azioni come ottenere le voci di registro più recenti o accedere a un sistema. Ad esempio, un comando come
docker-compose -f docker-compose.yml exec timescale psql -Upostgres
si trasforma inmake db-shell
. - file
Makefile
Puoi adattarti in modo flessibile man mano che il progetto cresce. Ad esempio, è semplice aggiungere un comando per creare un backup del database o eseguire qualsiasi altra azione. - Se un grande team di sviluppatori utilizza lo stesso
Makefile
, questo semplifica la collaborazione e riduce gli errori.
PS Nel nostro
Cari lettori! Come automatizzi Docker Compose?
Fonte: habr.com