Docker Compose – odpalamy wiele kontenerów

Docker Compose jest kolejnym krokiem w pracy z kontenerami. Służy do uruchamiania i definiowania aplikacji składającej się z wielu kontenerów. Definiując pojedynczy plik Dockerfile nie mamy problemu z uruchomieniem go, jeśli natomiast mamy wiele takich plików pojawia się bardzo duża złożoność. Rozwiązaniem problemu jest Docker Compose.

Uwaga! Aby korzystać z Docker Compose wymagana jest instalacja Dockera.

Na początek zacznijmy od stworzenia dwóch plików Dockerfile dla naszych aplikacji. Pierwszy, który będzie producentem wiadomości na kolejkę:

FROM openjdk:8-jre-alpine
ADD target/producer-docker.jar producer-docker.jar
EXPOSE 8081
EXPOSE 8001
ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001", "-jar", "producer-docker.jar"]

Natomiast plik Dockerfile dla consumera naszych wiadomości będzie wyglądał następująco:

FROM openjdk:8-jre-alpine
ADD target/consumer-docker.jar consumer-docker.jar
EXPOSE 8082
EXPOSE 8002
ENTRYPOINT ["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8002", "-jar", "consumer-docker.jar"]

Gdy stworzyliśmy pliki Dockerfile możemy przystąpić do utworzenia pliku docker-compose.yml.

version: '3'
services:
    rabbitmq:
        image: rabbitmq:3.6-management-alpine
        ports:
            - "5672:5672"
            - "15672:15672"
    producer:
        build: ./producer
        ports:
            - "8081:8081"
            - "8001:8001"
        links:
            - rabbitmq
        environment:
            RABBIT_HOST: rabbitmq
    consumer:
        build: ./consumer
        ports:
            - "8082:8082"
            - "8002:8002"
        links:
            - rabbitmq
        environment:
            RABBIT_HOST: rabbitmq

gdzie:

  • version – oznacza wersję Docker Compose (aktualna wersja to 3.3)
  • services – sekcja, w której definiujemy serwisy
  • rabbitmq/producer/consumer – nazwa własna usługi
  • image – wskazujemy z jakiego obrazu ma być zbudowany kontener
  • build – wskazujemy ścieżkę do pliku Dockerfile naszego serwisu
  • ports – definiujemy porty, które będą mapowane z konteneru
  • links – zależność pomiędzy kontenerami, producer oraz consumer “widzą się” z rabbitmq, czyli mogą korzystać z jego usług
  • environment – zmienna środowiskowa dla danego kontenera

Aby uruchomić Docker Compose w naszym terminalu Dockerowym używamy polecenia (tam gdzie mamy plik docker-compose.yml):

docker-compose up

Aby sprawdzić czy nasze kontenery pracują:

docker-compose ps

Teraz wystarczy udać się pod wybrany przez nas adres. Jeśli zakończyliśmy pracę z naszymi kontenerami wydajemy polecenie (tam gdzie mamy plik docker-compose.yml), które stopuje kontenery:

docker-compose stop

Usunięcie kontenerów osiągniemy dzięki (polecenie uruchamiamy tam gdzie mamy plik docker-compose.yml):

docker-compose rm

Github

Całość jak zawsze na GitHub.

  • Artur Skrzydło

    Fajny artykuł ,jak zwykle zresztą. Podoba mi się ta krótka forma – można przeczytać jak się ma dosłownie chwile czasu 🙂 Dodam od siebie tylko dwie rzeczy :

    -links jest w zasadzie niepotrzebne. Docker compose sam sobie tworzy sieć (network) pomiędzy serwisami wymienionymi w pliku .yml. Serwis będzie widoczny zatem po jej nazwie bez linkowania.

    – jeszcze jeśli chodzi o dobre praktyki, to w Dockerfile sugerowane jest, żeby używać COPY zamiast ADD, chyba, że chcemy ściągać coś z innego zasobu sieciowego https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

    • CodeCouple.pl

      Dzięki @arturskrzydo:disqus za dobre słowo 😉 Co do links jak najbardziej masz rację, ja niestety nie posiadam “normalnego” (czyt. Linux) systemu operacyjnego i mam cały czas problemy z Docker Toolbox’a dlatego dodaje to links. Co do drugiego punktu nie wiedziałem o tym, fajnie że można się czegoś więcej nauczyć od czytelników, dzięki za linka i zapraszam ponownie!

  • thalion

    Mam jedno pytanie. Jestem kompletnie zielony w Dockerze. Potrzebuje się dostać do konsoli jednej z aplikacji odpalonych przez docker-compose. Jak mogę to zrobić? Konkretnie chodzi o sytuację, w której każdy z kontenerów odpala aplikację, która posiada swoją własną linię poleceń i chciałbym móc się do niej dostać.

    Z góry baaaardzo dziękuję za odpowiedź

    • CodeCouple.pl

      Witaj, sprawdź sobie jaki masz hash/nazwe kontenera i w nowym oknie użyj:
      docker exec -t -i container_name /bin/bash

  • Kimi

    Cześć! Świetny artykuł, jednak mimo, że bazowałem na nim, nie jestem w stanie poradzić sobie z pewnym błędem. Mam dwa kontenery, które zawierają moje własne drobne pythonowe aplikacje, chce skomunikowac te kontenery ze soba za pomocą rabbita.
    Cały kod dostępny jest tutaj: https://github.com/Kimi82/rabbitmq_learning
    Jednak gdy uruchamiam plik docker-compose.yml. Wywala mi dokładnie taki sam błąd, jak gdybym uruchamiał aplikacje korzystające z Rabbita, bez wcześniejszego uruchomienia kontenera z Rabbitem właśnie.

    Próbowałem wiele rzeczy, ale nic nie pomogło :/
    Może tutaj znajdę pomoc? 🙂