</> Docker & Local Data Platform

0 / 16 section completed
Section 00

Docker alapok Docker Grafana Prometheus

A Docker konténerizáció a modern data engineering alapköve. Ahelyett, hogy minden szolgáltatást egyesével telepítenénk a gépünkre (PostgreSQL, Spark, Airflow stb.), Docker containerekbe csomagoljuk őket — így minden másodperc alatt indul, izoláltan fut, és könnyen reprodukálható. Egy docker-compose.yml fájlban leírjuk a teljes infrastruktúrát, amit egyetlen paranccsal életre kelthetünk.

Ez a megközelítés kulcsfontosságú a data engineeringben, mert a valóságban sosem egyetlen adatbázissal dolgozunk. Egy tipikus adatplatform tartalmaz adattárolót, feldolgozó motort, ütemezőt, kísérkövető rendszert és monitoringot is. Docker Compose-szal ezt az egész rendszert lokálisan felépíthetjük, tesztelhetjük, és ami a legfontosabb: megoszthatjuk a csapattal.

Ebben a kurzusban lépésről lépésre megismerjük a Docker alapjait, majd felépítünk egy teljes lokális data platformot hét szolgáltatással: PostgreSQL (adatbázis), MinIO (S3-compatible objektumtároló), Spark (big data feldolgozás), Airflow (workflow ütemezés), MLflow (ML kísérkövetés), Prometheus (metrikagyűjtés) és Grafana (vizualizáció).

Pro tipp: Mindig a lehető legegyszerűbb docker-compose.yml-lal indulj, és egyesével add hozzá a szolgáltatásokat — így sokkal könnyebb debugolni, ha valami nem működik.

Tartalom

Dockerfile, Compose, Postgres, MinIO, Spark, Airflow, MLflow, Prometheus, Grafana

Projekt

Teljes lokális data stack: 7 szolgáltatás egy paranccsal!

Szójegyzék

Docker Compose · MinIO · Prometheus

Section 01

Docker alapok: image, container, volume

A Docker három alapeleme az image, a container és a volume. Az image egy sablon — például a python:3.11 image tartalmazza a Python futtatókörnyezetet és minden szükséges rendszerkönyvtárat. A container ennek az image-nek egy futó példánya: izolált folyamat, amely a saját fájlrendszerével és hálózatával rendelkezik. A volume pedig a perzisztens adattárolásért felel, mert alapértelmezetten minden container adat elveszik, amikor leáll.

A data engineeringben ezek a fogalmak mindennaposak. Amikor egy ETL pipeline-t Docker-ben futtatunk, az image tartalmazza a kódot és függőségeket, a container futtatja a folyamatot, és a volume őrzi az eredményeket — például a feldolgozott adatfájlokat vagy az adatbázis tartalmát.

A kódblokkban három parancsot látunk: docker run -it python:3.11 python --version letölti és elindítja a Python image-et, majd kiírja a verziót. A docker ps felsorolja a futó containereket. A docker run -v $(pwd)/data:/app/data mountolja a lokális data mappát a container /app/data útvonalára, így a container hozzáfér a lokális fájlokhoz.

Pro tipp: A -v (volume) flag nélkül minden fájl, amit a containerben létrehoznak, eltűnik a container törlésekor — ez az egyik leggyakoribb kezdő hiba!

ParancsLeírás
docker runContainer indítás
docker psFutó containerek
docker execParancs futtatás containerben
docker logsNapló megtekintés
docker buildImage építés
[1]
# Pull and run Python container
docker run -it python:3.11 python --version

# List running containers
docker ps

# Run with volume mount
docker run -v $(pwd)/data:/app/data python:3.11 ls /app/data
Output:
Python 3.11.8

CONTAINER ID   IMAGE         STATUS
abc123         python:3.11   Up 5 seconds

orders.csv
products.csv
customers.csv
Section 02

Dockerfile: saját image építés

A Dockerfile egy szöveges fájl, amely lépésről lépésre leírja, hogyan építsük fel a saját Docker image-ünket. Ez a Docker "receptje" — minden sor egy utasítás, amely rétegeket (layer) hoz létre az image-ben. A legfontosabb utasítások: FROM (alapimage megadása), WORKDIR (munkakönyvtár beállítása), COPY (fájlok másolása a hostról), RUN (parancs futtatása az építés során) és CMD (alapértelmezett parancs a container indulásakor).

A data engineeringben a Dockerfile akkor válik nélkülözhetetlenné, amikor saját ETL pipeline-t akarunk containerizálni. Ahelyett, hogy minden gépen manuálisan telepítenénk a Python csomagokat és beállítanánk a környezetet, egy Dockerfile-ba foglaljuk az egészet — és bárki egyetlen docker build paranccsal reprodukálhatja a környezetet.

A kódblokkban egy ETL pipeline Dockerfile-ját látjuk. A FROM python:3.11-slim egy minimalista Python image-ből indul. A WORKDIR /app beállítja a munkakönyvtárat. A COPY requirements.txt . és az azt követő RUN pip install először csak a függőségeket másolja és telepíti — ez egy fontos optimalizálás, mert a Docker cache-eli a rétegeket, így ha csak a kód változik, a csomagok nem települnek újra. Végül a COPY . . másolja a teljes projektet, a CMD pedig elindítja a pipeline-t.

Pro tipp: Mindig a requirements.txt-et másold és telepítsd először, különben minden kódmódosításnál újra települnek a csomagok — ami perceket spórol a build időnél!

[2]
# Dockerfile for ETL pipeline
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "pipeline.py"]
Output:
$ docker build -t webshop-etl .
[+] Building 45.2s (9/9) FINISHED
 => exporting to image
Section 03

Docker Compose alapok

A Docker Compose egy eszköz, amely lehetővé teszi több container (szolgáltatás) definíálását és kezelését egyetlen YAML fájlban. Ahelyett, hogy minden containert külön docker run paranccsal indítgassunk — tucatnyi környezeti változóval, porttal és volume-mal —, mindent leírunk a docker-compose.yml-be, és egy docker-compose up -d paranccsal az összes szolgáltatás elindul.

Ez a data engineering "game changer"-je, mert egy valós adatplatform tipikusan 5-10 szolgáltatásból áll. Képzeld el, hogy minden reggel kézzel kellene indítanod a Postgres-t, a MinIO-t, a Spark-ot, az Airflow-t és a monitoringot — a Compose ezt egy paranccsal megoldja, ráadásul biztosítja a szolgáltatások közötti hálózati kommunikációt is.

A példában a legalapvetőbb Compose struktúrát látjuk: a version: '3.8' a fájl formátum verziója. A services blokk alatt definiáljuk a szolgáltatásokat — itt egy postgres nevű service-t, amely a postgres:16 image-et használja. Az environment szekcióban adjuk meg az adatbázis nevét, felhasználót és jelszót. A ports: '5432:5432' a container 5432-es portját a host azonos portjára mappeleli. A volumes: pgdata:/var/lib/postgresql/data biztosítja, hogy az adatok perzisztensek maradjanak.

Pro tipp: A -d (detached) flag nélkül a docker-compose up blokkolja a terminált — fejlesztéshez mindig használd a -d-t, és docker-compose logs -f-fel nézd a naplókat!

[3]
# docker-compose.yml - Basic structure
version: '3.8'
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: webshop
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
    ports:
      - '5432:5432'
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
Output:
$ docker-compose up -d
[+] Running 2/2
 ✔ Network default  Created
 ✔ Container postgres  Started
Section 04

PostgreSQL konténer

A PostgreSQL a data engineering leggyakrabban használt relációs adatbázisa, és Docker-ben kiválóan futtatható. A hivatalos postgres:16 image tartalmaz egy különleges funkciót: a /docker-entrypoint-initdb.d mappába helyezett SQL és shell scriptek automatikusan lefutnak az adatbázis első indulásakor. Ez lehetővé teszi, hogy a séma létrehozását, seed adatok betöltését és felhasználói jogosultságok beállítását automatizáljuk.

Ez a funkció kritikus a data engineeringben, mert így garantálható, hogy minden fejlesztő azonos adatbázissémával és tesztadatokkal dolgozik. Amikor egy új csapattag csatlakozik, egyetlen docker-compose up paranccsal azonnal egy teljesen felépített adatbázist kap — nem kell manuálisan SQL scripteket futtatnia.

A kódblokkban a Postgres container kibővített konfigurációját látjuk. Az environment blokkban csak az adatbázis nevet adjuk meg (POSTGRES_DB: webshop_pro), a felhasználó és jelszó a korábbi .env vagy alapértelmezett beállításokból jön. A volumes: ./init:/docker-entrypoint-initdb.d mountolja a lokális init mappát — ide tett .sql fájlok automatikusan végrehajtódnak. A healthcheck blokk alapvető: pg_isready paranccsal ellenőrzi, hogy az adatbázis fogad-e kapcsolatokat, 5 másodpercenként, maximum 5 próbálkozással.

Pro tipp: A healthcheck nélkül más szolgáltatások (pl. Airflow, MLflow) megpróbálhatnak csatlakozni az adatbázishoz, mielőtt az még elindulna — a depends_on csak a container indulását várja meg, nem azt, hogy az adatbázis tényleg készen áll!

[4]
# docker-compose.yml - Postgres section
  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: webshop_pro
    volumes:
      - ./init:/docker-entrypoint-initdb.d
    ports:
      - '5432:5432'
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U admin']
      interval: 5s
      retries: 5
Output:
$ docker-compose up postgres
postgres  | database system is ready to accept connections
postgres  | /docker-entrypoint-initdb.d/01_schema.sql executed
Section 05

MinIO: S3-compatible storage

A MinIO egy nyílt forráskódú, S3-compatible objektumtároló, amely lokális fejlesztői környezetben tökéletes helyettesíti az AWS S3-at. Teljesen ugyanazt az API-t beszéli, így a kód, amit lokálisan a MinIO-val írsz, élesben változtatás nélkül működik az AWS S3-on — csak a connection endpointot kell átírni. Ez a "develop locally, deploy globally" elv alapja.

A data engineeringben az objektumtárolók (S3, GCS, Azure Blob) a modern data lake architektúrák központi elemei. Ide kerülnek a nyers adatok (raw zone), a feldolgozott adatok (curated zone), és a gépi tanulási modellek artifact-jai is. A MinIO lehetővé teszi, hogy ezt az architektúrát a saját gépeden építsd ki, felhő költségek nélkül.

A kódblokkban a MinIO container konfigurációját látjuk. A command: server /data --console-address ':9001' kulcsfontosságú: a server /data elindítja az objektumtároló szervert a /data könyvtárra, a --console-address ':9001' pedig elérhetővé teszi a webes admin felületet. A ports szekció két portot expose-ol: a 9000-es az S3 API port (ide csatlakozik a boto3 vagy az MLflow), a 9001-es pedig a webes konzol, ahol böngészőből kezelheted a bucket-eket.

Pro tipp: Alapértelmezetten a MinIO a minioadmin/minioadmin hitelesítő adatokkal indul — éleshez sose használd ezeket, de lokális fejlesztéshez tökéletesek!

[5]
# docker-compose.yml - MinIO
  minio:
    image: minio/minio
    command: server /data --console-address ':9001'
    ports:
      - '9000:9000'
      - '9001:9001'
    volumes:
      - minio_data:/data
Output:
$ docker-compose up minio
MinIO Object Storage Server
Status:         1 Online, 0 Offline
Console: http://localhost:9001
Section 06

Spark konténer Spark

Az Apache Spark a big data feldolgozás de facto szabványa, és Docker-ben egy standalone clusteret építhetünk belőle. A cluster két komponensből áll: egy Master node-ból, amely koordinálja a feladatokat, és egy vagy több Worker node-ból, amelyek a tényleges számítást végzik. Ez az architektúra lehetővé teszi, hogy párhuzamosan dolgozzunk fel nagy adathalmazokat — pontosan úgy, ahogy egy éles Spark cluster működik.

A data engineeringben a Spark akkor kerül képbe, amikor az adatok mérete meghaladja az egy gép kapacitását. Ha egy Pandas DataFrame már nem fér a memóriába (több GB-os fájlok), vagy ha a feldolgozás órákig tart egy szálon, a Spark elosztja a munkát több Worker között, és perceken belül végez. A PySpark API lehetővé teszi, hogy Pythonból használjuk ezt a teljesítményt.

A kódblokkban a Spark cluster Compose definícióját látjuk. A spark-master service a hivatalos Apache Spark image-et használja, és a command paraméterben elindítja a Master folyamatot a 7077-es porton, webes UI-val a 8080-on. A spark-worker csatlakozik a Masterhez a spark://spark-master:7077 címen — figyeld meg, hogy itt a szolgáltatás nevét használjuk címként, a Docker belső DNS-e feloldja. A Worker --cores 1 --memory 1G korlátokkal indul, ezeket a saját géped erőforrásaihoz érdemes igazítani.

Pro tipp: A depends_on: spark-master biztosítja, hogy a Worker csak a Master után induljon, de ha a Master még nem készült el teljesen, a Worker újrapróbálkozik — érdemes a Worker-hez is restart policy-t adni!

[6]
# docker-compose.yml - Spark
  spark-master:
    image: apache/spark:3.5.3-scala2.12-java17-python3-ubuntu
    command: ["/opt/spark/bin/spark-class", "org.apache.spark.deploy.master.Master", "--host", "spark-master", "--port", "7077", "--webui-port", "8080"]
    ports:
      - '8080:8080'
      - '7077:7077'

  spark-worker:
    image: apache/spark:3.5.3-scala2.12-java17-python3-ubuntu
    command: ["/opt/spark/bin/spark-class", "org.apache.spark.deploy.worker.Worker", "spark://spark-master:7077", "--cores", "1", "--memory", "1G", "--webui-port", "8081"]
    depends_on:
      - spark-master
Output:
$ docker compose up spark-master spark-worker
Spark Master: running at spark://localhost:7077
Web UI: http://localhost:8080
Workers: 1 alive
Section 07

Airflow konténer Airflow

Az Apache Airflow a data engineering legnépszerűbb workflow-ütemezője. DAG-okat (Directed Acyclic Graph) definiálunk benne, amelyek leírják, milyen sorrendben fussanak az egyes feladatok — például "először töltsd le az adatot, aztán tisztítsd, végül töltsd be az adatbázisba". Az Airflow webserver-e biztosítja a webes felületet, a scheduler pedig figyeli és elindítja a feladatokat a megadott ütemezés szerint.

A data engineeringben az Airflow a "brain" szerepét tölti be: minden ETL pipeline, adatfrissítés és modellezési workflow itt van definiálva és ütemezve. Nélküle minden folyamatot manuálisan kellene indítani, vagy cron job-okkal bütykölni — az Airflow ehhez kérist láthatóságot, újraindítást, alerteket és audit trail-t ad.

A kódblokkban az Airflow container egyszerűsített konfigurációját látjuk. A command: standalone egy specialált mód, amely egyetlen containerben elindítja a webservert, a schedulert és az adatbázist — fejlesztésre tökéletes. A ports: '8081:8080' a container 8080-as portját a host 8081-es portjára mappeleli (azért 8081, mert a 8080-at a Spark foglalja). A volumes: ./dags:/opt/airflow/dags mountolja a lokális DAG mappát, így szerkesztheted a Python fájlokat, és az Airflow azonnal észleli a változásokat. Az environment megadja a PostgreSQL connection string-et, amit az Airflow a metaadatok tárolásához használ.

Pro tipp: Az Airflow standalone mód nem éles használatra való — production-ben a CeleryExecutor-t és külön schedulert használnak, de lokális fejlesztéshez a standalone a legkényelmesebb megoldás.

[7]
# docker-compose.yml - Airflow
  airflow:
    image: apache/airflow:2.8
    command: standalone
    ports:
      - '8081:8080'
    volumes:
      - ./dags:/opt/airflow/dags
    environment:
      AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql://admin:secret@postgres/airflow
    depends_on:
      spark-master:
        condition: service_started
Output:
$ docker-compose up airflow
airflow | webserver running at 0.0.0.0:8080
airflow | scheduler started
Section 08

MLflow konténer MLflow

Az MLflow a gépi tanulás kísérletkövető rendszere, amelyet a Databricks fejlesztett. Három fő funkciója van: tracking (kísérletek paramétereinek, metrikáinak naplózása), model registry (modellek verziózása és tárolása) és model serving (modellek Deploy-olása). Docker-ben a tracking server-ként futtatjuk, amely egyetlen központi helyet biztosít az összes ML kísérlet kezeléséhez.

A data engineeringben az MLflow egyre fontosabb szerepet játszik, mert a modern adatplatformok nem csak adatot mozgatnak, hanem modelleket is. Egy tipikus MLOps pipelineben az MLflow követi a modellek tanítási paramétereit (learning rate, epochs stb.), a metrikákat (accuracy, F1 score) és az artifactokat (magát a modellt, konfúziós mátrixot). Így később pontosan rekonstruálható, melyik modell milyen adatokból és beállításokkal készült.

A kódblokkban az MLflow server konfigurációját látjuk. A --backend-store-uri postgresql://... azt mondja meg, hogy a kísérleti adatokat (paraméterek, metrikák) PostgreSQL-ben tárolja — ez tartós és lekérdezhető. A --default-artifact-root s3://mlflow/artifacts az artifactokat (modellek, grafikonok) az S3-compatible MinIO-ba irányítja, az s3://mlflow/artifacts útvonalra. A --host 0.0.0.0 biztosítja, hogy a server a container összes interfészén hallgasson, ne csak a localhost-on.

Pro tipp: Az MLflow kliensnek is be kell állítani az S3 endpointot a MinIO-hoz — használd az MLFLOW_S3_ENDPOINT_URL=http://minio:9000 környezeti változót a containerben!

[8]
# docker-compose.yml - MLflow
  mlflow:
    image: ghcr.io/mlflow/mlflow:v2.10
    ports:
      - '5000:5000'
    command: >
      mlflow server
      --backend-store-uri postgresql://admin:secret@postgres/mlflow
      --default-artifact-root s3://mlflow/artifacts
      --host 0.0.0.0
Output:
$ docker-compose up mlflow
MLflow running on http://localhost:5000
Section 09

Prometheus + Grafana Prometheus Grafana

A Prometheus és a Grafana együtt alkotják a data engineering világ legnépszerűbb monitoring stackjét. A Prometheus egy time-series adatbázis, amely rendszeres időközönként (alapértelmezetten 15 másodpercenként) lekéri a megfigyelt szolgáltatások metrikáit — például CPU használat, memória, kérés-szám, hibaarány. A Grafana pedig egy vizualizációs eszköz, amely ezeket az adatokat valós idejű dashboardokon jeleníti meg.

A data engineeringben a monitoring nem luxus, hanem szükségszerűség. Ha egy ETL pipeline órákig fut, tudni kell, melyik lépés lassú. Ha az adatbázis kapcsolatok száma megugrik, azt korábban észre kell venni, mielőtt összeomlik a rendszer. A Prometheus + Grafana párossal minden szolgáltatás állapotát egyetlen dashboard-on követheted.

A kódblokkban mindkét szolgáltatás konfigurációját látjuk. A Prometheus a ./prometheus.yml konfigurációs fájlt mountolja be — ez tartalmazza a "scrape" célokat, vagyis hogy mely szolgáltatásoktól gyűjtsön metrikákat. A Grafana az admin/admin alapértelmezett jelszóval indul, és a depends_on: prometheus biztosítja, hogy csak a Prometheus után induljon el. A Grafanában első lépésként hozzá kell adni a Prometheust adatforrásként, majd dashboardokat építeni rá.

Pro tipp: A Prometheus csak azokat a szolgáltatásokat tudja monitorozni, amelyek expose-olnak egy /metrics végpontot — sok alkalmazásnak külön kell beállítani ezt, de a Postgres, Spark és Airflow mind rendelkeznek exporter-rel!

[9]
# docker-compose.yml - Monitoring
  prometheus:
    image: prom/prometheus
    ports:
      - '9090:9090'
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - '3000:3000'
    environment:
      GF_SECURITY_ADMIN_PASSWORD: admin
    depends_on:
      - prometheus
Output:
$ docker-compose up prometheus grafana
Prometheus: http://localhost:9090
Grafana: http://localhost:3000 (admin/admin)
Section 09b

Adminer: PostgreSQL webes felület

Az Adminer egyetlen PHP fájlból álló, ultrakönnyű adatbázis-kezelő felület — a phpMyAdmin modernebb, karcsúbb alternatívája. Docker-ben az adminer image mindössze ~50 MB, és egyetlen containert indít, amelyen keresztül vizuálisan böngészheted a PostgreSQL adatbázisokat, táblákat, lekérdezéseket futtathatsz, és adatokat módosíthatsz — mindezt egy letisztult webes felületen.

A data engineeringben az Adminer felbecsülhetetlen segítség a fejlesztés során. Amikor Bronze/Silver/Gold pipeline-t építesz, látnod kell, mi került az adatbázisba. Amikor egy dbt modellezés nem adja a várt eredményt, gyors SELECT-tel ellenőrizheted a nyers adatokat. Amikor seed adatokat töltesz be, vizuálisan ellenőrizheted, hogy a táblák helyesek-e. Mindezt parancssori psql nélkül, kattintgatva.

A kódblokkban az Adminer konfigurációját látjuk. A image: adminer a hivatalos, mindig naprakész image-t húzza. A ports: '8082:8080' a 8080-as belső portot a host 8082-es portjára mappeli (8080=Spark, 8081=Airflow, 8082=Adminer). A depends_on: postgres biztosítja, hogy csak a PostgreSQL indulása után induljon el. A belépéshez a webes felületen használd: szerver=postgres, felhasználó=admin, jelszó=secret, adatbázis=postgres.

Pro tipp: Az Adminer nem csak PostgreSQL-t támogat — MySQL, SQLite, MongoDB, Oracle és MS SQL driver-eket is tartalmaz, így egyetlen containerrel bármilyen adatbázist elérhetsz a platformodon!

[9b]
# docker-compose.yml - Adminer (Postgres UI)
  adminer:
    image: adminer
    ports:
      - '8082:8080'
    depends_on:
      - postgres
Output:
$ docker-compose up adminer
Adminer: http://localhost:8082
Login: server=postgres, user=admin, password=secret
Section 09c

Kafka UI: üzenetsor vizualizáció

A Provectus Kafka UI (most már HoloInsight/kafka-ui néven is elérhető) a legnépszerűbb nyílt forráskódú, lightweight felület az Apache Kafka klaszterek kezeléséhez. Egy letisztult webes UI-n keresztül böngészheted a topicokat, consumer csoportokat, üzeneteket, és valós időben láthatod, mi folyik az üzenetsorban — mindent, amit amúgy csak a kafka-topics.sh és kafka-console-consumer.sh parancssori eszközökkel tudnál.

A data engineeringben a Kafka UI elengedhetetlen a streaming pipelineok fejlesztése során. Amikor egy producer nem küld üzeneteket, a UI-ban azonnal látod, hogy a topic üres. Amikor a consumer lemaradt, a lag grafikonon egyértelműen megjelenik. Amikor sémát módosítasz, vizuálisan ellenőrizheted az üzenetek formátumát. A parancssori Kafka eszközök használata fárasztó és hibaállékony — a UI mindent átláthatóvé tesz.

A kódblokkban a Kafka UI konfigurációját látjuk. A image: provectuslabs/kafka-ui a legstabilabb, legkönnyebb Kafka UI image. A KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS környezeti változó mondja meg, hol fut a Kafka broker — ha a Kafka is ebben a docker-compose-ban van, akkor egyszerűen kafka:9092. A port 8083:8080 a host 8083-as portjára mappeli (8080=Spark, 8081=Airflow, 8082=Adminer, 8083=Kafka UI).

Pro tipp: Ha a Kafka még nem fut ebben a compose-ban, csak hagyd a KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS változót üresen, és később a Settings-ben is hozzáadhatod a klasztert. A Kafka UI több klasztert is támogat egyidejűleg!

[9c]
# docker-compose.yml - Kafka UI
  kafka-ui:
    image: provectuslabs/kafka-ui:latest
    ports:
      - '8083:8080'
    environment:
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092
      DYNAMIC_CONFIG_ENABLED: 'true'
Output:
$ docker-compose up kafka-ui
Kafka UI: http://localhost:8083
Topics: 0 | Consumer Groups: 0
Section 10

Docker networking

A Docker networking határozza meg, hogyan kommunikálnak egymással a containerek. A három legfontosabb hálózati típus: a bridge (alapértelmezett, izolált hálózat, ahol a containerek név alapján elérik egymást), a host (nincs hálózati izoláció, a container közvetlenül a host hálózatát használja), és az overlay (több gépre kiterjedő hálózat, Swarm vagy Kubernetes környezetben). A Docker Compose automatikusan létrehoz egy bridge hálózatot minden projekthez, és a szolgáltatások a saját nevükön (pl. postgres, minio) hivatkozhatnak egymásra.

A data engineeringben a hálózati konfiguráció akkor válik kritikussá, amikor több szolgáltatásnak kell egymással kommunikálnia. Például az MLflow-nak el kell érnie a Postgres-t (metaadatok) és a MinIO-t (artifactok), az Airflow-nak csatlakoznia kell a Postgres-hez (backend), a Spark Worker-nek pedig el kell érnie a Master-t. A Docker belső DNS-e automatikusan feloldja a szolgáltatásneveket IP-címekké — ezért működik a postgresql://admin:secret@postgres:5432 connection string.

A kódblokkban egy custom bridge hálózatot definiálunk data-platform néven. A driver: bridge jelzi, hogy ez egy standard izolált hálózat. A postgres és spark szolgáltatásokat a networks: - data-platform sorral csatlakoztatjuk ehhez a hálózathoz. A kommentek mutatják, hogy a szolgáltatások a nevükön és a portjukon elérik egymást: postgres:5432, minio:9000, spark-master:7077 — mindezt külső IP-címek vagy localhost használata nélkül.

Pro tipp: Ha két szolgáltatás nem látja egymást, ellenőrizd, hogy ugyanazon a hálózaton vannak-e — a docker network inspect data-platform paranccsal listázhatod a hálózatra csatlakozott containereket!

HálózatLeírás
bridgeAlapértelmezett, izolált hálózat
hostHost hálózat, nincs izoláció
overlayMulti-host, Swarm/K8s
noneNincs hálózat
[10]
# Custom network for services
networks:
  data-platform:
    driver: bridge

services:
  postgres:
    networks:
      - data-platform
  spark:
    networks:
      - data-platform

# Services can reach each other by name:
# postgres:5432, minio:9000, spark-master:7077
Output:
$ docker network ls
NETWORK ID   NAME              DRIVER
abc123       data-platform     bridge
Section 11

Volumes és persistent data

A Docker volumes a perzisztens adattárolás megoldásai. Két fő típust különböztetünk meg: a named volumes-okat (Docker által kezelt tárolók, mint a pgdata vagy minio_data) és a bind mounts-okat (host fájlrendszer közvetlen csatolása, mint a ./dags:/opt/airflow/dags). Named volumes Docker Compose újraindítás után is megőrzik az adatokat, míg a bind mounts valós idejű szinkronizációt biztosít a host és a container között.

A data engineeringben az adatvesztés az egyik legnagyobb kockázat. Ha egy Postgres container összeomlik és újraépül, de nincs volume, az összes adatbázis-tartalom eltűnik. Ugyanez igaz a MinIO-ban tárolt fájlokra és az MLflow kísérleti adataira. A volume-ok biztosítják, hogy a containerek állapota (state) túléli a container újraépítését, törlését vagy a gép újraindítását.

A kódblokkban a teljes volume stratégiát látjuk. A volumes szekció deklarál három named volume-ot: pgdata (Postgres adatok), minio_data (MinIO objektumok) és spark_data (Spark munkaadatok). A backup stratégia két részből áll: docker exec postgres pg_dump SQL dumpot készít az adatbázisról, a második parancs pedig egy ideiglenes Alpine container-rel tar.gz archívumba csomagolja a volume tartalmát. Ez a --rm flag miatt az Alpine container a futás után automatikusan törlődik.

Pro tipp: A docker-compose down -v parancs törli a volume-okat is — ha csak meg akarod állítani a szolgáltatásokat, használd a sima docker-compose down-t, és az adatok megmaradnak!

[11]
# Named volumes
volumes:
  pgdata:
  minio_data:
  spark_data:

# Backup strategy
# 1. pg_dump
docker exec postgres pg_dump -U admin webshop_pro > backup.sql

# 2. Volume backup
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine tar czf /backup/pgdata.tar.gz /data
Output:
$ ls backup/
backup.sql  pgdata.tar.gz  minio_backup.tar.gz
Total size: 125MB
Section 12

Environment és secrets

Az environment változók és a secrets kezelése a Docker Compose biztonságának alapja. Az .env fájl egy egyszerű szöveges fájl, amely kulcs-érték párokat tartalmaz, és a Docker Compose automatikusan betölti a projektkönyvtárból. Ezeket az értékeket a YAML-ben a ${VARIABLE_NAME} szintaxissal hivatkozhatjuk — így a jelszavak, API kulcsok és connection stringek nem kerülnek be a verziókezelőbe (git-be).

A data engineeringben ez különösen fontos, mert egy adatplatform tucatnyi érzékeny adatot kezel: adatbázis jelszavak, S3 access kulcsok, API tokenek. Ha ezek bekerülnek a kódba, bárki hozzáférhet az éles rendszerhez. Az .env fájlt hozzá kell adni a .gitignore-hoz, és a csapat minden tagja létrehozza a sajátját — vagy CI/CD környezetben titkosított vault-ból töltődnek be az értékek.

A kódblokkban egy tipikus .env fájlt látunk. A POSTGRES_PASSWORD, MINIO_ROOT_USER és MINIO_ROOT_PASSWORD a szolgáltatások hitelesítő adatai. Az MLFLOW_TRACKING_URI egy belső URL, amit más szolgáltatások használnak az MLflow eléréséhez. Lent a docker-compose.yml mutatja, hogyan hivatkozunk rá: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} — a Docker Compose behelyettesíti az .env fájlból olvasott értéket.

Pro tipp: Oszd meg a csapattal egy .env.example fájlt (minta értékekkel), és a valódi .env-et add hozzá a .gitignore-hoz — így mindenki tudja, milyen változókat kell beállítania, de a jelszavak nem szivároghatnak ki!

[12]
# .env file
POSTGRES_PASSWORD=super_secret_123
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=minio_secret
MLFLOW_TRACKING_URI=http://mlflow:5000

# docker-compose.yml references
services:
  postgres:
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
Output:
# .env loaded automatically
POSTGRES_PASSWORD=super_secret_123 (from .env)
Section 13

Teljes data platform docker-compose.yml

Most jön a legizgalmasabb rész: az összes korábban megismert szolgáltatást egyetlen docker-compose.yml fájlba foglaljuk. A 10 szolgáltatás együtt alkotja a teljes lokális data platformot: PostgreSQL (relációs adatbázis, port 5432), MinIO (S3 objektumtároló, port 9000/9001), Spark Master (cluster koordinátor, port 8080/7077), Spark Worker (számítási node), Airflow (workflow ütemező, port 8081), MLflow (ML kísérkövetés, port 5000), Prometheus (metrikagyűjtés, port 9090), Grafana (vizualizáció, port 3000), Adminer (Postgres UI, port 8082) és Kafka UI (üzenetsor vizualizáció, port 8083).

Ez az architektúra a modern data platform "minimum viable" verziója. A valóságban az AWS, GCP vagy Azure hasonló szolgáltatásokat nyújt felügyelt formában (RDS, S3, EMR, MWAA stb.), de lokálisan ez a Docker Compose adja meg ugyanazt a funkcionalitást — ingyen, a saját gépeden. Minden szolgáltatás ugyanazon a Docker hálózaton van, így zökkenőmentesen kommunikálnak egymással.

A kódblokkban a teljes docker-compose.yml vázlatát látjuk. Minden szolgáltatás port-térképezéssel és volume-mal van konfigurálva. A legfontosabb parancs a docker-compose up -d: ez letölti a szükséges image-eket (első alkalommal), létrehozza a hálózatot és volume-okat, majd elindítja mind a 10 containert. Az output mutatja, ahogy minden szolgáltatás egymás után elindul — a healthcheck-ekkel ellátottak (postgres, minio, airflow) a "healthy" státuszt is elérnek.

Pro tipp: Ha valamelyik szolgáltatás nem indul, ne az egészet indítsd újra — használd a docker-compose logs <service_name> parancsot, hogy lásd, mi a hiba, és csak a problémás szolgáltatást indítsd újra!

[13]
# Complete docker-compose.yml
version: '3.8'
services:
  postgres:  { ... 5432 }
  minio:     { ... 9000-9001 }
  spark-master: { ... 8080, 7077 }
  spark-worker: { depends_on: spark-master }
  airflow:   { ... 8081 }
  mlflow:    { ... 5000 }
  prometheus: { ... 9090 }
  grafana:   { ... 3000 }
  adminer:   { ... 8082 }
  kafka-ui:  { ... 8083 }

# One command to rule them all:
# docker-compose up -d
Output:
$ docker-compose up -d
[+] Running 10/10
 ✔ Container postgres       Started (healthy)
 ✔ Container minio          Started (healthy)
 ✔ Container spark-master   Started
 ✔ Container spark-worker   Started
 ✔ Container airflow        Started (healthy)
 ✔ Container mlflow         Started
 ✔ Container prometheus     Started
 ✔ Container grafana        Started
 ✔ Container adminer        Started
 ✔ Container kafka-ui       Started

All services running!
Section 14

Health checks, resource limits

A health check-ek és a resource limit-ek a production-ready Docker konfiguráció két alappillére. A health check rendszeres időközönként ellenőrzi, hogy egy szolgáltatás valóban készen áll-e — nem csak a container fut, hanem az alkalmazás is válaszol. A resource limit-ek pedig biztosítják, hogy egyetlen szolgáltatás sem fogyasztja el az összes rendszererőforrást, ami az egész platform összeomlásához vezethetne.

A data engineeringben ezek a beállítások különösen fontosak, mert egy adatplatform erőforrás-igényes szolgáltatásokat futtat. A Spark Worker például több GB memóriát használhat egy nagy adathalmaz feldolgozásakor, és ha nincs korlát, "megfojthatja" a Postgres-t vagy az Airflow-t. A health check-ek nélkül pedig a Docker nem tudja, hogy egy adatbázis tényleg fogad-e lekérdezéseket — csak azt látja, hogy a container fut.

A kódblokk mindkét fogalmat bemutatja. A Postgres health check a pg_isready paranccsal ellenőriz 10 másodpercenként, 5 másodperces időkorláttal, maximum 5 próbálkozással. A Spark Worker deploy.resources.limits blokkja 2 CPU magot és 4 GB memóriát állít be felső korlátnak, a reservations pedig garantál 2 GB-ot. A restart: unless-stopped biztosítja, hogy ha a container összeomlik, automatikusan újrainduljon — kivéve, ha mi magunk állítottuk meg.

Pro tipp: Mindig állíts be memory limit-et a Spark Worker-nez — különben egyetlen nagy Spark job "kiszívhatja" a memóriát az összes többi szolgáltatás elől, és az egész platform instabillá válik!

[14]
# Health check example
  postgres:
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready']
      interval: 10s
      timeout: 5s
      retries: 5

# Resource limits
  spark-worker:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          memory: 2G

# Restart policy
    restart: unless-stopped
Output:
Health checks: All passing
Resource usage:
  postgres:     256MB / 1GB limit
  spark-worker: 1.8GB / 4GB limit
  grafana:      128MB / 512MB limit
Section 15

Összefoglalás

Gratulálunk! Felépítetted a teljes lokális data platformot — a Docker alapoktól a 10 szolgáltatásból álló stack-ig. Most már érted, miért használja az iparág a Docker-t: reprodukálhatóság, izoláció, és az a képesség, hogy egyetlen paranccsal felépíts egy teljes infrastruktúrát. Ezek a készségek közvetlenül átülhetők éles környezetbe — a konceptek ugyanazok, csak a futtatókörnyezet változik (Docker Compose helyett Kubernetes, lokális volume-ok helyett felhős tárolók).

Összegezve, mit tanultunk: Docker image-eket és containereket kezelsz, saját Dockerfile-t írsz, Docker Compose-szal több szolgáltatást koordinálsz, hálózatot és volume-okat konfigurálsz, környezeti változókat menedzselsz, health check-eket és resource limit-eket állítasz be. Mindezt egy valós adatplatform kontextusában: Postgres, MinIO, Spark, Airflow, MLflow, Prometheus, Grafana, Adminer és Kafka UI szolgáltatásokkal.

A következő kurzusokban ezt a platformot fogjuk használni alapul: a Delta Table Crash Course-on Bronze/Silver/Gold adatpipelines-t építünk Spark-pal, az Airflow Crash Course-on DAG-okat írunk, amelyek automatizálják a feldolgozást, és a monitoring kurzusban Grafana dashboardokat készítünk a platform állapotának nyomon követésére. A Docker alap, amire mindent építünk — most már szilárd alapokon állsz!

Következő lépés: Indítsd el a platformot (docker-compose up -d), nyisd meg a Grafanát (localhost:3000), és nézd meg, ahogy minden szolgáltatás bejelentkezik — aztán jöhet a Delta Table kurzus!

FelépítettükKövetkező
Postgres, MinIO, SparkDelta Table Crash Course
Airflow, MLflowBronze/Silver/Gold pipeline
Prometheus, GrafanaMonitoring dashboardek
Adminer (Postgres UI)Adatbázis böngészés vizuálisan
Kafka UIStreaming pipeline debug
Docker networking, volumesProduction best practices
Következő

Delta Table Crash Course - ahol a platformon építkezünk!

Quiz: Mi a Docker volume célja?

Quiz: Melyik nem Docker Compose kulcsszó?