Cum să instalezi și să folosești Docker Compose pe Ubuntu


Introducere

Docker simplifică procesul de gestionare a proceselor aplicațiilor în containere. Deși containerele sunt asemănătoare cu mașinile virtuale în anumite privințe, ele sunt mai ușoare și mai prietenoase cu resursele. Acest lucru le permite dezvoltatorilor să împartă mediul unei aplicații în mai multe servicii izolate.

Pentru aplicațiile care depind de mai multe servicii, orchestrarea tuturor containerelor pentru a porni, a comunica și a se opri împreună poate deveni rapid dificil de gestionat. Docker Compose este un instrument care îți permite să rulezi medii de aplicații cu mai multe containere, bazate pe definiții stabilite într-un fișier YAML. Acesta folosește definiții de servicii pentru a construi medii complet personalizabile cu mai multe containere care pot partaja rețele și volume de date.

Acest ghid te va ajuta să instalezi Docker Compose pe un server Ubuntu și să rulezi un container simplu. De acolo, vei învăța să construiești un mediu cu mai multe servicii folosind o aplicație WordPress și o bază de date MySQL. Vom aborda, de asemenea, subiecte mai avansate, inclusiv scalarea serviciilor, definirea rețelelor personalizate și utilizarea directivelor modulare include. În final, acest articol oferă un ghid de migrare de la vechiul docker-compose (v1) la modernul docker compose (v2) și o secțiune detaliată despre rezolvarea problemelor comune, cum ar fi conflictele de porturi și erorile de permisiuni.

Aspecte principale:

  • Docker Compose este un instrument pentru definirea și rularea aplicațiilor cu mai multe containere, folosind un singur fișier YAML pentru a configura serviciile, rețelele și volumele.
  • Docker Compose este instalat pe Ubuntu prin adăugarea depozitului oficial Docker și folosind apt pentru a instala pachetul docker-compose-plugin.
  • Comanda modernă este docker compose (cu un spațiu). Aceasta înlocuiește instrumentul v1 învechit docker-compose (cu cratimă).
  • Folosește docker compose up -d pentru a porni o aplicație în modul detașat și docker compose down pentru a opri și elimina toate containerele și rețelele acesteia.
  • Directiva depends_on ajută la controlul ordinii de pornire a serviciilor, de exemplu, asigurându-se că un container de bază de date pornește înaintea unui container de aplicație web.
  • Cele mai frecvente probleme sunt „Permisiune Refuzată” (rezolvată prin adăugarea utilizatorului tău în grupul docker), conflictele de porturi (rezolvate prin schimbarea portului host în fișierul YAML) și erorile de sintaxă YAML (rezolvate prin corectarea indentării).
  • Poți rula mai multe instanțe ale unui serviciu folosind comanda docker compose up --scale <service_name>=<number>.
  • Directiva include îți permite să împarți un fișier docker-compose.yml mare în fișiere de configurare mai mici și mai ușor de gestionat.

Cerințe prealabile

Pentru a urma acest articol, vei avea nevoie de:

  • Acces la o mașină locală Ubuntu sau un server de dezvoltare ca utilizator non-root cu privilegii sudo. Dacă folosești un server de la distanță, este recomandat să ai un firewall activ instalat. Pentru a configura aceste lucruri, te rugăm să consulți Ghidul nostru de Configurare Inițială a Serverului pentru Ubuntu.
  • Docker instalat pe serverul sau pe calculatorul tău local, urmând Pașii 1 și 2 din Cum să instalezi Docker pe Ubuntu – Ghid pas cu pas.

Notă: Începând cu Docker Compose v2, Docker a migrat către utilizarea comenzii plugin CLI compose și s-a îndepărtat de docker-compose original, așa cum este documentat în ghidul nostru Cum să Instalezi Docker Compose pe Ubuntu (Ghid Pas cu Pas). Deși instalarea diferă, în general utilizarea efectivă implică eliminarea cratimei din apelurile docker-compose pentru a deveni docker compose. Pentru detalii complete despre compatibilitate, consultați documentația oficială Docker privind compatibilitatea comenzilor între noul compose și vechiul docker-compose.

Pasul 1 — Instalarea Docker Compose

Există două modalități de a instala Docker Compose pe Ubuntu:

  • Instalează folosind depozitul
  • Instalează manual

Vom discuta ambele moduri în această secțiune.

Instalarea Docker Compose folosind depozitul apt

Mai întâi, să configurăm depozitul 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

Acum, poți instala Docker Compose folosind următoarea comandă:

sudo apt install docker-compose-plugin

Docker Compose este acum instalat cu succes pe sistemul dumneavoastră. Pentru a verifica dacă instalarea a fost realizată cu succes, puteți rula:

docker compose version

Veți vedea un rezultat similar cu acesta:

Docker Compose version v2.3.3

Instalarea Docker Compose manual

Pentru a te asigura că obții cea mai recentă versiune stabilă a Docker Compose, vei descărca acest software din depozitul său oficial de pe Github.

Mai întâi, confirmă cea mai recentă versiune disponibilă pe pagina lor de release-uri. În momentul scrierii acestui text, cea mai actuală versiune stabilă este v2.40.2.

Folosește următoarea comandă pentru a descărca:

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

Apoi, setează permisiunile corecte astfel încât comanda docker compose să poată fi executată:

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

În secțiunea următoare, vei vedea cum să configurezi un fișier docker-compose.yml și să pui în funcțiune un mediu containerizat cu acest instrument.

Pasul 2 — Configurarea unui fișier docker-compose.yml

Pentru a demonstra cum să configurezi un fișier docker-compose.yml și să lucrezi cu Docker Compose, vei crea un mediu de server web folosind imaginea oficială Nginx de pe Docker Hub, registrul public Docker. Acest mediu containerizat va servi un singur fișier HTML static.

Începe prin a crea un director nou în folderul tău de acasă, apoi intră în el:

mkdir ~/compose-demo

cd ~/compose-demo

În acest director, configurează un folder pentru aplicație care să servească drept rădăcină a documentelor pentru mediul tău Nginx:

mkdir app

Folosind editorul de text preferat, creează un nou fișier index.html în interiorul folderului app:

nano app/index.html

Plasați următorul conținut în acest fișier:

<!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>

Salvează și închide fișierul când ai terminat. Dacă folosești nano, poți face asta tastând CTRL+X, apoi Y și ENTER pentru a confirma.

În continuare, creați fișierul docker-compose.yml:

nano docker-compose.yml

Introduceți următorul conținut în fișierul dvs. docker-compose.yml:

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

În Docker Compose modern, câmpul version este opțional și adesea omis, deoarece Compose poate detecta automat versiunea configurației. Exemplul de mai sus nu include un câmp version, ceea ce este abordarea recomandată pentru majoritatea proiectelor noi. Trebuie să specificați version doar pentru compatibilitate cu versiunile mai vechi.

Apoi ai blocul services, unde configurezi serviciile care fac parte din acest mediu. În cazul tău, ai un singur serviciu numit web. Acest serviciu folosește imaginea nginx:alpine și configurează o redirecționare a portului cu directiva ports. Toate solicitările pe portul 8000 al mașinii gazdă (sistemul de pe care rulezi Docker Compose) vor fi redirecționate către containerul web pe portul 80, unde va rula Nginx.

Directiva volumes va crea un volum partajat între mașina gazdă și container. Acest lucru va partaja folderul local app cu containerul, iar volumul va fi localizat la /usr/share/nginx/html în interiorul containerului, ceea ce va suprascrie rădăcina implicită a documentelor pentru Nginx.

Salvează și închide fișierul.

Ați configurat o pagină demo și un fișier docker-compose.yml pentru a crea un mediu de server web containerizat care o va servi. În pasul următor, veți ridica acest mediu cu Docker Compose.

Pasul 3 — Rularea Docker Compose

Cu fișierul docker-compose.yml la locul său, poți acum să execuți Docker Compose pentru a porni mediul tău. Comanda următoare va descărca imaginile Docker necesare, va crea un container pentru serviciul web și va rula mediul containerizat în modul background:

docker compose up -d

Docker Compose va căuta mai întâi imaginea definită pe sistemul tău local și, dacă nu poate găsi imaginea, o va descărca de pe Docker Hub. Vei vedea un output de genul acesta:

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

Notă: Dacă întâlniți o eroare „permisiune refuzată” atunci când rulați docker compose up, aceasta înseamnă de obicei că utilizatorul dumneavoastră non-root nu are permisiunea de a accesa socketul daemon-ului Docker.

Implicit, daemonul Docker se leagă la un socket Unix (/var/run/docker.sock) care este deținut de utilizatorul root. Pentru a remedia acest lucru, trebuie să adăugați utilizatorul non-root în grupul docker, care este creat în timpul instalării Docker.

Rulați următoarea comandă pentru a adăuga utilizatorul dvs. în grupul docker:

sudo usermod -aG docker ${USER}

După executarea acestei comenzi, va trebui să te deloghezi și să te loghezi din nou pentru ca modificările grupului să intre în vigoare. De asemenea, poți activa modificările pentru sesiunea curentă de terminal tastând:

newgrp docker

Această comandă ar trebui să rezolve orice erori de permisiuni legate de socket-ul Docker. Pentru un ghid complet, vă rugăm să consultați Pasul 2 din Cum să instalați Docker pe Ubuntu – Ghid pas cu pas.

Mediul tău este acum funcțional în fundal. Pentru a verifica dacă containerul este activ, poți rula:

docker compose ps

Această comandă vă va arăta informații despre containerele care rulează și starea lor, precum și orice redirecționări de porturi aflate în prezent în vigoare:

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

Acum puteți accesa aplicația demo indicând browserul către localhost:8000 dacă rulați această demonstrație pe calculatorul dumneavoastră local, sau domeniul_sau_IP-ul_serverului_dumneavoastră:8000 dacă rulați această demonstrație pe un server la distanță.

Vei vedea o pagină ca aceasta:

Volumul partajat pe care l-ai configurat în fișierul docker-compose.yml menține fișierele din folderul tău app sincronizate cu rădăcina documentului din container. Dacă faci modificări în fișierul index.html, acestea vor fi preluate automat de container și vor fi astfel reflectate în browserul tău atunci când reîncarci pagina.

În următorul pas, vei vedea cum să gestionezi mediul tău containerizat folosind comenzile Docker Compose.

Pasul 4 — Familiarizarea cu comenzile Docker Compose

Ai văzut cum să configurezi un fișier docker-compose.yml și să pornești mediul tău cu docker compose up. Acum vei vedea cum să folosești comenzile Docker Compose pentru a gestiona și a interacționa cu mediul tău containerizat.

Pentru a verifica jurnalele generate de containerul tău Nginx, poți folosi comanda logs:

docker compose logs

Veți vedea un rezultat similar cu acesta:

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" "-"

Dacă doriți să puneți în pauză execuția mediului fără a schimba starea curentă a containerelor dvs., puteți folosi:

docker compose pause
Pausing compose-demo_web_1 ... done

Pentru a relua executarea după ce ați întrerupt:

docker compose unpause
Unpausing compose-demo_web_1 ... done

Comanda stop va opri executarea containerului, dar nu va șterge niciunul dintre datele asociate containerelor tale:

docker compose stop
Stopping compose-demo_web_1 ... done

Dacă doriți să eliminați containerele, rețelele și volumele asociate acestui mediu containerizat, folosiți comanda down:

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

Rețineți că acest lucru nu va elimina imaginea de bază folosită de Docker Compose pentru a porni mediul dvs. (în cazul dvs., nginx:alpine). Astfel, ori de câte ori porniți din nou mediul cu docker compose up, procesul va fi mult mai rapid deoarece imaginea este deja pe sistemul dvs.

În cazul în care doriți să eliminați și imaginea de bază de pe sistemul dumneavoastră, puteți folosi:

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

Notă: Vă rugăm să consultați ghidul nostru despre Cum să instalați Docker pe Ubuntu – Ghid pas cu pas pentru o referință mai detaliată privind comenzile Docker.

Pasul 5 — Crearea unei aplicații cu mai multe servicii

Adevărata putere a Docker Compose constă în gestionarea mai multor servicii care lucrează împreună. Exemplul cu Nginx a fost un serviciu unic. Să creăm o aplicație mai practică, cu mai multe servicii: un site WordPress conectat la o bază de date MySQL.

Această configurație implică două servicii: wordpress (care rulează aplicația) și db (care rulează baza de date). De asemenea, vom folosi volume Docker pentru a ne asigura că datele din baza de date persistă chiar dacă containerul este eliminat.

Să creăm un nou director pentru această aplicație:

mkdir -p ~/compose-demo/wordpressapp

cd ~/compose-demo/wordpressapp

Pentru acest exemplu, nu avem nevoie de fișiere locale, deoarece imaginile vor conține tot software-ul necesar.

Creează un fișier nou docker-compose.yml:

nano docker-compose.yml

Lipește următoarea configurație. Acest fișier este mai complex, așa că vom examina fiecare parte.

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:

Notă: Am hardcodat valorile pentru parolă aici în scop ilustrativ. Când le folosești într-un mediu real, asigură-te că folosești variabile de mediu în fișierul .env pentru a evita expunerea credentialelor tale.

Salvați și închideți fișierul. Amintiți-vă să înlocuiți locurile <^...^> cu parole puternice și sigure.

Să descompunem noile directive din acest fișier:

  • services: Acest bloc definește în continuare containerele noastre. Acum avem două: db și wordpress.
  • image: Folosim mysql:8.0 pentru baza de date și imaginea wordpress:latest pentru aplicație.
  • container_name: Aceasta setează un nume specific, ușor de citit de către oameni, pentru container, care este mai ușor de referit decât cele generate automat.
  • environment: Aceasta este o listă de variabile de mediu transmise în container. Imaginea mysql le folosește pentru a seta parola de root și pentru a crea o bază de date și un utilizator inițial. Imaginea wordpress le folosește pentru a ști cum să se conecteze la baza sa de date.
  • volume (la nivel de serviciu):

    • Pentru serviciul db, db_data:/var/lib/mysql mapează un volum gestionat de Docker numit db_data către directorul de date MySQL din interiorul containerului. Acest lucru păstrează datele tale în siguranță.
    • Pentru serviciul wordpress, ./wp_content:/var/www/html/wp-content mapează un director local (wp_content) către directorul de conținut WordPress. Aceasta îți permite să editezi direct teme și pluginuri de pe calculatorul gazdă.
  • depends_on: Aceasta indică Compose să pornească serviciul db înainte de a porni serviciul wordpress. Acest lucru este important, deoarece WordPress va eșua dacă nu găsește baza sa de date la pornire.
  • volumes (nivel superior): Acest bloc definește volumele denumite. db_data: creează un volum gestionat de Docker, care este metoda preferată pentru a gestiona datele persistente.

Acum, pornește această aplicație multi-servicii:

docker compose up -d

Compose va prelua atât imaginile mysql, cât și wordpress, apoi va crea containerele, pornind mai întâi serviciul 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

Acum poți accesa noul tău site WordPress navigând la localhost:8001 sau <^domeniul_sau_IP-ul_serverului_tău<^>:8001 în browserul tău. Ar trebui să vezi ecranul de instalare WordPress. Pentru un exemplu mai detaliat, consultă articolul nostru despre Cum să instalezi WordPress cu Docker Compose

Pasul 6 — Utilizarea Docker Compose pentru dezvoltarea AI/ML

Dincolo de aplicațiile web, Docker Compose este un instrument extrem de util pentru crearea de medii reproducibile pentru știința datelor și învățarea automată (AI/ML). Proiectele AI/ML sunt cunoscute pentru dependențele lor complexe, inclusiv versiuni specifice de Python, biblioteci precum TensorFlow sau PyTorch și drivere la nivel de sistem precum NVIDIA CUDA Toolkit. Docker Compose capturează întreg acest mediu în fișiere de configurare, rezolvând problema „funcționează pe calculatorul meu”, ceea ce este esențial pentru cercetarea reproductibilă.

În acest exemplu, vei crea un mediu AI/ML cu mai multe servicii constând din:

  • JupyterLab: Un mediu pentru dezvoltare interactivă, construit dintr-un Dockerfile personalizat.
  • PostgreSQL: Un container de baze de date pentru stocarea rezultatelor experimentelor și a metadatelor.
  • Acces GPU: Containerul JupyterLab va fi configurat pentru a accesa GPU-ul NVIDIA al mașinii gazdă, un lucru obișnuit necesar pentru antrenarea modelelor.

Prerechizită: Acest exemplu necesită un GPU NVIDIA pe mașina gazdă și instalarea NVIDIA Container Toolkit. Fără acestea, containerul nu va porni atunci când se solicită resurse GPU.

Structura fișierelor

Mai întâi, creează un director pentru proiectul tău. În interiorul acestuia, vei crea un fișier docker-compose.yml, un director jupyter, un Dockerfile pentru Jupyter și un fișier requirements.txt. Structura ar trebui să arate cam așa:

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

Crearea fișierelor componentei

1. Fișierul requirements.txt

Acest fișier listează pachetele Python pentru mediul tău de știință a datelor.

nano jupyter/requirements.txt

Adaugă pachetele necesare. Pentru acest exemplu, vom include biblioteci pentru manipularea datelor, conectarea la baze de date și un cadru de învățare profundă.

pandas
scikit-learn
tensorflow
jupyterlab
psycopg2-binary

Salvează și închide fișierul.

2. Fișierul Dockerfile

Acest fișier definește serviciul tău personalizat JupyterLab. Utilizează o imagine oficială Jupyter ca bază și instalează pachetele din requirements.txt.

nano jupyter/Dockerfile

Lipiti următorul conținut:

# 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

Acest fișier instructează Docker să folosească jupyter/scipy-notebook ca punct de pornire, să copieze requirements.txt în container și apoi să folosească pip pentru a instala pachetele.

Definirea mediului cu docker-compose.yml

Acum, creează fișierul principal docker-compose.yml. Acest fișier va orchestra atât serviciul db, cât și serviciul tău personalizat jupyter.

nano docker-compose.yml

Lipiți următoarea configurație, înlocuind locurile rezervate <^...^> cu propriile dvs. credențiale securizate.

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

Acest fișier de configurare introduce câteva concepte importante:

  • build: ./jupyter: Aceasta indică Docker Compose să construiască o imagine personalizată pentru serviciul jupyter. Caută un Dockerfile în interiorul directorului specificat ./jupyter.
  • volumes: - ./notebooks:/home/jovyan/work: Aceasta montează un director local numit notebooks în container. Acest lucru asigură că toate notebook-urile Jupyter pe care le creați sunt salvate direct pe mașina gazdă, păstrându-le chiar și după ce containerul este eliminat.
  • healthcheck: Așa cum se vede în secțiunea de depanare, această verificare validează că serviciul db nu doar că este pornit, ci este pregătit să accepte conexiuni înainte ca celelalte servicii să pornească.
  • depends_on: ... condition: service_healthy: Aceasta îi spune serviciului jupyter să aștepte până când testul de sănătate al db trece înainte de a porni.
  • deploy.resources.reservations.devices: Acesta este blocul care solicită acces la GPU.

    • driver: nvidia: Specifică driverul de gazdă care trebuie utilizat.
    • count: 1: Solicită un GPU.
    • capabilities: [gpu]: Asigură că containerul dispune de capacitățile necesare pentru a utiliza GPU-ul.

Executarea mediului AI/ML

Cu fișierele tale la locul lor, ești gata să construiești și să rulezi serviciile.

  1. Din directorul tău ai-project, rulează comanda docker compose up. Trebuie să adaugi flag-ul --build prima dată pentru a spune lui Compose să construiască imaginea ta personalizată jupyter.

    docker compose up -d --build
  2. Compose va construi mai întâi imaginea jupyter (ceea ce poate dura câteva minute în timp ce descarcă TensorFlow), apoi va prelua imaginea postgres și, în final, va porni ambele containere.

    [+] 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. Acum puteți accesa interfața JupyterLab navigând la http://localhost:8888 (sau <^adresa_ip_a_serverului_tău^>:8888) în browserul dumneavoastră. Vi se va solicita un token, pe care îl puteți obține din jurnalele containerului:

    docker compose logs jupyter

    Caută o linie similară cu http://127.0.0.1:8888/lab?token=a1b2c3d4e5f6...

  4. Într-un notebook Jupyter, acum poți să te conectezi la baza ta de date folosind numele de gazdă db și acreditările pe care le-ai furnizat. Mediul tău are, de asemenea, acces la GPU-ul gazdei pentru antrenarea modelelor.

Scalarea serviciilor și utilizarea rețelelor personalizate

Docker Compose include funcții pentru scalarea serviciilor și gestionarea rețelelor pe care acestea comunică.

Scalarea serviciului cu replici

Imaginează-ți că serverul tău web Nginx de la Pasul 2 primește prea mult trafic. Poți scala serviciul web pentru a rula mai multe instanțe de containere. Docker Compose poate gestiona acest lucru automat.

Există două modalități principale de a scala un serviciu.

1. Utilizarea cheii replicas (Preferată în v2)

Poți defini numărul dorit de instanțe direct în fișierul tău docker-compose.yml folosind cheile deploy și replicas. Această funcționalitate a făcut inițial parte din Docker Swarm, dar este acum disponibilă și pentru implementările standard Compose.

Modificați fișierul dvs. Nginx docker-compose.yml de la Pasul 2:

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

Când rulezi docker compose up -d, Compose va crea trei containere web. Totuși, vei avea o problemă: toate trei vor încerca să se lege de portul gazdă 8000. Acest lucru va cauza o eroare „port is already allocated” pentru al doilea și al treilea container. Pentru a rezolva acest lucru într-un mediu de producție, ar trebui să elimini maparea ports din serviciul web. În acest fel, containerele web vor fi accesibile doar în rețeaua Docker. Un serviciu separat de load balancer ar fi singurul care are un port public. Acesta ar distribui apoi traficul către cele trei replici web.

Un exemplu de configurare ar arăta astfel (acesta este un exemplu avansat):

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:

În această configurație, load_balancer ascultă pe portul 80 și direcționează cererile către web_1, web_2 și web_3 intern.

Această cheie replicas este cea mai utilă atunci când este folosită împreună cu un proxy invers (precum Traefik sau o altă instanță Nginx) care poate distribui cererile între replici în cadrul rețelei Docker, fără ca fiecare replică să fie nevoită să expună un port pe gazdă.

2. Utilizarea flag-ului --scale

O metodă comună de scalare este flag-ul --scale, preluat din Compose v1. Acest flag se aplică la rulare și suprascrie orice cheie replicas.

Totuși, trebuie să fii atent cu definițiile porturilor. Dacă serviciul tău definește o mapare fixă a portului gazdă (de exemplu, "8000:80"), rularea docker compose up --scale va cauza o eroare pentru al doilea și al treilea container, deoarece toate încearcă să se lege la același port gazdă.

Pentru a folosi --scale pentru serviciile care expun porturi, nu trebuie să folosiți o mapare fixă a portului gazdei.

  • Opțiunea 1: Mapare către porturi aleatorii pe gazdă (Bun pentru dezvoltare)

    Poți modifica fișierul tău docker-compose.yml pentru a specifica doar portul containerului. Aceasta îi spune Docker-ului să mapese portul 80 din fiecare container la un port aleatoriu, disponibil pe mașina ta gazdă.

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

    Acum, când rulezi comanda scale:

    docker compose up -d --scale web=3

    Rulați docker compose ps pentru a vedea rezultatul. Fiecare container va rula pe un port gazdă diferit, atribuit la întâmplare:

          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 - Corect pentru --scale

  • Opțiunea 2: Folosește un Proxy Invers (Bun pentru Producție)

    Cealaltă soluție, așa cum se menționează în secțiunea replicas, este să eliminați complet directiva ports din serviciul web. Apoi, ați folosi un container separat de tip load balancer (care are singurul port public) pentru a gestiona și distribui traficul către replicile scalate din cadrul rețelei Docker.

    Pentru a opri și a elimina toate cele trei containere, comanda rămâne aceeași:

    docker compose down

Configurare rețea personalizată

Implicit, Docker Compose creează o singură rețea bridge pentru aplicația ta. Fiecare serviciu din fișier este conectat la aceasta, ceea ce explică modul în care containerul wordpress a putut găsi containerul db doar folosind numele serviciului său (db).

Totuși, poți defini propriile rețele personalizate pentru o mai bună izolare și control.

Să modificăm exemplul WordPress pentru a folosi o rețea personalizată 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

Iată ce am adăugat:

  • rețele (de nivel superior): Aceasta definește o nouă rețea numită app_net și specifică faptul că ar trebui să folosească driverul standard bridge.
  • rețele (nivel serviciu): Atât sub db, cât și sub wordpress, această cheie le atașează la rețeaua noastră app_net.

Dacă ai avea un al treilea serviciu (cum ar fi un instrument de analiză) pe care **nu** l-ai conecta la `app_net`, acesta ar fi complet izolat și incapabil să comunice cu containerele `db` sau `wordpress`.

Pentru clustering pe mai multe gazde cu Docker Swarm, ai schimba driver de la bridge la overlay. Driver-ul bridge este pentru comunicarea între containere pe o singură gazdă, ceea ce este standardul pentru majoritatea cazurilor de utilizare Docker Compose.

Folosirea fișierelor de configurare modulare

Pe măsură ce aplicațiile tale cresc, fișierul tău docker-compose.yml poate deveni mare și greu de gestionat. Docker Compose suportă o directivă include, permițându-ți să împarți configurația ta în mai multe fișiere.

Imaginează-ți că vrei să separi definițiile WordPress și ale bazei de date și, eventual, să ai un docker-compose.override.yml comun pentru setările specifice dezvoltării (cum ar fi legarea unui port pe baza de date).

Structura directorului tău ar putea arăta astfel:

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

Acest fișier va defini doar serviciul 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:

Acest fișier va defini doar serviciul 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

Acum, fișierul tău principal docker-compose.yml devine foarte simplu. Acesta doar folosește include pentru a include celelalte fișiere.

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

Când rulezi docker compose up -d, Compose va citi toate cele trei fișiere, va combina configurațiile și va porni serviciile db și wordpress exact ca și cum ar fi fost definite într-un singur fișier. Această abordare face ca configurația ta să fie mult mai modulară și mai ușor de reutilizat.

Notă: Directiva include: necesită Docker Compose v2.20 sau o versiune mai recentă. Dacă sistemul tău folosește o versiune mai veche, poți combina fișierele folosind docker compose -f docker-compose.db.yml -f docker-compose.web.yml up.

Migrarea de la docker-compose (v1) la docker compose (v2)

Comanda docker compose pe care ai instalat-o la Pasul 1 este „Compose v2.” Este un plugin bazat pe Go, integrat direct în CLI-ul Docker.

Versiunea originală, „Compose v1,” era un instrument Python separat invocat cu docker-compose (cu cratimă). Începând cu iulie 2023, Compose v1 nu mai este suportat și a fost depreciat.

Schimbări cheie și compatibilitate inversă

  • Comanda: Cea mai evidentă schimbare este comanda. Liniuța (docker-compose) este acum înlocuită cu un spațiu (docker compose).
  • Instalare: v1 a fost instalat cu pip. v2 este inclus în Docker Desktop sau instalat ca plugin CLI, așa cum ai făcut la Pasul 1.
  • Fișiere YAML: Fișierele dvs. docker-compose.yml sunt aproape 100% compatibile cu versiunile anterioare. Compose v2 acceptă complet versiunile de fișiere 3.x. Nu trebuie să modificați fișierele YAML pentru migrare, ci doar comenzile dvs.
  • --project-name flag: Flagul -p funcționează în continuare, dar flagul complet este acum --project-name în loc de --project_name.

Ghid de migrare a comenzilor

Majoritatea comenzilor sunt identice, doar că cratima a fost eliminată. Iată un tabel care compară comenzile comune v1 cu echivalentele lor v2.

Comandă docker-compose (v1)Comandă docker compose (v2)Note
docker-compose up -d
docker compose up -d
Fără modificări în sintaxă.
docker-compose down
docker compose down
Fără modificări în sintaxă.
docker-compose ps
docker compose ps
Fără modificări în sintaxă.
docker-compose logs
docker compose logs
Fără modificări în sintaxă.
docker-compose stop
docker compose stop
Fără modificări în sintaxă.
docker-compose build
docker compose build
Nicio modificare în sintaxă.
docker-compose exec web bash
docker compose exec web bash
Nicio modificare în sintaxă.
docker-compose run web bash
docker compose run web bash
run creează un container nou. exec rulează într-unul existent.
docker-compose up --scale web=3
docker compose up --scale web=3
Opțiunea --scale este încă suportată în v2.

După cum puteți vedea, pentru majoritatea utilizărilor zilnice, singura schimbare este docker-compose -> docker compose. Dacă folosiți scripturi, le puteți actualiza pur și simplu eliminând cratima.

Dacă încă aveți instalat vechiul docker-compose v1, îl puteți elimina pentru a evita confuzia:

sudo pip3 uninstall docker-compose

Sau, dacă a fost instalat prin apt:

sudo apt remove docker-compose

Depanarea problemelor comune în Docker Compose

Când lucrați cu Docker Compose, este posibil să întâmpinați probleme legate de sintaxa fișierelor, permisiuni sau conflicte la rularea containerelor. Majoritatea problemelor pot fi diagnosticate și rezolvate verificând metodic configurația, permisiunile și jurnalele containerelor.

Să analizăm câteva dintre cele mai frecvente greșeli și soluțiile lor.

Permisiune refuzată (Socket Docker)

Aceasta este una dintre cele mai frecvente erori pentru utilizatorii noi de Docker. Rulați docker compose up și vedeți un mesaj de eroare legat de socket-ul Docker daemon-ului.

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
  • Problemă: Utilizatorul tău non-root nu are permisiuni pentru a comunica cu demonul Docker, care rulează ca root.

  • Solutie: Trebuie să adaugi utilizatorul tău în grupul docker, care a fost creat în timpul instalării Docker.

    1. Adaugă utilizatorul tău în grupul docker:

      sudo usermod -aG docker ${USER}
    2. Pentru ca apartenența la noul grup să intre în vigoare, trebuie să vă delogați și să vă autentificați din nou.

    3. Alternativ, poți activa schimbările de grup pentru sesiunea ta curentă de terminal tastând:

      newgrp docker

    Aceasta ar trebui să rezolve orice erori de permisiune legate de socket-ul Docker.

Erori de sintaxă și indentare YAML

Docker Compose nu reușește să pornească și raportează că fișierul tău docker-compose.yml este invalid.

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

Aur :

mapping values are not allowed in this context at line 5
  • Problema: Fișierul docker-compose.yml se bazează pe sintaxa YAML strictă. Cea mai frecventă greșeală este indentarea incorectă. YAML folosește spații, nu tab-uri, pentru a defini structura.
  • Soluție: Verificați cu atenție indentarea fișierului dumneavoastră docker-compose.yml.

    • Standardul este două spații pentru fiecare nivel de indentare.
    • Asigurați-vă că toate cheile de același nivel (cum ar fi version, services, volumes) încep în aceeași coloană.
    • Asigurați-vă că toate sub-cheile (cum ar fi image, ports, volumes sub un serviciu) sunt indentate cu două spații mai mult decât serviciul părinte (de exemplu, web).
    • Folosește un editor de cod cu un linter YAML pentru a evidenția automat erorile de sintaxă.

Conflicte de port

Încerci să pornești mediul tău, dar comanda eșuează cu un mesaj de eroare care spune că adresa este deja utilizată.

Error starting userland proxy: listen tcp 0.0.0.0:8000: bind: address already in use
  • Problemă: Un alt proces de pe mașina gazdă ascultă deja pe portul pe care încerci să-l mapezi (în acest caz, portul 8000). De multe ori este vorba de un alt container Docker sau de un server de dezvoltare local.

  • Soluție: Ai două opțiuni:

    1. Oprește celălalt proces. Poți găsi procesul care folosește portul cu această comandă:

      sudo lsof -i :8000

      Dacă este un alt container Docker, oprește-l cu docker stop <container_id>.

    2. Schimbați portul gazdei în fișierul dumneavoastră docker-compose.yml. Aceasta este adesea cea mai simplă soluție. Schimbați maparea ports de la "8000:80" la un alt port, de exemplu "8001:80".

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

Serviciul eșuează cu Conexiune Refuzată (depends_on)

Într-o aplicație cu mai multe servicii (ca exemplul cu WordPress și MySQL), containerul wordpress pornește, dar în jurnalele sale apare Connection refused sau MySQL server has gone away atunci când încearcă să se conecteze la serviciul db.

  • Problemă: Ați folosit depends_on, dar această directivă așteaptă doar ca containerul db să pornească. Nu așteaptă ca aplicația MySQL din container să fie complet inițializată și gata să accepte conexiuni.

  • Soluție: Aplicația (în acest caz, WordPress) trebuie configurată să încerce din nou conectarea. Majoritatea imaginilor moderne au această logică de retry încorporată. Pentru imaginile care nu o au, trebuie să implementați un healthcheck.

    Poți adăuga un healthcheck la serviciul tău db. Serviciul wordpress își poate configura apoi depends_on să aștepte ca baza de date să fie „sănătoasă”, nu doar „pornită”.

Exemplu de verificare a stării 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
    ...

Erori cu volumele și mount-urile legate

Este posibil să întâmpinați erori de permisiune în jurnalele containerului dvs., sau să constatați că directorul de date al containerului este gol.

Permisiuni fișier/director

  • Problema: Containerul rulează ca un utilizator specific (de exemplu, www-data cu ID de utilizator 33), dar directorul de pe gazdă pe care l-ați montat este deținut de utilizatorul dumneavoastră (de exemplu, ubuntu cu ID de utilizator 1000). Utilizatorul din container nu are permisiunea de a scrie în directorul de pe gazdă.

  • Soluție: Schimbați proprietatea directorului gazdă pentru a corespunde ID-ului utilizatorului din container. Puteți afla ID-ul utilizatorului din container rulând docker compose exec <service_name> id. De exemplu, dacă ID-ul este 33 (comun pentru www-data):

    sudo chown -R 33:33 ./wp_content

Probleme cu calea relativă

  • Problemă: Fișierul tău docker-compose.yml folosește o cale relativă precum ./app, dar fișierul tău index.html nu este servit.

  • Solutie: Docker Compose interpretează căile relative în funcție de directorul din care rulezi comanda docker compose up. Încearcă întotdeauna să rulezi comenzile Compose din același director care conține fișierul tău docker-compose.yml.

Rețelistică și Descoperirea Serviciilor

Jurnalele containerului aplicației tale arată Gazdă negăsită sau Nu s-a putut rezolva gazda: db.

  • Problemă: Containerul tău wordpress nu poate găsi containerul db în rețea.
  • Soluție: Implicit, Docker Compose creează o rețea și atașează toate serviciile la aceasta. Serviciile se pot găsi între ele folosind numele serviciilor.

    1. Verificați Numele Serviciilor: Asigurați-vă că numele gazdei din configurația aplicației dvs. (de exemplu, variabila de mediu WORDPRESS_DB_HOST) este exact același cu numele serviciului din docker-compose.yml (de exemplu, db).

    2. Inspectează rețeaua: Folosește docker compose ps pentru a afla numele proiectului tău (de exemplu, compose-demo). Apoi, inspectează rețeaua implicită:

      docker network inspect compose-demo_default

      Ieșirea JSON va lista toate containerele atașate la această rețea. Dacă unul dintre serviciile tale lipsește, verifică fișierul tău docker-compose.yml pentru orice configurație networks personalizată care ar putea să-l izoleze.

Neconcordanță a comenzii (v1 vs. v2)

Tastați docker-compose up (cu un cratimă) și vedeți o eroare „comandă negăsită”.

docker-compose: command not found
  • Problemă: Încercați să folosiți comanda pentru Compose v1, care este un instrument Python învechit. Acest ghid instalează Compose v2, care este un plugin integrat direct în CLI-ul Docker.
  • Soluție: Folosește comanda corectă înlocuind cratima (-) cu un spațiu.
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

Folosește întotdeauna docker compose (spațiu) atunci când urmezi acest ghid.

Întrebări frecvente

1. La ce se folosește Docker Compose?

Docker Compose este un instrument pentru definirea și rularea aplicațiilor Docker cu mai multe containere.

Folosește un singur fișier YAML (implicit, docker-compose.yml) pentru a configura toate componentele aplicației tale, care sunt numite servicii. Acest fișier definește, de asemenea, rețelele care permit serviciilor să comunice între ele și volumele folosite pentru date persistente.

Cu acest singur fișier, poți gestiona întregul tău stack de aplicații cu comenzi simple:

  • docker compose up pornește și rulează întreaga ta aplicație, inclusiv toate containerele, rețelele și volumele specificate.
  • docker compose down oprește și elimină toate containerele, rețelele și volumele create de aplicația ta.

Este cel mai util pentru gestionarea aplicațiilor care necesită mai multe componente, cum ar fi un site web care are nevoie de un server web (precum Nginx), un backend de aplicație (precum WordPress) și o bază de date (precum MySQL).

2. Cum îmi instalez Docker Compose pe Ubuntu?

Metoda recomandată este să instalați Docker Compose ca un plugin pentru CLI-ul Docker. Acest lucru se face prin instalarea pachetului docker-compose-plugin din depozitul oficial apt al Docker.

  1. Mai întâi, asigură-te că ai urmat documentația oficială Docker pentru a configura depozitul apt al Docker pe sistemul tău Ubuntu.

  2. Actualizează lista de pachete:

    sudo apt update
  3. Instalează pluginul Docker Compose:

    sudo apt install docker-compose-plugin
  4. Verificați instalarea verificând versiunea. Comanda folosește un spațiu, nu un cratimă.

    docker compose version

3. Cum îmi actualizez Docker Compose la cea mai recentă versiune?

Deoarece Docker Compose (v2) este instalat ca pachet de sistem folosind apt, îl poți actualiza folosind procesul standard de actualizare a software-ului Ubuntu.

  1. Reîmprospătează indexul de pachete local:

    sudo apt update
  2. Rulați o actualizare la nivel de sistem, care va include pluginul Compose:

    sudo apt upgrade

    Alternativ, dacă vrei să actualizezi doar pluginul în sine, poți rula:

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

4. Poate fi utilizat Docker Compose în medii de producție?

Da, Docker Compose este frecvent utilizat în producție, în special pentru aplicațiile care rulează pe un singur gazdă.

Oferă o modalitate simplă de a defini, implementa și gestiona ciclul de viață al serviciilor, rețelelor și volumelor aplicației tale. Pentru o implementare pe un singur server, este o soluție foarte eficientă și ușor de gestionat.

Pentru scenarii mai complexe care necesită coordonarea containerelor pe mai multe gazde (un cluster), alte instrumente sunt mai frecvent utilizate. Acestea includ Docker Swarm (care folosește o sintaxă de fișier Compose similară) și Kubernetes (care este standardul industriei pentru orchestrarea containerelor la scară largă).

5. Care este diferența dintre Docker și Docker Compose?

Acest tabel prezintă principalele diferențe dintre Docker CLI și Docker Compose CLI.

Funcțiedocker (motor Docker)docker compose (Plugin Compose)
DomeniuGestionează obiecte individuale Docker.Gestionează o aplicație completă, cu mai multe containere ca o unitate unică.
Utilizare principalăCrearea imaginilor (docker build), rularea containerelor individuale (docker run), gestionarea containerelor (docker ps), imaginilor, volumelor și rețelelor.Orchestrarea mai multor servicii definite într-un fișier docker-compose.yml.
ComenziComenzi la nivel scăzut axate pe un singur obiect. Exemplu: docker run -d -p 80:80 -v ./:/app nginxComenzi la nivel înalt pentru întreaga aplicație. Exemplu: docker compose up
AnalogieUn element de construcție (un singur container).Planul schematic și managerul de construcție pentru întreaga clădire (aplicația).

Pe scurt, folosești docker pentru a interacționa cu un singur container. Folosești docker compose pentru a gestiona întregul tău stack de aplicații (de exemplu, web, app, db) dintr-o dată.

6. Cum pot rula mai multe containere cu Docker Compose?

Rulezi mai multe containere definindu-le ca servicii în fișierul tău docker-compose.yml.

  1. Creează un fișier numit docker-compose.yml.

  2. În acest fișier, folosește cheia services: pentru a defini fiecare container pe care vrei să-l rulezi.

    Iată un exemplu practic care definește și rulează două containere: un site WordPress și o bază de date 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. Salvează fișierul și deschide un terminal în același director.

  5. Rulează o singură comandă pentru a porni ambele containere:

    docker compose up -d

Docker Compose va citi fișierul, va crea o rețea partajată pentru servicii, va descărca imaginile mysql și wordpress, și va porni un container pentru fiecare serviciu.

7. De ce să folosești Docker Compose pentru dezvoltare?

Docker Compose este un instrument standard pentru mediile de dezvoltare deoarece rezolvă mai multe probleme comune.

  • Medii Consistente: Asigură că fiecare dezvoltator dintr-o echipă rulează exact aceleași servicii (bază de date, cache, server web) cu aceleași versiuni și configurații. Acest lucru este definit în fișierul docker-compose.yml, care este comis în controlul versiunilor. Aceasta elimină problema „funcționează pe calculatorul meu”.

  • Simplificare: Înlocuiește scripturile complexe de configurare și comenzile lungi docker run. Un dezvoltator trebuie doar să ruleze docker compose up pentru a porni întregul pachet de aplicații și docker compose down pentru a-l opri.

  • Izolarea Serviciilor: Dezvoltatorii pot lucra la mai multe proiecte pe aceeași mașină fără conflicte de dependențe. Proiectul A poate folosi PostgreSQL 9.6, iar Proiectul B poate folosi PostgreSQL 14, deoarece fiecare bază de date rulează într-un container izolat, gestionat de propriul fișier Compose.

  • Testare ușoară a integrării: Deoarece Compose pornește toate dependențele unei aplicații împreună, creează un mediu local perfect pentru efectuarea testelor de integrare care verifică modul în care serviciile interacționează între ele.

Concluzie

În acest ghid, ați instalat Docker Compose și ați configurat o aplicație completă cu mai multe containere. Ați început cu un fișier de bază docker-compose.yml pentru un server web Nginx și ați progresat către un stack mai complex și realist, implicând o aplicație WordPress și o bază de date MySQL. Ați învățat să gestionați întregul ciclu de viață al aplicației, de la construirea și rularea serviciilor până la oprirea și eliminarea acestora.

Acum sunteți familiarizați cu conceptele cheie pentru gestionarea eficientă a aplicațiilor, inclusiv scalarea serviciilor, definițiile de rețea personalizate și împărțirea configurației în fișiere modulare folosind directiva include. Urmând ghidul de migrare și pașii de depanare, puteți rezolva, de asemenea, probleme comune precum conflictele de porturi, erorile „Permisiune refuzată” și greșelile de sintaxă YAML. Abilitățile prezentate aici vă vor permite să construiți medii de dezvoltare consistente și reproductibile și să implementați aplicații pe un singur host cu încredere.

Pentru o referință completă a tuturor comenzilor disponibile docker compose, consultați documentația oficială.

Pentru mai multe tutoriale legate de Docker, consultați următoarele articole:

  • Cum să instalezi Docker pe Ubuntu – Ghid pas cu pas
  • Cum să instalezi WordPress cu Docker Compose

Mulțumim că ați învățat împreună cu comunitatea Linux-Console.net.