\section{Docker Compose} \begin{frame}{Mi a Docker Compose?} \begin{block}{Docker Compose -- Több konténer kezelése} \begin{itemize} \item Eszköz \textbf{több konténerből álló} alkalmazások definiálására \item YAML formátumú konfigurációs fájl (\texttt{docker-compose.yml}) \item Egyetlen parancs: teljes alkalmazás indítása/leállítása \end{itemize} \end{block} \end{frame} \begin{frame}{Docker Compose -- Használati eset} \begin{exampleblock}{Példa használati eset} Node.js backend + PostgreSQL adatbázis + Redis cache\\ $\Rightarrow$ 3 konténer, 1 docker-compose.yml, 1 parancs: \texttt{docker compose up} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Miért? -- Docker Compose nélkül} \begin{alertblock}{Docker Compose nélkül} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] docker network create myapp docker run -d --name postgres \ --network myapp \ -e POSTGRES_PASSWORD=secret \ postgres:15 docker run -d --name redis \ --network myapp redis:7 docker run -d --name backend \ --network myapp \ -p 3000:3000 my-backend \end{lstlisting} \end{alertblock} \end{frame} \begin{frame}{Miért? -- A probléma} \begin{alertblock}{Probléma} Bonyolult, sok parancs, nehezen karbantartható \end{alertblock} \end{frame} \begin{frame}[fragile]{Miért? -- Docker Compose-zal} \begin{exampleblock}{Docker Compose-zal} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] docker compose up \end{lstlisting} \end{exampleblock} \begin{block}{Előnyök} \begin{itemize} \item Egyetlen parancs! \item Minden konfiguráció a \texttt{docker-compose.yml}-ben \item Reprodukálható és verziókezelhető \end{itemize} \end{block} \end{frame} \begin{frame}{Miért? -- Csapatmunka} \begin{block}{Csapatmunka előnyök} \begin{itemize} \item Verziókezelhető (Git) \item Csapatmunkában könnyen megosztható \item Konzisztens környezet minden fejlesztőnél \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Docker Compose telepítés} \begin{block}{Modern Docker verzió} Docker Desktop és újabb Docker Engine verziók tartalmazzák: \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Ellenőrzés docker compose version # Docker Compose version v2.24.0 \end{lstlisting} \end{block} \end{frame} \begin{frame}{Docker Compose -- Régi vs új szintaxis} \begin{alertblock}{Régi vs új szintaxis} \begin{itemize} \item Régi (v1): \texttt{docker-compose up} (kötőjellel, külön telepítés) \item Új (v2): \texttt{docker compose up} (szóköz, built-in) \end{itemize} Ajánlott: v2 (docker compose) \end{alertblock} \end{frame} \begin{frame}[fragile]{Első docker-compose.yml -- Kód} \begin{exampleblock}{Egyszerű webszerver példa} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] version: '3.8' services: web: image: nginx:alpine ports: - "8080:80" \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Első docker-compose.yml -- Parancsok} \begin{block}{Indítás és leállítás} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Indítás (háttérben) docker compose up -d # Leállítás és törlés docker compose down \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{docker-compose.yml struktúra -- Kód} \begin{block}{Fő elemek} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] version: '3.8' # Compose fájl verzió services: # Konténerek definíciója service1: # konfiguráció service2: # konfiguráció volumes: # Named volume-ok (opcionális) data: networks: # Egyedi hálózatok (opcionális) backend: \end{lstlisting} \end{block} \end{frame} \begin{frame}{docker-compose.yml struktúra -- Magyarázat} \begin{block}{Elemek} \begin{itemize} \item \texttt{version}: Compose fájl formátum verzió \item \texttt{services}: Konténerek (ezeket indítja) \item \texttt{volumes}: Megosztott perzisztens tárolók \end{itemize} \end{block} \end{frame} \begin{frame}{docker-compose.yml struktúra -- Networks} \begin{block}{Hálózatok} \begin{itemize} \item \texttt{networks}: Hálózati konfiguráció \item Compose automatikusan létrehoz egy default hálózatot \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Service definíció -- image alapú} \begin{exampleblock}{Existing image használata} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: database: image: postgres:15-alpine environment: POSTGRES_DB: myapp POSTGRES_USER: admin POSTGRES_PASSWORD: secret123 ports: - "5432:5432" volumes: - postgres-data:/var/lib/postgresql/data restart: unless-stopped volumes: postgres-data: \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Service definíció -- build alapú} \begin{exampleblock}{Saját Dockerfile build-elése} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: build: context: ./backend dockerfile: Dockerfile ports: - "3000:3000" environment: NODE_ENV: production DB_HOST: database depends_on: - database restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Service definíció -- build magyarázat} \begin{block}{Build elemek} \begin{itemize} \item \texttt{build}: Dockerfile-ból épít \item \texttt{context}: Build context útvonal \item \texttt{depends\_on}: Függőségek (ez után indul) \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Environment variables -- Inline} \begin{block}{Inline környezeti változók} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: app: environment: NODE_ENV: production PORT: 3000 \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Environment variables -- Fájlból} \begin{block}{.env fájlból} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: app: env_file: - .env - .env.local \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Environment variables -- Host változók} \begin{block}{Host environment változók} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: app: environment: # .env fájlból vagy host-ról DB_PASSWORD: ${DB_PASSWORD} \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Volumes -- Named volumes} \begin{block}{Named volumes (ajánlott)} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: db: image: postgres:15 volumes: - db-data:/var/lib/postgresql/data volumes: db-data: \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Volumes -- Bind mounts} \begin{block}{Bind mounts (fejlesztéshez)} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: app: volumes: # Relatív útvonal - ./src:/app/src # Abszolút útvonal - /host/path:/container/path \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Networks -- Automatikus} \begin{block}{Automatikus hálózat} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: image: my-app database: image: postgres \end{lstlisting} Compose automatikusan létrehoz egy hálózatot!\\ \texttt{backend} eléri \texttt{database}-t a név alapján. \end{block} \end{frame} \begin{frame}[fragile]{Networks -- Egyedi hálózatok} \begin{block}{Egyedi hálózatok} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: networks: - frontend - backend database: networks: - backend networks: frontend: backend: \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{MERN stack -- Adatbázisok} \begin{exampleblock}{MongoDB és Redis} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] version: '3.8' services: mongodb: image: mongo:7 volumes: - mongo-data:/data/db environment: MONGO_INITDB_ROOT_USERNAME: admin MONGO_INITDB_ROOT_PASSWORD: secret restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{MERN stack -- Redis és volumes} \begin{exampleblock}{Redis és adattárolás} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: redis: image: redis:7-alpine restart: unless-stopped volumes: mongo-data: \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{MERN stack -- Adatbázis magyarázat} \begin{block}{Adattárolás} \begin{itemize} \item \textbf{MongoDB:} perzisztens volume (mongo-data) \item \textbf{Redis:} cache, nincs szükség volume-ra \item \textbf{Restart policy:} biztosítja a rendelkezésre állást \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{MERN stack -- Backend} \begin{exampleblock}{Backend szolgáltatás} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: build: ./backend ports: - "3001:3001" environment: MONGO_URL: mongodb://admin:secret@mongodb:27017 REDIS_URL: redis://redis:6379 depends_on: - mongodb - redis restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{MERN stack -- Frontend} \begin{exampleblock}{Frontend szolgáltatás} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: frontend: build: ./frontend ports: - "3000:3000" environment: REACT_APP_API_URL: http://localhost:3001 depends_on: - backend restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{depends\_on -- Alap használat} \begin{block}{Alapvető függőség} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: depends_on: - database database: image: postgres \end{lstlisting} \texttt{database} indul először, \textbf{de nem vár} amíg kész! \end{block} \end{frame} \begin{frame}{depends\_on -- Figyelmeztetés} \begin{alertblock}{Fontos} \texttt{depends\_on} csak az indítási sorrendet szabályozza,\\ \textbf{NEM várja meg} amíg a szolgáltatás tényleg készen áll! \end{alertblock} \begin{exampleblock}{Megoldás} \begin{itemize} \item Alkalmazásban: retry logika \item Healthcheck használata \item wait-for-it.sh script \end{itemize} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Healthcheck a Compose-ban} \begin{exampleblock}{Szolgáltatás készenlét ellenőrzés} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: database: image: postgres:15 healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5 backend: depends_on: database: condition: service_healthy \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Healthcheck -- Magyarázat} \begin{block}{Healthcheck elemek} \begin{itemize} \item \texttt{condition: service\_healthy}: Vár amíg healthcheck OK \item \texttt{test}: Ellenőrző parancs \item \texttt{interval}: Ellenőrzések gyakorisága \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Compose parancsok -- Indítás} \begin{block}{Indítás} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Indítás (előtérben, logokkal) docker compose up # Indítás háttérben docker compose up -d # Rebuild és indítás docker compose up --build \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Compose parancsok -- Leállítás} \begin{block}{Leállítás} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Leállítás (konténerek megmaradnak) docker compose stop # Leállítás és törlés docker compose down # Törlés volume-okkal együtt docker compose down -v \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Compose parancsok -- Státusz} \begin{block}{Státusz és logok} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Futó szolgáltatások listája docker compose ps # Összes szolgáltatás (leállítottak is) docker compose ps -a # Logok megjelenítése docker compose logs \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Compose parancsok -- Log szűrés} \begin{block}{Log szűrés} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Követés (egyik szolgáltatás) docker compose logs -f backend # Utolsó 100 sor docker compose logs --tail=100 \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Exec és run -- Futó konténerben} \begin{block}{Parancs futtatása futó szolgáltatásban} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Shell futó konténerben docker compose exec backend sh # PostgreSQL konzol docker compose exec database psql -U admin -d myapp \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Exec és run -- Egyszeri parancs} \begin{block}{Egyszeri parancs (új konténer)} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Database migráció docker compose run backend npm run migrate # Teszt futtatás docker compose run --rm backend npm test \end{lstlisting} \texttt{--rm}: Konténer törlése futás után \end{block} \end{frame} \begin{frame}[fragile]{Scale -- Több példány} \begin{block}{Szolgáltatás skálázása} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # 3 backend példány indítása docker compose up -d --scale backend=3 \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Scale -- Port konfliktus} \begin{alertblock}{Port konfliktus} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: ports: - "3000:3000" # Nem skálázható! \end{lstlisting} \end{alertblock} \begin{exampleblock}{Megoldás: dinamikus port} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] ports: - "3000-3002:3000" # 3 példány \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Override fájlok -- Dev config} \begin{block}{docker-compose.override.yml} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] # docker-compose.yml (base) services: app: image: my-app # docker-compose.override.yml (dev) services: app: volumes: - ./src:/app/src # live reload environment: DEBUG: "true" \end{lstlisting} Automatikusan egyesül a base-zel fejlesztéskor! \end{block} \end{frame} \begin{frame}[fragile]{Override fájlok -- Production} \begin{block}{docker-compose.prod.yml} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: app: image: my-app:1.0.0 restart: always deploy: replicas: 3 resources: limits: cpus: '0.5' memory: 512M \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Override fájlok -- Használat} \begin{block}{Használat} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Specifikus fájl megadása docker compose -f docker-compose.yml \ -f docker-compose.prod.yml up -d \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Secrets kezelés -- .env fájl} \begin{block}{Érzékeny adatok .env fájlban} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # .env fájl (ne commitold!) POSTGRES_PASSWORD=supersecret123 API_KEY=abc123xyz JWT_SECRET=random_secret_key \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Secrets kezelés -- Compose-ban} \begin{block}{Használat docker-compose.yml-ben} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: database: environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} backend: env_file: - .env \end{lstlisting} \end{block} \begin{alertblock}{Biztonság} \texttt{.env} legyen a \texttt{.gitignore}-ban!\\ Használj \texttt{.env.example} sablont repository-ban! \end{alertblock} \end{frame} \begin{frame}[fragile]{Profiles -- Opcionális szolgáltatások} \begin{block}{Fejlesztői eszközök csak manuális indításkor} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: app: image: my-app database: image: postgres adminer: image: adminer profiles: - debug ports: - "8080:8080" \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Profiles -- Használat} \begin{block}{Használat} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Normál indítás: app + database docker compose up # Debug profillal: app + database + adminer docker compose --profile debug up \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Resource limits} \begin{exampleblock}{CPU és memória korlátok} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: image: my-app deploy: resources: limits: cpus: '1.0' memory: 1G reservations: cpus: '0.5' memory: 512M \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Logging konfiguráció} \begin{exampleblock}{Log beállítások} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: logging: driver: "json-file" options: max-size: "10m" max-file: "3" \end{lstlisting} \end{exampleblock} \begin{block}{Driverek} \texttt{json-file}, \texttt{syslog}, \texttt{journald}, \texttt{awslogs} \end{block} \end{frame} \begin{frame}[fragile]{Teljes projekt -- PostgreSQL} \begin{exampleblock}{PostgreSQL szolgáltatás} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] version: '3.8' services: postgres: image: postgres:15-alpine environment: POSTGRES_DB: ${DB_NAME} POSTGRES_USER: ${DB_USER} POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - postgres-data:/var/lib/postgresql/data restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Teljes projekt -- PostgreSQL healthcheck} \begin{exampleblock}{Healthcheck hozzáadása} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: postgres: healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"] interval: 5s timeout: 5s retries: 5 \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Teljes projekt -- Redis és volumes} \begin{exampleblock}{Redis és adattárolás} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: redis: image: redis:7-alpine restart: unless-stopped volumes: postgres-data: \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Teljes projekt -- Backend} \begin{exampleblock}{Backend hotreload-dal} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: backend: build: ./backend ports: - "3001:3001" environment: DATABASE_URL: postgresql://${DB_USER}: ${DB_PASSWORD}@postgres:5432/${DB_NAME} REDIS_URL: redis://redis:6379 volumes: - ./backend/src:/app/src depends_on: postgres: condition: service_healthy restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Teljes projekt -- Frontend} \begin{exampleblock}{React frontend hotreload-dal} \begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily] services: frontend: build: ./frontend ports: - "3000:3000" environment: REACT_APP_API_URL: http://localhost:3001 volumes: - ./frontend/src:/app/src - /app/node_modules depends_on: - backend restart: unless-stopped \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Teljes projekt -- Frontend magyarázat} \begin{block}{Fejlesztői környezet} \begin{itemize} \item Volume mount: kód változások azonnal láthatóak \item node\_modules izolált a konténerben \item Restart policy védelem összeomlás ellen \end{itemize} \end{block} \end{frame} \begin{frame}{Compose vs Orchestration -- Compose} \begin{block}{Mikor használj Docker Compose-t?} \begin{itemize} \item Fejlesztési környezet \item Teszt környezet \item Kisebb produkciós alkalmazások (1-2 szerver) \end{itemize} \end{block} \end{frame} \begin{frame}{Compose vs Orchestration -- Kubernetes} \begin{block}{Mikor kell Kubernetes vagy Docker Swarm?} \begin{itemize} \item Nagy léptékű production (több szerver) \item Magas rendelkezésre állás (HA) \item Automatikus failover és auto-scaling \end{itemize} \end{block} \begin{alertblock}{Fontos} Kezdd Compose-zal, csak akkor válts orchestration-re, ha tényleg szükséges! \end{alertblock} \end{frame} \begin{frame}{Best Practices -- Konfiguráció} \begin{exampleblock}{Ajánlott gyakorlatok} \begin{itemize} \item \textbf{Verziókezeld} a \texttt{docker-compose.yml}-t \item \textbf{.env fájl} érzékeny adatokhoz (.gitignore!) \item \textbf{Named volumes} adatok perzisztálásához \end{itemize} \end{exampleblock} \end{frame} \begin{frame}{Best Practices -- Megbízhatóság} \begin{exampleblock}{Ajánlott gyakorlatok} \begin{itemize} \item \textbf{Healthcheck} használata depends\_on-nál \item \textbf{Restart policy}: unless-stopped production-ben \item \textbf{Resource limits} beállítása \end{itemize} \end{exampleblock} \end{frame} \begin{frame}{Best Practices -- Build} \begin{exampleblock}{Ajánlott gyakorlatok} \begin{itemize} \item \textbf{Specifikus image verziók} (ne latest) \item \textbf{Multi-stage Dockerfile} kisebb image-ekhez \item \textbf{Service nevek} beszédesek legyenek \end{itemize} \end{exampleblock} \end{frame} \begin{frame}{Anti-patterns -- Kerülendő} \begin{alertblock}{Ne csináld} \begin{itemize} \item Érzékeny adatok közvetlenül a YAML-ban \item \texttt{latest} tag production-ben \item Adatok a konténerben (volume nélkül) \end{itemize} \end{alertblock} \end{frame} \begin{frame}{Anti-patterns -- Kerülendő folyt.} \begin{alertblock}{Ne csináld} \begin{itemize} \item Egy konténerben több alkalmazás \item Hardcoded portok ha skálázni akarsz \item Depends\_on healthcheck nélkül \end{itemize} \end{alertblock} \end{frame} \begin{frame}{Összefoglalás -- Lényeg} \begin{block}{Docker Compose = Egyszerű multi-container kezelés} \begin{itemize} \item YAML fájl: teljes alkalmazás stack leírása \item Egy parancs: \texttt{docker compose up} \item Automatikus hálózat, volume, service discovery \end{itemize} \end{block} \end{frame} \begin{frame}{Összefoglalás -- Előnyök} \begin{exampleblock}{Előnyök} \begin{itemize} \item Gyors setup -- másodpercek alatt \item Konzisztens környezet minden fejlesztőnél \item Reprodukálható, verziókezelhető \end{itemize} \end{exampleblock} \end{frame} \begin{frame}{Összefoglalás -- Kulcs koncepciók} \begin{block}{Fő elemek} \begin{itemize} \item \texttt{services}: Mi fusson (konténerek definíciója) \item \texttt{volumes}: Adatok perzisztálása \item \texttt{networks}: Szolgáltatások összekapcsolása \end{itemize} \end{block} \begin{alertblock}{Következő lépés} Docker hálózatok részletesen \end{alertblock} \end{frame}