Wyszukiwanie w witrynie

Jak zainstalować i używać Docker Compose na Ubuntu


Wprowadzenie

Docker upraszcza proces zarządzania procesami aplikacji w kontenerach. Chociaż kontenery w pewnych aspektach przypominają maszyny wirtualne, są one bardziej lekkie i oszczędne pod względem zasobów. Umożliwia to programistom podział środowiska aplikacji na wiele izolowanych usług.

W przypadku aplikacji zależnych od kilku usług, koordynowanie uruchamiania, komunikacji i zamykania wszystkich kontenerów może szybko stać się niepraktyczne. Docker Compose to narzędzie, które pozwala uruchamiać środowiska aplikacji wielokontenerowych w oparciu o definicje zapisane w pliku YAML. Wykorzystuje definicje usług do tworzenia w pełni konfigurowalnych środowisk z wieloma kontenerami, które mogą współdzielić sieci i woluminy danych.

Ten przewodnik przeprowadzi Cię przez instalację Docker Compose na serwerze Ubuntu oraz uruchomienie prostego kontenera. Następnie nauczysz się tworzyć środowisko wielousługowe z użyciem aplikacji WordPress i bazy danych MySQL. Omówimy również bardziej zaawansowane tematy, w tym skalowanie usług, definiowanie niestandardowych sieci oraz korzystanie z dyrektyw modułowych include. Na koniec artykuł zawiera przewodnik migracji ze starszej wersji docker-compose (v1) do nowoczesnej wersji docker compose (v2) oraz szczegółową sekcję dotyczącą rozwiązywania typowych problemów, takich jak konflikty portów i błędy uprawnień.

Najważniejsze wnioski:

  • Docker Compose to narzędzie do definiowania i uruchamiania aplikacji wielokontenerowych za pomocą jednego pliku YAML, w którym konfiguruje się usługi, sieci i wolumeny.
  • Docker Compose jest instalowany na Ubuntu poprzez dodanie oficjalnego repozytorium Dockera i użycie apt do zainstalowania pakietu docker-compose-plugin.
  • Nowoczesnym poleceniem jest docker compose (ze spacją). Zastępuje ono przestarzałe narzędzie v1 docker-compose (z myślnikiem).
  • Użyj docker compose up -d, aby uruchomić aplikację w trybie odłączonym, oraz docker compose down, aby zatrzymać ją i usunąć wszystkie jej kontenery oraz sieci.
  • Dyrektywa depends_on pomaga kontrolować kolejność uruchamiania usług, na przykład zapewniając, że kontener bazy danych uruchomi się przed kontenerem aplikacji internetowej.
  • Najczęstsze problemy to „Brak uprawnień” (rozwiązywane przez dodanie użytkownika do grupy docker), konflikty portów (rozwiązywane przez zmianę portu hosta w pliku YAML) oraz błędy składni YAML (rozwiązywane przez poprawienie wcięć).
  • Możesz uruchomić wiele instancji usługi za pomocą polecenia docker compose up --scale <nazwa_usługi>=<liczba>.
  • Dyrektywa include pozwala podzielić duży plik docker-compose.yml na mniejsze, łatwiejsze do zarządzania pliki konfiguracyjne.

Wymagania wstępne

Aby śledzić ten artykuł, będziesz potrzebować:

  • Dostęp do lokalnej maszyny Ubuntu lub serwera deweloperskiego jako użytkownik nieuprzywilejowany z uprawnieniami sudo. Jeśli korzystasz z zdalnego serwera, zaleca się, aby był na nim aktywny firewall. Aby to skonfigurować, prosimy o zapoznanie się z naszym Przewodnikiem początkowej konfiguracji serwera dla Ubuntu.
  • Docker zainstalowany na Twoim serwerze lub komputerze lokalnym, zgodnie z Krokami 1 i 2 przewodnika Jak zainstalować Docker na Ubuntu – przewodnik krok po kroku.

Uwaga: Od wersji Docker Compose v2, Docker przeszedł na używanie polecenia wtyczki CLI compose, rezygnując z oryginalnego docker-compose, jak opisano w naszym przewodniku Jak Zainstalować Docker Compose na Ubuntu (Krok po Kroku). Chociaż proces instalacji różni się, w praktyce użycie polega na usunięciu myślnika z poleceń docker-compose, zmieniając je na docker compose. Aby uzyskać pełne informacje o kompatybilności, sprawdź oficjalną dokumentację Dockera dotyczącą zgodności poleceń między nowym compose a starym docker-compose.

Krok 1 — Instalacja Docker Compose

Są dwa sposoby instalacji Docker Compose na Ubuntu:

  • Zainstaluj za pomocą repozytorium
  • Zainstaluj ręcznie

Omówimy oba sposoby w tej sekcji.

Instalowanie Docker Compose przy użyciu repozytorium apt

Najpierw skonfigurujmy repozytorium Docker apt.

# Add Docker's official GPG key:

sudo apt-get update

sudo apt-get install ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc



# Add the repository to Apt sources:

echo \

  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \

  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \

  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

Teraz możesz zainstalować Docker Compose, używając następującego polecenia:

sudo apt install docker-compose-plugin

Docker Compose został teraz pomyślnie zainstalowany na Twoim systemie. Aby sprawdzić, czy instalacja przebiegła pomyślnie, możesz uruchomić:

docker compose version

Zobaczysz wynik podobny do tego:

Docker Compose version v2.3.3

Ręczna instalacja Docker Compose

Aby upewnić się, że pobierzesz najnowszą stabilną wersję Docker Compose, należy pobrać to oprogramowanie z jego oficjalnego repozytorium na GitHubie.

Najpierw potwierdź najnowszą wersję dostępną na stronie z wydaniami. W momencie pisania tego tekstu, najnowsza stabilna wersja to v2.40.2.

Użyj następującego polecenia, aby pobrać:

mkdir -p ~/.docker/cli-plugins/

curl -SL https://github.com/docker/compose/releases/download/v2.40.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

Następnie ustaw odpowiednie uprawnienia, aby polecenie docker compose było możliwe do wykonania:

chmod +x ~/.docker/cli-plugins/docker-compose

W następnej sekcji zobaczysz, jak skonfigurować plik docker-compose.yml i uruchomić środowisko w kontenerze za pomocą tego narzędzia.

Krok 2 — Tworzenie pliku docker-compose.yml

Aby pokazać, jak skonfigurować plik docker-compose.yml i pracować z Docker Compose, stworzysz środowisko serwera WWW z użyciem oficjalnego obrazu Nginx z Docker Hub, publicznego rejestru Docker. To środowisko w kontenerze będzie obsługiwać pojedynczy statyczny plik HTML.

Zacznij od utworzenia nowego katalogu w swoim folderze domowym, a następnie przejdź do niego:

mkdir ~/compose-demo

cd ~/compose-demo

W tym katalogu utwórz folder aplikacji, który będzie pełnił funkcję katalogu głównego dokumentów dla Twojego środowiska Nginx:

mkdir app

Używając swojego ulubionego edytora tekstu, utwórz nowy plik index.html w folderze app:

nano app/index.html

Umieść następującą zawartość w tym pliku:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Docker Compose Demo</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css">
</head>
<body>

    <h1>This is a Docker Compose Demo Page.</h1>
    <p>This content is being served by an Nginx container.</p>

</body>
</html>

Zapisz i zamknij plik, gdy skończysz. Jeśli używasz nano, możesz to zrobić, naciskając CTRL+X, a następnie Y i ENTER, aby potwierdzić.

Następnie utwórz plik docker-compose.yml:

nano docker-compose.yml

Wstaw następującą zawartość do swojego pliku docker-compose.yml:

services:
  web:
    image: nginx:alpine
    ports:
      - "8000:80"
    volumes:
      - ./app:/usr/share/nginx/html

W nowoczesnym Docker Compose pole version jest opcjonalne i często pomijane, ponieważ Compose potrafi automatycznie wykryć wersję konfiguracji. Powyższy przykład nie zawiera pola version, co jest zalecanym podejściem w większości nowych projektów. Określenie version jest potrzebne tylko dla zgodności z starszymi wersjami.

Następnie masz blok services, w którym konfigurujesz usługi będące częścią tego środowiska. W Twoim przypadku masz jedną usługę o nazwie web. Ta usługa używa obrazu nginx:alpine i ustawia przekierowanie portów za pomocą dyrektywy ports. Wszystkie żądania na porcie 8000 maszyny hosta (systemu, z którego uruchamiasz Docker Compose) zostaną przekierowane do kontenera web na porcie 80, gdzie będzie działać Nginx.

Dyrektywa volumes utworzy współdzieloną wolumin pomiędzy maszyną hosta a kontenerem. Udostępni to lokalny folder app kontenerowi, a wolumin będzie znajdował się w /usr/share/nginx/html wewnątrz kontenera, co spowoduje nadpisanie domyślnego katalogu dokumentów Nginx.

Zapisz i zamknij plik.

Utworzyłeś stronę demonstracyjną oraz plik docker-compose.yml, aby stworzyć konteneryzowane środowisko serwera WWW, które ją obsłuży. W następnym kroku uruchomisz to środowisko za pomocą Docker Compose.

Krok 3 — Uruchamianie Docker Compose

Mając plik docker-compose.yml, możesz teraz uruchomić Docker Compose, aby uruchomić swoje środowisko. Następujące polecenie pobierze niezbędne obrazy Dockera, utworzy kontener dla usługi web i uruchomi środowisko w kontenerze w trybie tła:

docker compose up -d

Docker Compose najpierw poszuka zdefiniowanego obrazu na Twoim lokalnym systemie, a jeśli nie będzie w stanie go znaleźć, pobierze obraz z Docker Hub. Zobaczysz taki komunikat:

Creating network "compose-demo_default" with the default driver
Pulling web (nginx:alpine)...
alpine: Pulling from library/nginx
cbdbe7a5bc2a: Pull complete
10c113fb0c77: Pull complete
9ba64393807b: Pull complete
c829a9c40ab2: Pull complete
61d685417b2f: Pull complete
Digest: sha256:57254039c6313fe8c53f1acbf15657ec9616a813397b74b063e32443427c5502
Status: Downloaded newer image for nginx:alpine
Creating compose-demo_web_1 ... done

Uwaga: Jeśli podczas uruchamiania docker compose up napotkasz błąd „permission denied”, zazwyczaj oznacza to, że Twój użytkownik nieuprzywilejowany nie ma uprawnień do dostępu do gniazda demona Dockera.

Domyślnie demon Dockera łączy się przez gniazdo Unix (/var/run/docker.sock), które należy do użytkownika root. Aby to naprawić, musisz dodać swojego użytkownika nie-root do grupy docker, która jest tworzona podczas instalacji Dockera.

Uruchom następujące polecenie, aby dodać swojego użytkownika do grupy docker:

sudo usermod -aG docker ${USER}

Po uruchomieniu tej komendy będziesz musiał się wylogować i ponownie zalogować, aby zmiany w grupach zostały zastosowane. Możesz również aktywować zmiany w bieżącej sesji terminala, wpisując:

newgrp docker

To polecenie powinno rozwiązać wszystkie błędy uprawnień związane z gniazdem Dockera. Aby uzyskać pełną instrukcję, proszę odnieść się do Kroku 2 w przewodniku Jak zainstalować Docker na Ubuntu – krok po kroku.

Twoje środowisko działa teraz w tle. Aby sprawdzić, czy kontener jest aktywny, możesz uruchomić:

docker compose ps

To polecenie pokaże informacje o działających kontenerach i ich stanie, a także o wszelkich aktualnie obowiązujących przekierowaniach portów:

       Name                     Command               State          Ports        
----------------------------------------------------------------------------------
compose-demo_web_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8000->80/tcp

Teraz możesz uzyskać dostęp do aplikacji demonstracyjnej, kierując swoją przeglądarkę pod adres localhost:8000, jeśli uruchamiasz tę demonstrację na swoim lokalnym komputerze, lub your_server_domain_or_IP:8000, jeśli uruchamiasz tę demonstrację na zdalnym serwerze.

Zobaczysz stronę taką jak ta:

Współdzielony wolumen, który skonfigurowałeś w pliku docker-compose.yml, utrzymuje pliki folderu app w synchronizacji z katalogiem głównym dokumentów kontenera. Jeśli dokonasz jakichkolwiek zmian w pliku index.html, zostaną one automatycznie zauważone przez kontener i w efekcie będą widoczne w Twojej przeglądarce po odświeżeniu strony.

W kolejnym kroku zobaczysz, jak zarządzać środowiskiem kontenerowym za pomocą poleceń Docker Compose.

Krok 4 — Zapoznanie się z poleceniami Docker Compose

Widziałeś, jak skonfigurować plik docker-compose.yml i uruchomić swoje środowisko za pomocą docker compose up. Teraz zobaczysz, jak używać poleceń Docker Compose do zarządzania i interakcji ze swoim środowiskiem kontenerowym.

Aby sprawdzić logi generowane przez kontener Nginx, możesz użyć polecenia logs:

docker compose logs

Zobaczysz wynik podobny do tego:

Attaching to compose-demo_web_1
web_1  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web_1  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web_1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web_1  | 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
web_1  | 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
web_1  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web_1  | /docker-entrypoint.sh: Configuration complete; ready for start up
web_1  | 172.22.0.1 - - [02/Jun/2020:10:47:13 +0000] "GET / HTTP/1.1" 200 353 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" "-"

Jeśli chcesz wstrzymać wykonywanie środowiska bez zmiany bieżącego stanu swoich kontenerów, możesz użyć:

docker compose pause
Pausing compose-demo_web_1 ... done

Aby wznowić wykonywanie po wstrzymaniu:

docker compose unpause
Unpausing compose-demo_web_1 ... done

Polecenie stop zakończy działanie kontenera, ale nie usunie żadnych danych związanych z Twoimi kontenerami:

docker compose stop
Stopping compose-demo_web_1 ... done

Jeśli chcesz usunąć kontenery, sieci i wolumeny związane z tym środowiskiem kontenerowym, użyj polecenia down:

docker compose down
Removing compose-demo_web_1 ... done
Removing network compose-demo_default

Zauważ, że to nie usunie bazowego obrazu używanego przez Docker Compose do uruchomienia Twojego środowiska (w Twoim przypadku nginx:alpine). Dzięki temu, gdy ponownie uruchomisz swoje środowisko za pomocą docker compose up, proces będzie znacznie szybszy, ponieważ obraz znajduje się już na Twoim systemie.

Jeśli chcesz również usunąć podstawowy obraz ze swojego systemu, możesz użyć:

docker image rm nginx:alpine
Untagged: nginx:alpine
Untagged: nginx@sha256:b89a6ccbda39576ad23fd079978c967cecc6b170db6e7ff8a769bf2259a71912
Deleted: sha256:7d0cdcc60a96a5124763fddf5d534d058ad7d0d8d4c3b8be2aefedf4267d0270
Deleted: sha256:05a0eaca15d731e0029a7604ef54f0dda3b736d4e987e6ac87b91ac7aac03ab1
Deleted: sha256:c6bbc4bdac396583641cb44cd35126b2c195be8fe1ac5e6c577c14752bbe9157
Deleted: sha256:35789b1e1a362b0da8392ca7d5759ef08b9a6b7141cc1521570f984dc7905eb6
Deleted: sha256:a3efaa65ec344c882fe5d543a392a54c4ceacd1efd91662d06964211b1be4c08
Deleted: sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a

Uwaga: Prosimy odnieść się do naszego przewodnika Jak Zainstalować Docker na Ubuntu – Przewodnik Krok po Kroku, aby uzyskać bardziej szczegółowe informacje na temat poleceń Dockera.

Krok 5 — Tworzenie aplikacji wieloserwisowej

Prawdziwa moc Docker Compose tkwi w zarządzaniu wieloma usługami, które współpracują ze sobą. Przykład z Nginx dotyczył jednej usługi. Stwórzmy bardziej praktyczną, wielousługową aplikację: stronę WordPress połączoną z bazą danych MySQL.

To ustawienie obejmuje dwie usługi: wordpress (uruchamiającą aplikację) i db (uruchamiającą bazę danych). Użyjemy również wolumenów Dockera, aby dane bazy danych były zachowane nawet po usunięciu kontenera.

Utwórzmy nowy katalog dla tej aplikacji:

mkdir -p ~/compose-demo/wordpressapp

cd ~/compose-demo/wordpressapp

W tym przykładzie nie potrzebujemy żadnych lokalnych plików, ponieważ obrazy będą zawierać całe niezbędne oprogramowanie.

Utwórz nowy plik docker-compose.yml:

nano docker-compose.yml

Wklej następującą konfigurację. Ten plik jest bardziej skomplikowany, więc przyjrzymy się każdej jego części.

services:
  db:
    image: mysql:8.0
    container_name: mysql_db
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: <^your_root_password_here<^>
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress_user
      MYSQL_PASSWORD: <^your_wordpress_password_here<^>
    restart: unless-stopped

  wordpress:
    image: wordpress:latest
    container_name: wordpress_app
    ports:
      - "8001:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress_user
      WORDPRESS_DB_PASSWORD: <^your_wordpress_password_here<^>
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp_content:/var/www/html/wp-content
    depends_on:
      - db
    restart: unless-stopped

volumes:
  db_data:

Uwaga: Wartości hasła zostały tutaj wpisane na sztywno w celach ilustracyjnych. Podczas używania w rzeczywistym środowisku upewnij się, że korzystasz ze zmiennych środowiskowych w pliku .env, aby nie ujawniać swoich danych uwierzytelniających.

Zapisz i zamknij plik. Pamiętaj, aby zastąpić znaczniki <^...^> silnymi, bezpiecznymi hasłami.

Rozbijmy nowe dyrektywy w tym pliku:

  • services: Ten blok wciąż definiuje nasze kontenery. Obecnie mamy dwa: db i wordpress.
  • image: Używamy mysql:8.0 dla bazy danych oraz obrazu wordpress:latest dla aplikacji.
  • container_name: Ustawia konkretną, czytelną nazwę dla kontenera, która jest łatwiejsza do odwoływania się niż automatycznie generowane nazwy.
  • environment: To lista zmiennych środowiskowych przekazywanych do kontenera. Obraz mysql używa ich do ustawienia hasła root oraz utworzenia początkowej bazy danych i użytkownika. Obraz wordpress używa ich, aby wiedzieć, jak połączyć się ze swoją bazą danych.
  • wolumeny (na poziomie usługi):

    • Dla usługi db, db_data:/var/lib/mysql mapuje wolumen zarządzany przez Dockera o nazwie db_data do katalogu danych MySQL wewnątrz kontenera. Dzięki temu Twoje dane są bezpieczne.
    • Dla serwisu wordpress, ./wp_content:/var/www/html/wp-content mapuje lokalny katalog (wp_content) na katalog zawartości WordPressa. Umożliwia to bezpośrednie edytowanie motywów i wtyczek z maszyny hosta.
  • depends_on: To mówi Compose, aby uruchomił usługę db przed uruchomieniem usługi wordpress. Jest to ważne, ponieważ WordPress nie uruchomi się, jeśli nie znajdzie swojej bazy danych podczas startu.
  • volumes (na najwyższym poziomie): Ten blok definiuje nazwane wolumeny. db_data: tworzy wolumen zarządzany przez Dockera, co jest preferowanym sposobem obsługi danych trwałych.

Teraz uruchom tę aplikację wieloserwisową:

docker compose up -d

Compose pobierze zarówno obrazy mysql, jak i wordpress, a następnie utworzy kontenery, uruchamiając najpierw usługę db.

Creating network "compose-demo_default" with the default driver
Creating volume "compose-demo_db_data" with default driver
Pulling db (mysql:8.0)...
...
Pulling wordpress (wordpress:latest)...
...
Creating mysql_db        ... done
Creating wordpress_app ... done

Teraz możesz uzyskać dostęp do swojej nowej strony WordPress, przechodząc w przeglądarce pod adres localhost:8001 lub <^twoja_domena_lub_IP_serwera<^>:8001. Powinieneś zobaczyć ekran instalacji WordPress. Dla bardziej szczegółowego przykładu, sprawdź nasz artykuł Jak Zainstalować WordPress za pomocą Docker Compose

Krok 6 — Wykorzystanie Docker Compose do rozwoju AI/ML

Poza zastosowaniami w aplikacjach internetowych, Docker Compose jest niezwykle przydatnym narzędziem do tworzenia powtarzalnych środowisk do nauki danych i uczenia maszynowego (AI/ML). Projekty AI/ML są znane ze swoich złożonych zależności, w tym konkretnych wersji Pythona, bibliotek takich jak TensorFlow czy PyTorch oraz sterowników systemowych, takich jak NVIDIA CUDA Toolkit. Docker Compose uchwyca całe to środowisko w plikach konfiguracyjnych, rozwiązując problem „u mnie działa”, który jest kluczowy dla powtarzalnych badań.

W tym przykładzie utworzysz środowisko AI/ML składające się z wielu usług, obejmujące:

  • JupyterLab: Kontener do interaktywnego rozwoju, zbudowany na podstawie niestandardowego Dockerfile.
  • PostgreSQL: Kontener bazy danych do przechowywania wyników eksperymentów i metadanych.
  • Dostęp do GPU: Kontener JupyterLab zostanie skonfigurowany tak, aby uzyskiwać dostęp do GPU NVIDIA na komputerze gospodarza, co jest częstym wymogiem przy trenowaniu modeli.

Wymagania wstępne: Ten przykład wymaga karty graficznej NVIDIA w twoim komputerze oraz zainstalowanego NVIDIA Container Toolkit. Bez tego kontener nie uruchomi się przy próbie użycia zasobów GPU.

Struktura plików

Najpierw stwórz katalog dla swojego projektu. W jego wnętrzu utworzysz plik docker-compose.yml, katalog jupyter, plik Dockerfile dla Jupytera oraz plik requirements.txt. Struktura powinna wyglądać mniej więcej tak:

ai-project/
├── docker-compose.yml
└── jupyter/
    ├── Dockerfile
    └── requirements.txt

Tworzenie plików komponentu

1. Plik requirements.txt

Ten plik zawiera listę pakietów Pythona dla Twojego środowiska do nauki o danych.

nano jupyter/requirements.txt

Dodaj wymagane pakiety. W tym przykładzie uwzględnimy biblioteki do manipulacji danymi, połączenia z bazą danych oraz frameworka do uczenia głębokiego.

pandas
scikit-learn
tensorflow
jupyterlab
psycopg2-binary

Zapisz i zamknij plik.

2. Plik Dockerfile

Ten plik definiuje Twój niestandardowy serwis JupyterLab. Używa oficjalnego obrazu Jupyter jako bazy i instaluje pakiety z pliku requirements.txt.

nano jupyter/Dockerfile

Wklej następującą treść:

# Start from a base image that includes Jupyter and scientific libraries
FROM jupyter/scipy-notebook:latest

# Copy our local requirements file into the container
COPY requirements.txt /tmp/requirements.txt

# Install the Python packages
RUN pip install --no-cache-dir -r /tmp/requirements.txt

Ten plik instruuje Dockera, aby używał jupyter/scipy-notebook jako punktu wyjścia, skopiował Twój requirements.txt do kontenera, a następnie użył pip do zainstalowania pakietów.

Definiowanie środowiska za pomocą docker-compose.yml

Teraz utwórz główny plik docker-compose.yml. Plik ten będzie orkiestracją zarówno usługi db, jak i Twojej niestandardowej usługi jupyter.

nano docker-compose.yml

Wklej poniższą konfigurację, zastępując miejsca oznaczone <^...^> własnymi bezpiecznymi danymi uwierzytelniającymi.

services:
  db:
    image: postgres:15-alpine
    container_name: ai_postgres_db
    environment:
      POSTGRES_USER: <^your_db_user^>
      POSTGRES_PASSWORD: <^your_db_pass^>
      POSTGRES_DB: experiments
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U <^your_db_user^> -d experiments"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - ai_net

  jupyter:
    build: ./jupyter
    container_name: ai_jupyter_lab
    ports:
      - "8888:8888"
    volumes:
      - ./notebooks:/home/jovyan/work
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_USER=<^your_db_user^>
      - POSTGRES_PASSWORD=<^your_db_pass^>
      - POSTGRES_DB=experiments
    restart: unless-stopped
    networks:
      - ai_net
    depends_on:
      db:
        condition: service_healthy
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

volumes:
  postgres_data:
    name: ai_project_data

networks:
  ai_net:
    driver: bridge

Ten plik konfiguracyjny wprowadza kilka ważnych pojęć:

  • build: ./jupyter: To mówi Docker Compose, aby zbudował własny obraz dla usługi jupyter. Szuka pliku Dockerfile w określonym katalogu ./jupyter.
  • volumes: - ./notebooks:/home/jovyan/work: Montuje lokalny katalog o nazwie notebooks w kontenerze. Zapewnia to, że wszystkie notatniki Jupyter, które utworzysz, będą zapisywane bezpośrednio na komputerze gospodarza, co pozwala zachować je nawet po usunięciu kontenera.
  • healthcheck: Jak widać w sekcji rozwiązywania problemów, ta kontrola sprawdza, czy usługa db nie tylko działa, ale jest gotowa do przyjmowania połączeń, zanim inne usługi się uruchomią.
  • depends_on: ... condition: service_healthy: To mówi serwisowi jupyter, aby poczekał na przejście testu stanu zdrowia db zanim się uruchomi.
  • deploy.resources.reservations.devices: To jest blok, który żąda dostępu do GPU.

    • driver: nvidia: Określa sterownik hosta, który ma być użyty.
    • count: 1: Żąda jednej karty GPU.
    • capabilities: [gpu]: Zapewnia, że kontener ma niezbędne możliwości do korzystania z GPU.

Uruchamianie środowiska AI/ML

Kiedy Twoje pliki są gotowe, możesz zbudować i uruchomić usługi.

  1. Z katalogu ai-project uruchom polecenie docker compose up. Za pierwszym razem musisz dodać flagę --build, aby poinformować Compose, żeby zbudował Twój niestandardowy obraz jupyter.

    docker compose up -d --build
  2. Compose najpierw zbuduje obraz jupyter (co może zająć kilka minut, ponieważ zostanie pobrany TensorFlow), następnie pobierze obraz postgres, a na końcu uruchomi oba kontenery.

    [+] Building 5.8s (9/9) FINISHED
     => [internal] load build definition from Dockerfile
    ...
    [+] Running 3/3
     ✔ Network ai-project_ai_net        Created
     ✔ Container ai_postgres_db         Started
     ✔ Container ai_jupyter_lab         Started
  3. Teraz możesz uzyskać dostęp do interfejsu JupyterLab, przechodząc w przeglądarce pod adres http://localhost:8888 (lub <^adres_twojego_serwera^>:8888). Zostaniesz poproszony o token, który można uzyskać z logów kontenera:

    docker compose logs jupyter

    Szukaj linii podobnej do http://127.0.0.1:8888/lab?token=a1b2c3d4e5f6...

  4. W notatniku Jupyter możesz teraz połączyć się z bazą danych, używając nazwy hosta db oraz podanych przez siebie danych uwierzytelniających. Twoje środowisko ma również dostęp do GPU hosta w celu trenowania modeli.

Skalowanie usług i korzystanie z sieci niestandardowych

Docker Compose zawiera funkcje umożliwiające skalowanie usług oraz zarządzanie sieciami, na których się komunikują.

Skalowanie usługi za pomocą replik

Wyobraź sobie, że Twój serwer Nginx z Kroku 2 otrzymuje zbyt duży ruch. Możesz skalować usługę web, aby uruchamiać wiele instancji kontenerów. Docker Compose może zarządzać tym automatycznie.

Istnieją dwa główne sposoby skalowania usługi.

1. Używanie klucza replicas (Preferowane w v2)

Możesz określić żądaną liczbę instancji bezpośrednio w swoim pliku docker-compose.yml używając kluczy deploy i replicas. Ta funkcja pierwotnie była częścią Docker Swarm, ale teraz jest dostępna również w standardowych wdrożeniach Compose.

Zmodyfikuj swój docker-compose.yml Nginx z Kroku 2:

services:
  web:
    image: nginx:alpine
    ports:
      - "8000:80"
    volumes:
      - ./app:/usr/share/nginx/html
    deploy:
      replicas: 3

Gdy uruchomisz docker compose up -d, Compose utworzy trzy kontenery web. Jednak pojawi się problem: wszystkie trzy będą próbowały powiązać się z portem hosta 8000. Spowoduje to błąd „port jest już przydzielony” dla drugiego i trzeciego kontenera. Aby rozwiązać to w środowisku produkcyjnym, należy usunąć mapowanie ports z usługi web. W ten sposób kontenery web będą dostępne tylko w ramach sieci Dockera. Oddzielna usługa load balancera byłaby jedyną posiadającą publiczny port. Następnie rozdzielałaby ruch do trzech replik web.

Przykładowa konfiguracja mogłaby wyglądać tak (to jest zaawansowany przykład):

services:
  web:
    image: nginx:alpine
    # No 'ports' mapping here.
    # The service is only accessible inside the 'web-net' network.
    volumes:
      - ./app:/usr/share/nginx/html
    deploy:
      replicas: 3
    networks:
      - web-net

  load_balancer:
    image: nginx:latest
    ports:
      - "80:80" # The load_balancer is the only service with a public port.
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf # A config file that load balances to 'web'.
    networks:
      - web-net
    depends_on:
      - web

networks:
  web-net:

W tym ustawieniu load_balancer nasłuchuje na porcie 80 i wewnętrznie kieruje żądania do web_1, web_2 i web_3.

Klucz replicas jest najbardziej przydatny, gdy jest używany z serwerem proxy odwrotnym (takim jak Traefik lub inna instancja Nginx), który może równoważyć obciążenie między replikami w sieci Docker, bez konieczności udostępniania każdego portu repliki na hoście.

2. Użycie flagi --scale

Powszechną metodą skalowania jest flaga --scale, pozostałość po Compose v1. Flaga ta jest stosowana w czasie wykonywania i nadpisuje dowolny klucz replicas.

Jednak musisz uważać na definicje portów. Jeśli twoja usługa definiuje statyczne mapowanie portu hosta (np. "8000:80"), uruchomienie docker compose up --scale spowoduje błąd dla drugiego i trzeciego kontenera, ponieważ wszystkie będą próbowały powiązać się z tym samym portem hosta.

Aby użyć --scale dla usług, które udostępniają porty, nie można używać stałego mapowania portów hosta.

  • Opcja 1: Mapowanie na losowe porty hosta (Dobre do rozwoju)

    Możesz zmodyfikować swój plik docker-compose.yml, aby określić tylko port kontenera. Informuje to Dockera, aby mapował port 80 w każdym kontenerze na losowy, dostępny port na maszynie hosta.

    services:
      web:
        image: nginx:alpine
        ports:
          - "80" # No fixed host port
        volumes:
          - ./app:/usr/share/nginx/html

    Teraz, gdy uruchomisz polecenie scale:

    docker compose up -d --scale web=3

    Uruchom docker compose ps, aby zobaczyć wynik. Każdy kontener będzie działał na innym, losowo przydzielonym porcie hosta:

          Name                     Command               State          Ports        
    ----------------------------------------------------------------------------------
    compose-demo_web_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:49154->80/tcp
    compose-demo-web_2   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:49155->80/tcp
    compose-demo-web_3   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:49156->80/tcp
  • docker-compose.yml - Poprawne dla --scale

  • Opcja 2: Użyj Reverse Proxy (Dobre dla produkcji)

    Innym rozwiązaniem, jak wspomniano w sekcji replicas, jest całkowite usunięcie dyrektywy ports z usługi web. Następnie można użyć oddzielnego kontenera z load balancerem (który posiada jedyny publiczny port) do zarządzania i rozdzielania ruchu pomiędzy skalowane repliki w obrębie sieci Dockera.

    Aby zatrzymać i usunąć wszystkie trzy kontenery, polecenie pozostaje takie samo:

    docker compose down

Niestandardowa konfiguracja sieci

Domyślnie Docker Compose tworzy jedną sieć bridge dla Twojej aplikacji. Każda usługa w pliku jest do niej podłączona, co pozwala kontenerowi wordpress znaleźć kontener db po prostu używając jego nazwy usługi (db).

Możesz jednak zdefiniować własne niestandardowe sieci, aby uzyskać lepszą izolację i kontrolę.

Zmodyfikujmy przykład WordPress, aby używał niestandardowej sieci bridge.

services:
  db:
    image: mysql:8.0
    ...
    networks:
      - app_net

  wordpress:
    image: wordpress:latest
    ...
    ports:
      - "8001:80"
    depends_on:
      - db
    networks:
      - app_net

volumes:
  db_data:

networks:
  app_net:
    driver: bridge

Oto, co dodaliśmy:

  • networks (główny poziom): To definiuje nową sieć o nazwie app_net i określa, że powinna używać standardowego sterownika bridge.
  • networks (poziom serwisu): Zarówno pod db, jak i wordpress, ten klucz podłącza je do naszej sieci app_net.

Gdybyś miał trzecią usługę (taką jak narzędzie analityczne), której nie podłączyłeś do app_net, byłaby całkowicie izolowana i nie mogłaby komunikować się z kontenerami db ani wordpress.

Dla klastrowania wieloserwerowego z Docker Swarm, należy zmienić driver z bridge na overlay. Sterownik bridge służy do komunikacji między kontenerami na jednym hoście, co jest standardem w większości przypadków użycia Docker Compose.

Używanie modułowych plików konfiguracyjnych

W miarę rozwoju twoich aplikacji, plik docker-compose.yml może stać się duży i trudny do zarządzania. Docker Compose obsługuje dyrektywę include, która pozwala podzielić konfigurację na wiele plików.

Wyobraź sobie, że chcesz oddzielić definicje WordPressa i bazy danych, a być może mieć wspólny plik docker-compose.override.yml dla ustawień specyficznych dla środowiska deweloperskiego (na przykład przypisywanie portu do bazy danych).

Twoja struktura katalogów może wyglądać tak:

compose-demo/
├── docker-compose.yml
├── docker-compose.db.yml
├── docker-compose.web.yml

Ten plik tylko zdefiniuje usługę db.

services:
  db:
    image: mysql:8.0
    container_name: mysql_db
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: <^your_root_password_here<^>
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress_user
      MYSQL_PASSWORD: <^your_wordpress_password_here<^>
    restart: unless-stopped

volumes:
  db_data:

Ten plik tylko zdefiniuje usługę wordpress.

services:
  wordpress:
    image: wordpress:latest
    container_name: wordpress_app
    ports:
      - "8001:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress_user
      WORDPRESS_DB_PASSWORD: <^your_wordpress_password_here<^>
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp_content:/var/www/html/wp-content
    depends_on:
      - db
    restart: unless-stopped

Teraz Twój główny plik docker-compose.yml staje się bardzo prosty. Używa po prostu include, aby wczytać inne pliki.

include:
  - docker-compose.db.yml
  - docker-compose.web.yml

Kiedy uruchamiasz docker compose up -d, Compose odczyta wszystkie trzy pliki, połączy konfiguracje i uruchomi usługi db i wordpress, tak jakby były zdefiniowane w jednym pliku. Takie podejście sprawia, że Twoja konfiguracja jest znacznie bardziej modułowa i wielokrotnego użytku.

Uwaga: Dyrektywa include: wymaga Docker Compose w wersji 2.20 lub nowszej. Jeśli Twój system używa starszej wersji, możesz połączyć pliki za pomocą docker compose -f docker-compose.db.yml -f docker-compose.web.yml up.

Migracja z docker-compose (v1) do docker compose (v2)

Polecenie docker compose, które zainstalowałeś w Kroku 1, to „Compose v2.” Jest to wtyczka oparta na języku Go, wbudowana bezpośrednio w CLI Dockera.

Oryginalna wersja, „Compose v1”, była osobnym narzędziem w Pythonie wywoływanym za pomocą docker-compose (z myślnikiem). Od lipca 2023 r. Compose v1 nie jest już wspierany i został przestarzały.

Kluczowe zmiany i zgodność wsteczna

  • Komenda: Najbardziej oczywistą zmianą jest sama komenda. Myślnik (docker-compose) został teraz zastąpiony spacją (docker compose).
  • Instalacja: wersja v1 została zainstalowana za pomocą pip. Wersja v2 jest dołączona do Docker Desktop lub zainstalowana jako wtyczka CLI, tak jak zrobiłeś w Kroku 1.
  • Pliki YAML: Twoje pliki docker-compose.yml są prawie w 100% kompatybilne wstecz. Compose w wersji v2 w pełni obsługuje wersje plików 3.x. Nie musisz zmieniać swoich plików YAML przy migracji, tylko swoje polecenia.
  • --project-name flaga: Flaga -p nadal działa, ale pełna flaga to teraz --project-name zamiast --project_name.

Przewodnik po migracji poleceń

Większość poleceń jest identyczna, tylko bez myślnika. Oto tabela porównująca popularne polecenia v1 z ich odpowiednikami w v2.

Polecenie docker-compose (v1)Polecenie docker compose (v2)Notatki
docker-compose up -d
docker compose up -d
Brak zmian w składni.
docker-compose down
docker compose down
Brak zmian w składni.
docker-compose ps
docker compose ps
Brak zmian w składni.
docker-compose logs
docker compose logs
Brak zmian w składni.
docker-compose stop
docker compose stop
Brak zmian w składni.
docker-compose build
docker compose build
Brak zmian w składni.
docker-compose exec web bash
docker compose exec web bash
Brak zmian w składni.
docker-compose run web bash
docker compose run web bash
run tworzy nowy kontener. exec uruchamia się w istniejącym.
docker-compose up --scale web=3
docker compose up --scale web=3
Flaga --scale jest nadal obsługiwana w wersji v2.

Jak widać, w przypadku większości codziennego użycia jedyną zmianą jest docker-compose -> docker compose. Jeśli używasz skryptów, możesz je zaktualizować, po prostu usuwając myślnik.

Jeśli nadal masz zainstalowaną starą wersję docker-compose v1, możesz ją usunąć, aby uniknąć zamieszania:

sudo pip3 uninstall docker-compose

Lub, jeśli został zainstalowany przez apt:

sudo apt remove docker-compose

Rozwiązywanie typowych problemów z Docker Compose

Kiedy pracujesz z Docker Compose, możesz napotkać problemy związane ze składnią plików, uprawnieniami lub konfliktami podczas działania kontenerów. Większość problemów można zdiagnozować i rozwiązać, systematycznie sprawdzając konfigurację, uprawnienia i logi kontenerów.

Przyjrzyjmy się niektórym z najczęstszych błędów i ich rozwiązaniom.

Odmowa dostępu (Gniazdo Dockera)

Jest to jeden z najczęstszych błędów wśród nowych użytkowników Dockera. Uruchamiasz docker compose up i widzisz komunikat o błędzie dotyczący gniazda demona Dockera.

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
  • Problem: Twój użytkownik bez uprawnień administratora nie ma dostępu do komunikacji z demonem Dockera, który działa jako root.

  • Rozwiązanie: Musisz dodać swojego użytkownika do grupy docker, która została utworzona podczas instalacji Dockera.

    1. Dodaj swojego użytkownika do grupy docker:

      sudo usermod -aG docker ${USER}
    2. Aby nowe członkostwo w grupie zaczęło obowiązywać, musisz się wylogować i zalogować ponownie.

    3. Alternatywnie, możesz aktywować zmiany grup dla bieżącej sesji terminala, wpisując:

      newgrp docker

    To powinno rozwiązać wszelkie błędy związane z uprawnieniami względem gniazda Dockera.

Błędy składni i wcięć w YAML

Docker Compose nie uruchamia się i zgłasza, że Twój plik docker-compose.yml jest nieprawidłowy.

ERROR: The Compose file './docker-compose.yml' is invalid because:
services.web.ports contains an invalid type, it should be a list

Lub :

mapping values are not allowed in this context at line 5
  • Problem: Plik docker-compose.yml opiera się na ścisłej składni YAML. Najczęstszym błędem jest niepoprawne wcięcie. YAML używa spacji, a nie tabulatorów, do definiowania struktury.
  • Rozwiązanie: Dokładnie sprawdź wcięcia w pliku docker-compose.yml.

    • Standardem jest dwie spacje dla każdego poziomu wcięcia.
    • Upewnij się, że wszystkie klucze na tym samym poziomie (takie jak version, services, volumes) zaczynają się w tej samej kolumnie.
    • Upewnij się, że wszystkie podklucze (takie jak image, ports, volumes pod usługą) są wcięte o dwie spacje więcej niż ich nadrzędna usługa (np. web).
    • Użyj edytora kodu z linterem YAML, aby automatycznie podświetlał błędy składni.

Konflikty portów

Próbujesz uruchomić swoje środowisko, ale polecenie kończy się błędem informującym, że adres jest już używany.

Error starting userland proxy: listen tcp 0.0.0.0:8000: bind: address already in use
  • Problem: Inny proces na twoim komputerze już nasłuchuje na porcie, który próbujesz przypisać (w tym przypadku na porcie 8000). Często jest to inny kontener Dockera lub lokalny serwer deweloperski.

  • Rozwiązanie: Masz dwie opcje:

    1. Zatrzymaj inny proces. Proces używający portu możesz znaleźć za pomocą tego polecenia:

      sudo lsof -i :8000

      Jeśli jest to inny kontener Dockera, zatrzymaj go za pomocą docker stop <container_id>.

    2. Zmień port hosta w swoim pliku docker-compose.yml. Często jest to najprostsze rozwiązanie. Zmień mapowanie ports z "8000:80" na inny port, na przykład "8001:80".

      ...
      ports:
        - "8001:80" # Changed from 8000
      ...
    3. docker-compose.yml

Usługa kończy się błędem Połączenie odrzucone (depends_on)

W aplikacji wielousługowej (takiej jak przykład WordPress i MySQL), kontener wordpress uruchamia się, ale w jego logach pojawia się Connection refused lub MySQL server has gone away podczas próby połączenia się z usługą db.

  • Problem: Użyłeś depends_on, ale ta dyrektywa czeka tylko, aż kontener db uruchomi się. Nie czeka na to, aż aplikacja MySQL wewnątrz kontenera zostanie w pełni zainicjalizowana i będzie gotowa do przyjmowania połączeń.

  • Rozwiązanie: Aplikacja (w tym przypadku WordPress) musi być skonfigurowana tak, aby ponawiała próbę połączenia. Większość nowoczesnych obrazów ma wbudowaną tę logikę ponawiania. Dla obrazów, które jej nie mają, należy wdrożyć kontrolę stanu (healthcheck).

    Możesz dodać healthcheck do swojej usługi db. Następnie depends_on usługi wordpress można skonfigurować tak, aby czekała na to, aż baza danych będzie „zdrowa”, a nie tylko „uruchomiona”.

Przykładowa kontrola stanu MySQL:

services:
  db:
    image: mysql:8.0
    ...
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p<^your_root_password_here<^>"]
      interval: 10s
      timeout: 5s
      retries: 5

  wordpress:
    image: wordpress:latest
    ...
    depends_on:
      db:
        condition: service_healthy # This now waits for the healthcheck
    ...

Błędy związane z woluminami i montowaniem katalogów

Możesz napotkać błędy uprawnień w logach kontenera lub zauważyć, że katalog danych twojego kontenera jest pusty.

Uprawnienia pliku/katalogu

  • Problem: Kontener działa jako konkretny użytkownik (np. www-data o identyfikatorze użytkownika 33), ale katalog hosta, który zamontowałeś, należy do Twojego użytkownika (np. ubuntu o identyfikatorze użytkownika 1000). Użytkownik kontenera nie ma uprawnień do zapisu w katalogu hosta.

  • Rozwiązanie: Zmień właściciela katalogu hosta, aby odpowiadał identyfikatorowi użytkownika wewnątrz kontenera. Możesz znaleźć identyfikator użytkownika kontenera, uruchamiając docker compose exec <service_name> id. Na przykład, jeśli ID to 33 (często dla www-data):

    sudo chown -R 33:33 ./wp_content

Problemy ze ścieżką względną

  • Problem: Twój plik docker-compose.yml używa ścieżki względnej takiej jak ./app, ale plik index.html nie jest serwowany.

  • Rozwiązanie: Docker Compose interpretuje ścieżki względne w odniesieniu do katalogu, w którym uruchamiasz polecenie docker compose up. Zawsze uruchamiaj polecenia Compose z tego samego katalogu, który zawiera plik docker-compose.yml.

Sieciowanie i wykrywanie usług

Logi kontenera Twojej aplikacji pokazują Nie znaleziono hosta lub Nie można rozpoznać hosta: db.

  • Problem: Twój kontener wordpress nie może znaleźć kontenera db w sieci.
  • Rozwiązanie: Domyślnie Docker Compose tworzy sieć i podłącza do niej wszystkie usługi. Usługi mogą się wzajemnie odnaleźć, używając swoich nazw usług.

    1. Sprawdź nazwy usług: Upewnij się, że nazwa hosta w konfiguracji Twojej aplikacji (np. zmienna środowiskowa WORDPRESS_DB_HOST) jest dokładnie taka sama jak nazwa usługi w pliku docker-compose.yml (np. db).

    2. Sprawdź sieć: Użyj docker compose ps, aby znaleźć nazwę swojego projektu (np. compose-demo). Następnie sprawdź domyślną sieć:

      docker network inspect compose-demo_default

      Dane wyjściowe JSON wyświetlą wszystkie kontenery podłączone do tej sieci. Jeśli brakuje któregoś z twoich usług, sprawdź plik docker-compose.yml pod kątem jakiejkolwiek niestandardowej konfiguracji networks, która mogłaby ją izolować.

Niezgodność poleceń (v1 vs. v2)

Wpisujesz docker-compose up (z myślnikiem) i pojawia się błąd „polecenie nie zostało znalezione”.

docker-compose: command not found
  • Problem: Próbujesz użyć polecenia dla Compose v1, które jest przestarzałym narzędziem w Pythonie. Ten przewodnik instaluje Compose v2, który jest wtyczką zintegrowaną bezpośrednio z CLI Dockera.
  • Rozwiązanie: Użyj poprawnej komendy, zastępując myślnik (-) spacją.
docker-compose (v1)docker compose (v2)
docker-compose updocker compose up
docker-compose downdocker compose down
docker-compose psdocker compose ps
docker-compose logsdocker compose logs

Zawsze używaj docker compose (spacja) podczas korzystania z tego przewodnika.

Najczęściej zadawane pytania

1. Do czego służy Docker Compose?

Docker Compose to narzędzie do definiowania i uruchamiania wielokontenerowych aplikacji Docker.

Do konfiguracji wszystkich komponentów aplikacji, zwanych usługami, używa jednego pliku YAML (domyślnie docker-compose.yml). Plik ten definiuje również sieci, które pozwalają usługom komunikować się ze sobą, oraz woluminy używane do przechowywania danych trwałych.

Dzięki temu pojedynczemu plikowi możesz zarządzać całym stosem aplikacji za pomocą prostych poleceń:

  • docker compose up uruchamia całą Twoją aplikację, w tym wszystkie określone kontenery, sieci i wolumeny.
  • docker compose down zatrzymuje i usuwa wszystkie kontenery, sieci i wolumeny utworzone przez Twoją aplikację.

Jest to najbardziej przydatne do zarządzania aplikacjami, które wymagają wielu komponentów, takimi jak strona internetowa potrzebująca serwera WWW (np. Nginx), zaplecza aplikacji (np. WordPress) i bazy danych (np. MySQL).

2. Jak zainstalować Docker Compose na Ubuntu?

Zalecana metoda to zainstalowanie Docker Compose jako wtyczki do interfejsu wiersza poleceń Docker. Robi się to, instalując pakiet docker-compose-plugin z oficjalnego repozytorium apt Dockera.

  1. Najpierw upewnij się, że postępowałeś zgodnie z oficjalną dokumentacją Dockera, aby skonfigurować repozytorium apt Dockera na swoim systemie Ubuntu.

  2. Zaktualizuj listę pakietów:

    sudo apt update
  3. Zainstaluj wtyczkę Docker Compose:

    sudo apt install docker-compose-plugin
  4. Zweryfikuj instalację, sprawdzając wersję. Polecenie używa spacji, a nie myślnika.

    docker compose version

3. Jak zaktualizować Docker Compose do najnowszej wersji?

Ponieważ Docker Compose (v2) jest zainstalowany jako pakiet systemowy przy użyciu apt, możesz go aktualizować za pomocą standardowego procesu aktualizacji oprogramowania Ubuntu.

  1. Odśwież lokalny indeks pakietów:

    sudo apt update
  2. Uruchom aktualizację całego systemu, która obejmie wtyczkę Compose:

    sudo apt upgrade

    Alternatywnie, jeśli chcesz zaktualizować tylko samą wtyczkę, możesz uruchomić:

    sudo apt install --only-upgrade docker-compose-plugin

4. Czy Docker Compose może być używany w środowiskach produkcyjnych?

Tak, Docker Compose jest często używany w produkcji, szczególnie w przypadku aplikacji działających na jednym hoście.

Zapewnia prosty sposób na definiowanie, wdrażanie i zarządzanie cyklem życia usług, sieci i wolumenów twojej aplikacji. W przypadku wdrożenia na jednym serwerze jest to bardzo skuteczne i łatwe do zarządzania rozwiązanie.

W przypadku bardziej złożonych scenariuszy, które wymagają koordynowania kontenerów między wieloma hostami (klastrem), częściej używa się innych narzędzi. Należą do nich Docker Swarm (który wykorzystuje podobną składnię plików Compose) oraz Kubernetes (który jest standardem branżowym w zakresie orkiestracji kontenerów na dużą skalę).

5. Jaka jest różnica między Docker a Docker Compose?

Ta tabela przedstawia główne różnice między interfejsem wiersza poleceń Dockera a interfejsem wiersza poleceń Docker Compose.

Funkcjadocker (Silnik Docker)docker compose (wtyczka Compose)
ZakresZarządza pojedynczymi obiektami Dockera.Zarządza kompletną, wielokontenerową aplikacją jako jedną jednostką.
Główne zastosowanieTworzenie obrazów (docker build), uruchamianie pojedynczych kontenerów (docker run), zarządzanie kontenerami (docker ps), obrazami, wolumenami i sieciami.Orkiestracja wielu usług zdefiniowanych w pliku docker-compose.yml.
PoleceniaPolecenia niskiego poziomu skoncentrowane na jednym obiekcie. Przykład: docker run -d -p 80:80 -v ./:/app nginxPolecenia wysokiego poziomu dla całej aplikacji. Przykład: docker compose up
AnalogiaPojedynczy element konstrukcyjny (pojedynczy kontener).Projekt i kierownik budowy całego budynku (zgłoszenia).

Krótko mówiąc, używasz docker, aby współpracować z pojedynczym kontenerem. Używasz docker compose, aby zarządzać całym stosem aplikacji (np. web, app, db) jednocześnie.

6. Jak uruchomić wiele kontenerów za pomocą Docker Compose?

Uruchamiasz wiele kontenerów, definiując je jako usługi w pliku docker-compose.yml.

  1. Utwórz plik o nazwie docker-compose.yml.

  2. W tym pliku użyj klucza services:, aby zdefiniować każdy kontener, który chcesz uruchomić.

    Oto praktyczny przykład, który definiuje i uruchamia dwa kontenery: stronę WordPress i bazę danych MySQL.

    services:
      db:
        # This is the first service (container)
        image: mysql:8.0
        environment:
          MYSQL_ROOT_PASSWORD: <^your_password_here<^>
          MYSQL_DATABASE: wordpress
        volumes:
          - db_data:/var/lib/mysql
    
      wordpress:
        # This is the second service (container)
        image: wordpress:latest
        ports:
          - "8001:80"
        environment:
          WORDPRESS_DB_HOST: db
          WORDPRESS_DB_PASSWORD: <^your_password_here<^>
        depends_on:
          - db
    
    volumes:
      db_data:
  3. docker-compose.yml

  4. Zapisz plik i otwórz terminal w tym samym katalogu.

  5. Uruchom jedno polecenie, aby startować oba kontenery:

    docker compose up -d

Docker Compose odczyta plik, utworzy wspólną sieć dla usług, pobierze obrazy mysql i wordpress oraz uruchomi kontener dla każdej usługi.

7. Dlaczego warto używać Docker Compose do tworzenia aplikacji?

Docker Compose to standardowe narzędzie w środowiskach deweloperskich, ponieważ rozwiązuje kilka powszechnych problemów.

  • Spójne środowiska: Zapewnia, że każdy deweloper w zespole uruchamia dokładnie te same usługi (baza danych, pamięć podręczna, serwer WWW) z dokładnie takimi samymi wersjami i konfiguracjami. Jest to zdefiniowane w pliku docker-compose.yml, który jest dodawany do kontroli wersji. To eliminuje problem „u mnie działa”.

  • Prostota: Zastępuje skomplikowane skrypty instalacyjne i długie polecenia docker run. Programista musi jedynie uruchomić docker compose up, aby uruchomić cały stos aplikacji, oraz docker compose down, aby go zatrzymać.

  • Izolacja usług: Programiści mogą pracować nad wieloma projektami na tym samym komputerze bez konfliktów zależności. Projekt A może korzystać z PostgreSQL 9.6, a Projekt B z PostgreSQL 14, ponieważ każda baza danych działa w izolowanym kontenerze zarządzanym przez własny plik Compose.

  • Łatwe testowanie integracyjne: Ponieważ Compose uruchamia wszystkie zależności aplikacji razem, tworzy idealne lokalne środowisko do przeprowadzania testów integracyjnych, które sprawdzają, jak usługi współdziałają ze sobą.

Wniosek

W tym przewodniku zainstalowałeś Docker Compose i skonfigurowałeś kompletną aplikację wielokontenerową. Zacząłeś od podstawowego pliku docker-compose.yml dla serwera internetowego Nginx, a następnie przeszedłeś do bardziej złożonego, realistycznego środowiska obejmującego aplikację WordPress i bazę danych MySQL. Nauczyłeś się zarządzać całym cyklem życia aplikacji, od budowania i uruchamiania usług po ich zatrzymywanie i usuwanie.

Teraz znasz kluczowe pojęcia związane z efektywnym zarządzaniem aplikacjami, w tym skalowanie usług, niestandardowe definicje sieci oraz dzielenie konfiguracji na modułowe pliki za pomocą dyrektywy include. Postępując zgodnie z przewodnikiem migracji i krokami rozwiązywania problemów, możesz również rozwiązać typowe problemy, takie jak konflikty portów, błędy „Permission denied” oraz błędy składni YAML. Umiejętności omówione tutaj pozwolą Ci tworzyć spójne, powtarzalne środowiska deweloperskie i pewnie wdrażać aplikacje na pojedynczym hoście.

Aby uzyskać pełne informacje o wszystkich dostępnych poleceniach docker compose, sprawdź oficjalną dokumentację.

Aby uzyskać więcej samouczków związanych z Dockerem, zapoznaj się z następującymi artykułami:

  • Jak zainstalować Docker na Ubuntu – przewodnik krok po kroku
  • Jak zainstalować WordPress za pomocą Docker Compose

Dziękujemy za naukę z społecznością Linux-Console.net.