Docker Compose: od rozwoju do produkcji

Tłumaczenie transkrypcji podcastu przygotowano z okazji rozpoczęcia kursu Administrator Linux

Docker Compose: od rozwoju do produkcji

Docker Compose to niesamowite narzędzie do tworzenia środowiska
roboczego dla stosu używanego w Twojej aplikacji. Pozwala zdefiniować
każdy komponent aplikacji, przestrzegając wyraźnej i prostej składni w plikach YAML
Z pojawieniem się
.

docker compose v3 te pliki YAML mogą być używane bezpośrednio w środowisku produkcyjnym, podczas pracy z klastrem
Docker Swarm Czy to oznacza, że można używać tego samego pliku docker-compose w.

procesie rozwoju i w środowisku produkcyjnym? Lub użyć tego samego pliku do
stagowania? Cóż, ogólnie - tak, ale aby uzyskać tę funkcjonalność, potrzebujemy następującego:
Interpolacja zmiennych: używanie zmiennych środowiskowych do niektórych

  • wartości, które zmieniają się w każdym środowisku.
    Nadpisywanie konfiguracji: możliwość określenia drugiego (lub dowolnego
  • innego następnego) pliku docker-compose, który zmieni coś w porównaniu do
    pierwszego, a docker compose zajmie się scaleniem obu plików.
    Różnice między plikami dla rozwoju a produkcji

Podczas rozwoju prawdopodobnie będziesz chciał śledzić zmiany kodu w

czasie rzeczywistym. W tym celu zazwyczaj montuje się wolumen z kodem źródłowym w
kontenerze, w którym znajduje się runtime dla Twojej aplikacji. Jednak dla środowiska produkcyjnego
taki sposób nie jest odpowiedni.
W produkcie masz klaster z wieloma węzłami, a wolumen jest lokalny względem

węzła, na którym działa Twój kontener (lub usługa), dlatego nie możesz
montować kodu źródłowego bez skomplikowanych operacji, które obejmują
synchronizację kodu, sygnały itd.
Zamiast tego zazwyczaj chcemy stworzyć obraz z określoną wersją naszego kodu.

Zwykle oznaczasz go odpowiednim tagiem (można zastosować semantyczne
wersjonowanie lub inny system według własnego uznania).
Nadpisywanie konfiguracji

Biorąc pod uwagę różnice i to, że Twoje zależności mogą się różnić w scenariuszach

rozwoju i produkcji, jasne jest, że będziemy potrzebować różnych plików konfiguracyjnych.
Docker compose wspiera scalanie różnych plików compose w celu

uzyskania ostatecznej konfiguracji. Jak to działa można zobaczyć na przykładzie:
uzyskania ostatecznej konfiguracji. Jak to działa, można zobaczyć na przykładzie:

$ cat docker-compose.yml
version: "3.2"

services:
  whale:
    image: docker/whalesay
    command: ["cowsay", "hello!"]
$ docker-compose up
Tworzenie sieci "composeconfigs_default" z domyślnym sterownikiem
Uruchamianie composeconfigs_whale_1
Podłączanie do 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 0

Jak wspomniano, docker compose wspiera łączenie kilku plików compose,
co pozwala na nadpisanie różnych parametrów w drugim pliku. Na przykład:

$ 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
Tworzenie composeconfigs_whale_1
Podłączanie do 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 0

Taki składnia nie jest zbyt wygodna w trakcie programowania, kiedy polecenie
będzie musiało być wykonywane wiele razy.

Na szczęście, docker compose automatycznie szuka specjalnego pliku o nazwie
docker-compose.override.yml do nadpisania wartości. docker-compose.yml. Jeśli
Zmiana nazwy drugiego pliku da ten sam rezultat, tylko przy użyciu oryginalnego polecenia:

$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Uruchamianie composeconfigs_whale_1
Podłączanie do 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 0

Dobrze, tak łatwiej zapamiętać.

Interpolacja zmiennych

Pliki konfiguracyjne wspierają interpolację
zmiennych
i wartości domyślne. Możesz więc zrobić coś takiego:

services:
  my-service:
    build:
      context: .
    image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
...

A jeśli wykonasz docker-compose build (lub push) bez zmiennej środowiskowej
$MY_SERVICE_VERSION, użyta zostanie wartość latest, ale jeśli ustawisz
wartość zmiennej środowiskowej przed budowaniem, zostanie ona użyta podczas budowy lub push
do rejestru private.registry.mine.

Moje zasady

Podejścia, które są dla mnie wygodne, mogą być przydatne także dla Was. Stosuję te
proste zasady:

  • Wszystkie moje stosy dla środowisk produkcyjnych, deweloperskich (czy innych) definiowane są przez
    pliki docker-compose.
  • Pliki konfiguracyjne, które są potrzebne do pokrycia wszystkich moich środowisk, maksymalnie
    unikają powielania.
  • Potrzebuję jednego prostego polecenia do pracy w każdym środowisku.
  • Podstawowa konfiguracja jest określana w pliku docker-compose.yml.
  • Zmienne środowiskowe są używane do definiowania tagów obrazów lub innych
    zmiennych, które mogą się różnić w zależności od środowiska (staging, integracja,
    produkcja).
  • Wartości zmiennych dla produkcji są używane jako wartości domyślne, co minimalizuje ryzyko w przypadku uruchomienia stosu w produkcji bez
    ustawionej zmiennej środowiskowej.
    Aby uruchomić usługę w środowisku produkcyjnym, używa się polecenia
  • docker stack deploy — compose-file docker-compose.yml —with-registry-auth my-stack-name Środowisko robocze uruchamia się za pomocą polecenia.
  • Zobaczmy prosty przykład. docker-compose up -d.

Mogę użyć

# 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}
...

I

# 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
...

docker-compose (docker-compose up) , aby uruchomić stos wtrybie deweloperskim z kodem źródłowym zamontowanym w
Mogę użyć tych samych plików w produkcji! I mogłem bym użyć dokładnie /project/src.

takiego samego pliku
dla stagingu. Aby wdrożyć to w docker-compose.yml produkcji, wystarczy, że zbuduję i wyślę obraz z wcześniej zdefiniowanym tagiem
na etapie CI:
export MY_SERVICE_VERSION=1.2.3 docker-compose -f docker-compose.yml build docker-compose -f docker-compose.yml push

W produkcji można to uruchomić za pomocą następujących poleceń:

export MY_SERVICE_VERSION=1.2.3 docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth

A jeśli chcesz zrobić to samo na stagu, wystarczy po prostu zdefiniować

niezbędne zmienne środowiskowe do działania w środowisku stagingowym:
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-auth

W rezultacie użyliśmy dwóch różnych plików docker-compose, które bez

powielania konfiguracji mogą być używane dla dowolnego z Twoich środowisk!
Dowiedz się więcej o kursie

Teoria i praktyka użycia ClickHouse w rzeczywistych aplikacjach. Aleksandr Zajcew (2018r) Administrator Linux

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster