La traduzione della trascrizione del podcast è stata preparata in vista dell'inizio del corso

Docker Compose è uno strumento straordinario per creare un ambiente di lavoro
per lo stack utilizzato nella tua applicazione. Ti consente di definire
ogni componente della tua applicazione, seguendo una sintassi chiara e semplice in .
Con l'arrivo di questi file YAML possono essere utilizzati direttamente in ambiente di lavoro, quando si lavora con
un cluster .
Ma significa che puoi utilizzare lo stesso file docker-compose nel
processo di sviluppo e in ambiente di produzione? O utilizzare lo stesso file per
lo staging? Beh, in generale sì, ma per questa funzionalità abbiamo bisogno di quanto segue:
- Interpolazione delle variabili: utilizzo di variabili ambientali per alcuni
valori che cambiano in ciascun ambiente. - Ridefinizione della configurazione: la possibilità di definire un secondo (o qualsiasi
altro successivo) file docker-compose che modifichi qualcosa rispetto al
primo, e docker compose si occuperà della fusione di entrambi i file.
Differenze tra i file per sviluppo e produzione
Durante lo sviluppo, è probabile che tu voglia testare le modifiche al codice in
tempo reale. A tal fine, di solito, il volume con il codice sorgente viene montato in
un contenitore che contiene il runtime per la tua applicazione. Ma per l'ambiente di produzione,
questo approccio non è adatto.
In produzione hai un cluster con molti nodi, e il volume è locale rispetto al
nodo in cui gira il tuo contenitore (o servizio), quindi non puoi
montare il codice sorgente senza operazioni complesse che includono
sincronizzazione del codice, segnali, ecc.
Invece, di solito vogliamo creare un'immagine con una versione specifica del tuo codice.
Di solito viene contrassegnata con un'etichetta appropriata (puoi utilizzare la
versione semantica o un altro sistema a tua scelta).
Ridefinizione della configurazione
Tenendo conto delle differenze e del fatto che le tue dipendenze possono variare negli scenari
di sviluppo e produzione, è chiaro che avremo bisogno di diversi file di configurazione.
Docker compose supporta la fusione di diversi file compose per
ottenere la configurazione finale. Come funziona può essere visto con un esempio:
$ cat docker-compose.yml
version: "3.2"
services:
whale:
image: docker/whalesay
command: ["cowsay", "hello!"]
$ docker-compose up
Creating network "composeconfigs_default" with the default driver
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ________
whale_1 |
whale_1 | --------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0Come già detto, docker compose supporta l'unione di più file compose-
ciò consente di ridefinire diversi parametri nel secondo file. Ad esempio:
$ cat docker-compose.second.yml
version: "3.2"
services:
whale:
command: ["cowsay", "bye!"]
$ docker-compose -f docker-compose.yml -f docker-compose.second.yml up
Creating composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ______
whale_1 |
whale_1 | ------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0Questa sintassi non è molto comoda durante lo sviluppo, quando il comando
dovrà essere eseguito molte volte.
Fortunatamente, docker compose cerca automaticamente un file speciale con il nome
docker-compose.override.yml per ridefinire i valori. docker-compose.ymlSe
rinomini il secondo file, otterrai lo stesso risultato, ma con il comando originale:
$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1 | ______
whale_1 |
whale_1 | ------
whale_1 |
whale_1 |
whale_1 |
whale_1 | ## .
whale_1 | ## ## ## ==
whale_1 | ## ## ## ## ===
whale_1 | /""""""""""""""""___/ ===
whale_1 | ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
whale_1 | ______ o __/
whale_1 | __/
whale_1 | __________/
composeconfigs_whale_1 exited with code 0Bene, è più facile ricordarlo in questo modo.
Interpolazione delle variabili
I file di configurazione supportano e i valori predefiniti. Quindi puoi fare quanto segue:
services:
my-service:
build:
context: .
image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
...E se esegui docker-compose build (o push) senza la variabile d'ambiente
$MY_SERVICE_VERSION, verrà utilizzato il valore latest, ma se imposti
il valore della variabile d'ambiente prima della build, esso verrà utilizzato durante la build o il push
nel registry private.registry.mine.
I miei principi
Gli approcci che sono comodi per me possono tornare utili anche a voi. Seguo queste
regole semplici:
- Tutti i miei stack per la produzione, lo sviluppo (o altri ambienti) vengono definiti tramite
file docker-compose. - I file di configurazione necessari per coprire tutti i miei ambienti evitano al massimo
la duplicazione. - Ho bisogno di un semplice comando per lavorare in ciascun ambiente.
- La configurazione principale è definita nel file docker-compose.yml.
- Le variabili di ambiente sono utilizzate per definire i tag delle immagini o altre
variabili che possono cambiare da un ambiente all'altro (stagging, integrazione,
produzione). - I valori delle variabili per la produzione vengono utilizzati come valori di
default, riducendo al minimo i rischi nel caso di avvio dello stack in produzione senza
una variabile di ambiente impostata. - Per avviare il servizio in ambiente di produzione si utilizza il comando docker stack deploy — compose-file docker-compose.yml —with-registry-auth my-stack-name.
- L'ambiente di lavoro viene avviato utilizzando il comando docker-compose up -d.
Diamo un'occhiata a un semplice esempio.
# docker-compose.yml
...
services:
my-service:
build:
context: .
image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
environment:
API_ENDPOINT: ${API_ENDPOINT:-https://production.my-api.com}
...E
# docker-compose.override.yml
...
services:
my-service:
ports: # This is needed for development!
- 80:80
environment:
API_ENDPOINT: https://devel.my-api.com
volumes:
- ./:/project/src
...Posso utilizzare docker-compose (docker-compose up), per avviare lo stack in
modalità di sviluppo con il codice sorgente montato in /project/src.
Posso utilizzare questi stessi file in produzione! E potrei utilizzare esattamente
lo stesso file docker-compose.yml per lo stagging. Per distribuirlo in
produzione, devo semplicemente costruire e inviare l'immagine con un tag predefinito
nella fase di CI:
export MY_SERVICE_VERSION=1.2.3
docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml pushIn produzione, questo può essere avviato utilizzando i seguenti comandi:
export MY_SERVICE_VERSION=1.2.3
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-authE se vuoi fare la stessa cosa nello stagging, è semplicemente necessario definire
le variabili di ambiente necessarie per lavorare in ambiente di stagging:
export MY_SERVICE_VERSION=1.2.3
export API_ENDPOINT=http://staging.my-api.com
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-authIn definitiva, abbiamo utilizzato due file docker-compose diversi che, senza
duplicazioni di configurazione, possono essere utilizzati per qualsiasi vostro ambiente!
Scopri di più sul corso
Fonte: habr.com
