Docker Compose használata: compose.yaml példákkal

Linux 13 perc olvasás

A Docker Compose egy YAML fájlban (compose.yaml) írja le, milyen konténerekből áll egy alkalmazás, és egyetlen paranccsal elindítja, frissíti vagy leállítja őket. Egy WordPress oldalhoz például két konténer kell (a webszerver a PHP-val és az adatbázis), a hozzájuk tartozó kötetekkel, jelszavakkal és hálózattal együtt. Hosszú docker run parancsok helyett mindez egy fájlban van, amelyet verziókezelőben is tárolhatsz, és egy másik szerverre átmásolva ugyanazt a környezetet kapod.

A Compose egy saját KVM VPS tipikus eszköze: így futtatható egymás mellett több önálló alkalmazás (például WordPress, n8n vagy egy saját webalkalmazás), mindegyik a saját mappájában, a saját beállításaival.

A lépéseket 2026 novemberében Ubuntu 24.04 rendszeren próbáltuk ki, a Docker saját tárolójából telepített Docker Engine 29.9.3 és Docker Compose 5.7.0 változattal. A parancsok AlmaLinuxon és Debianon is ugyanígy működnek.

Telepítés: docker compose vagy docker-compose?

A Compose ma a Docker parancssori eszköz bővítménye (plugin), a parancs neve ezért docker compose, szóközzel. A régi, Pythonban írt docker-compose (kötőjellel) az 1.x változat volt, amelyet 2023-ban kivezettek; a régi leírásokban ezzel találkozhatsz. A parancsok és a fájl formátuma szinte ugyanaz, csak a kötőjelet kell szóközre cserélni.

A Compose bővítmény a Docker telepítésekor a docker-compose-plugin csomaggal kerül fel (lásd: Docker telepítése Ubuntu, Debian és AlmaLinux rendszerre). Ellenőrzés:

docker compose version
Docker Compose version v5.7.0

A 2.x sorozat után a verziószám az 5-ösre ugrott; a parancsok és a compose.yaml formátuma ugyanaz maradt. Ha a docker compose parancsra „unknown command” a válasz, a bővítmény hiányzik: telepítsd a Docker tárolójából a docker-compose-plugin csomagot. Ubuntun a docker-compose parancs beírására a rendszer felajánlja az apt install docker-compose csomagot: ez a régi, 1.29-es változat, ne ezt telepítsd.

A cikk példáiban a felhasználó tagja a docker csoportnak, ezért a parancsok sudo nélkül szerepelnek. Ha nem tagja, írd eléjük a sudo-t.

A projekt felépítése

Minden alkalmazás kapjon egy saját mappát, benne a compose.yaml és a .env fájllal:

~/wordpress/
├── compose.yaml   # a szolgáltatások leírása
└── .env           # jelszavak és beállítások

A Compose a mappa nevét használja projektnévként: a konténerek, kötetek és hálózatok neve ezzel kezdődik (wordpress-db-1, wordpress_db_data). Ha más nevet szeretnél, a fájl elejére írj egy name: sajatnev sort.

A fájl neve a mai ajánlás szerint compose.yaml (a compose.yml is jó). A régi docker-compose.yml név továbbra is működik. Ha ugyanabban a mappában mindkettő megvan, a Compose figyelmeztet („Found multiple config files”) és a compose.yaml-t használja, ezért a régit nevezd át vagy töröld.

Példa: WordPress és MariaDB

Az alábbi compose.yaml egy WordPress oldalt és egy MariaDB adatbázist indít:

services:
  db:
    image: mariadb:11.8
    restart: unless-stopped
    environment:
      MARIADB_DATABASE: wordpress
      MARIADB_USER: wordpress
      MARIADB_PASSWORD: ${DB_PASSWORD:?Add meg a DB_PASSWORD-ot a .env fájlban}
      MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:?Add meg a DB_ROOT_PASSWORD-ot}
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  wordpress:
    image: wordpress:${WP_VERSION:-latest}
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
    ports:
      - "127.0.0.1:${WP_PORT:-8080}:80"
    volumes:
      - wp_data:/var/www/html
    networks:
      - backend

volumes:
  db_data:
  wp_data:

networks:
  backend:

A mellé tartozó .env fájl:

DB_PASSWORD=Valtoztassa-meg-1
DB_ROOT_PASSWORD=Valtoztassa-meg-2
WP_PORT=8080

A jelszavakat cseréld hosszú, véletlen értékekre (például openssl rand -base64 24), és a fájlt csak te olvashasd:

chmod 600 .env

A fájl elején nincs version: sor. A régi leírásokban szereplő version: "3.8" és hasonló kulcsot a Compose már nem használja; ha a fájlban marad, a teszten ezt a figyelmeztetést adta: „the attribute version is obsolete, it will be ignored”. Nyugodtan töröld.

Mit jelentenek a részek?

  • services: a konténerek. A szolgáltatás neve (db, wordpress) egyben a hálózati neve is: a WordPress a db névvel éri el az adatbázist (WORDPRESS_DB_HOST: db), IP-cím nélkül.
  • image: a használt kép és címke. Az adatbázisnál rögzítsd a fő verziót (mariadb:11.8), hogy egy frissítés ne hozzon váratlanul új főverziót.
  • restart: unless-stopped: a konténer leállás vagy a szerver újraindítása után magától elindul, kivéve, ha te állítottad le. A teszten egy újraindítás után a WordPress és a MariaDB magától elindult, a korábban docker compose stop-pal leállított konténer viszont leállítva maradt. A további lehetőségek: no (alapértelmezés), always, on-failure.
  • volumes: az adatok helye. A db_data és a wp_data nevesített kötet, amelyet a Docker kezel (/var/lib/docker/volumes/ alatt). A konténer törlése után is megmarad, így frissítéskor sem vesznek el az adatok.
  • ports: a 127.0.0.1:8080:80 a konténer 80-as portját a szerver 8080-as portjára köti, de csak a helyi címen. Kívülről így nem érhető el, csak egy elé tett fordított proxyn (reverse proxy) keresztül, lásd lent.
  • networks: a backend hálózat saját hálózat a két konténernek. Hálózat megadása nélkül a Compose magától létrehoz egy default hálózatot a projektnek; a nevesített hálózat akkor hasznos, ha több hálózatot szeretnél (lásd a proxyról szóló részt).
  • healthcheck és depends_on: a WordPress csak akkor indul, ha az adatbázis már válaszol (condition: service_healthy). A MariaDB hivatalos képében megtalálható a healthcheck.sh szkript. A teszten az első indításkor az adatbázis körülbelül 40 másodperc után lett healthy, a WordPress csak ezután indult el.

A depends_on sorrendje csak a docker compose up parancsra vonatkozik. A szerver újraindításakor a Docker a restart szabály alapján indítja a konténereket, és nem vár a függőségekre: a teszten újraindítás után a két konténer ugyanabban a másodpercben indult el. Az alkalmazásnak ezért el kell viselnie, ha az adatbázis az első néhány másodpercben még nem érhető el.

Változók és a .env fájl

A ${...} hivatkozásokat a Compose a projekt mappájában lévő .env fájlból (és a parancssor környezeti változóiból) tölti ki, még a konténerek indítása előtt:

Írásmód Jelentés
${DB_PASSWORD} A változó értéke; ha nincs megadva, üres szöveg (figyelmeztetéssel)
${WP_PORT:-8080} Alapérték: ha a változó üres vagy hiányzik, 8080
${DB_PASSWORD:?üzenet} Kötelező: ha hiányzik, a Compose hibaüzenettel leáll

A kötelező változó véd az üres jelszóval induló adatbázistól. A teszten .env nélkül a Compose el sem indította a projektet:

error while interpolating services.db.environment.MARIADB_PASSWORD: required variable DB_PASSWORD is missing a value: Add meg a DB_PASSWORD-ot a .env fájlban

A parancssorban megadott változó erősebb a .env fájlnál: WP_PORT=8090 docker compose up -d a 8090-es portot használja.

Ne keverd össze a .env fájlt a szolgáltatásoknál megadható env_file: kulccsal. A .env a compose.yaml-ban lévő ${...} helyekre kerül, az env_file: app.env viszont az ott felsorolt változókat közvetlenül a konténernek adja át, környezeti változóként. Ha egy alkalmazásnak sok beállítása van, az env_file rövidebb, mint mindet felsorolni az environment alatt.

Ellenőrzés és indítás

Indítás előtt ellenőrizd a fájlt:

cd ~/wordpress
docker compose config -q

Hiba nélkül nem ír ki semmit. A -q nélkül a teljes, kitöltött beállítást mutatja, a változók helyére írt értékekkel együtt: így látszik, mi kerül valójában a konténerekbe. Vigyázz, a jelszavak is olvashatóan szerepelnek benne, ezt a kimenetet ne másold fórumra vagy hibajegybe.

Indítás a háttérben:

docker compose up -d

Az első indításkor a Compose letölti a képeket, létrehozza a köteteket és a hálózatot, majd elindítja a konténereket. A -d nélkül előtérben fut, és a terminálban mutatja az összes konténer naplóját; ilyenkor a Ctrl+C leállítja a konténereket.

Mindennapi parancsok

Minden parancsot a projekt mappájában futtass (vagy add meg a fájlt a -f ~/wordpress/compose.yaml kapcsolóval).

Parancs Mit csinál
docker compose ps A projekt konténerei, állapotuk és portjaik
docker compose ls A gépen futó összes Compose projekt
docker compose logs -f Az összes konténer naplója, folyamatosan (kilépés: Ctrl+C)
docker compose logs --tail 50 wordpress Egy szolgáltatás utolsó 50 sora
docker compose exec db bash Parancssor a futó konténerben
docker compose restart wordpress Egy szolgáltatás újraindítása
docker compose stop Leállítás; a konténerek megmaradnak
docker compose start A leállított konténerek indítása
docker compose down Leállítás és a konténerek, a hálózat törlése; a kötetek megmaradnak
docker compose down -v Mint a down, de a köteteket, vagyis az adatokat is törli

A ps kimenete széles; a lényeges oszlopokat így kérheted le:

docker compose ps --format "table {{.Service}}\t{{.Status}}\t{{.Ports}}"

A docker compose ps, docker compose ls és docker volume ls kimenete: a db szolgáltatás healthy állapotban, a WordPress a 127.0.0.1:8080-as porton, alatta a két nevesített kötet

A naplóban minden sor elején a konténer neve áll, színnel megkülönböztetve:

A docker compose logs -f kimenete: a WordPress Apache-naplója és a MariaDB indulási üzenetei egymás alatt, konténerenként más színnel

Néhány hasznos exec példa:

# MariaDB parancssor a .env-ben megadott jelszóval
docker compose exec db mariadb -u wordpress -p wordpress

# PHP-verzió a WordPress konténerben
docker compose exec wordpress php -v

Szkriptben vagy cronból futtatva add hozzá a -T kapcsolót (docker compose exec -T ...), mert ott nincs terminál.

A down -v veszélye

A docker compose down csak a konténereket és a hálózatot törli; a következő up -d ugyanazokkal a kötetekkel, vagyis ugyanazokkal az adatokkal indul. A down -v viszont a projekt nevesített köteteit is törli, és ezzel az adatbázist és a feltöltött fájlokat is. A teszten a kötet a parancs után azonnal eltűnt („Volume proba_adat Removed”), megerősítés nélkül. Csak akkor használd, ha tényleg az egész projektet és az adatait szeretnéd eltávolítani, és előtte készíts mentést.

Frissítés

A képek frissítése két parancs:

docker compose pull
docker compose up -d

A pull letölti a címkék (például wordpress:latest, mariadb:11.8) legújabb képeit, az up -d pedig csak azokat a konténereket hozza létre újra, amelyeknek változott a képe vagy a beállítása; a többi fut tovább. A kötetekben lévő adatok megmaradnak. Ugyanígy érvényesíti az up -d a compose.yaml vagy a .env módosítását is: a teszten a WP_PORT átírása után csak a WordPress konténer indult újra, az új porton.

A régi képek a lemezen maradnak. Időnként takarítsd ki őket, ennek módjáról és a lemezhasználat ellenőrzéséről a Docker képek, konténerek és kötetek törlése cikk szól.

Főverzió-váltás előtt (például MariaDB 11.8 helyett egy újabb sorozat) mindig készíts mentést, és olvasd el a kép leírását a Docker Hubon: az adatbázisok egy része nem tud magától átállni az új főverzióra.

Saját kép építése

Ha az alkalmazásnak saját Dockerfile-ja van, az image helyett a build kulcs mondja meg, honnan építse a Compose:

services:
  web:
    build: ./app
    ports:
      - "127.0.0.1:8081:80"
docker compose build        # csak építés
docker compose up -d --build  # építés és indítás

Figyelem: a sima docker compose up -d nem építi újra a képet, ha az már létezik. A teszten a forrásfájl módosítása után az up -d még a régi tartalmat szolgálta ki, csak az up -d --build vette át az újat.

Fordított proxy: több alkalmazás egy szerveren

A példában a WordPress csak a 127.0.0.1:8080 címen hallgat. A 80-as és 443-as portot egy fordított proxy kapja, amely a kérésben szereplő domain alapján dönti el, melyik konténerhez továbbítsa, és intézi az SSL tanúsítványt is. Ilyen például a webes felülettel kezelhető Nginx Proxy Manager, amelynek beállítását a Nginx Proxy Manager telepítése Dockerrel cikk mutatja be.

Ha a proxy is Dockerben fut, a portot közzé sem kell tenni: elég, ha a webes konténer egy közös hálózaton van a proxyval. Hozd létre egyszer a közös hálózatot:

docker network create proxy

Majd a compose.yaml-ban a WordPressnél hagyd el a ports részt, és tedd fel a közös hálózatra is:

  wordpress:
    # ... a többi beállítás változatlan, a ports rész nélkül
    networks:
      - backend
      - proxy

networks:
  backend:
  proxy:
    external: true

Az external: true azt jelenti, hogy a hálózatot nem ez a projekt hozza létre és nem is törli a down. Az adatbázis maradjon csak a backend hálózaton: a teszten a proxy konténerből a wordpress és a wordpress-wordpress-1 név feloldható volt, a db viszont nem, így az adatbázis a proxy felől sem érhető el.

A Docker és a tűzfal

Ha a portot cím nélkül adod meg ("8080:80"), a Docker minden hálózati címen megnyitja, a saját tűzfalszabályaival. Ezek megelőzik az ufw és a firewalld szabályait, így a port kívülről akkor is elérhető lehet, ha a tűzfalon nem engedélyezted (az SQL Serverről szóló cikkünkben firewalld-vel ki is próbáltuk: SQL Server Express Linuxon). Ezért minden olyan portot, amelyet csak a szerveren belül vagy egy proxy használ, a 127.0.0.1: előtaggal köss. Hogy éppen mi hallgat kívülről elérhető címen, azt a Nyitott portok listázása: ss és lsof cikk szerint ellenőrizheted; a tűzfal beállításáról a Hogyan állítsak be tűzfalat a VPS-emen? cikk szól.

Mentés

A Compose nem készít mentést; a kötetek tartalmát neked kell elmentened. Két módszer:

Adatbázis-mentés futás közben

Adatbázisnál a legbiztosabb a saját mentőeszköze, amely a futó szerverről is konzisztens mentést ad:

cd ~/wordpress
set -a; . ./.env; set +a
docker compose exec -T db mariadb-dump -u root -p"$DB_ROOT_PASSWORD" --single-transaction wordpress > wordpress-$(date +%F).sql

Visszaállítás egy üres adatbázisba:

docker compose exec -T db mariadb -u root -p"$DB_ROOT_PASSWORD" wordpress < wordpress-2026-11-08.sql

Kötet mentése tar-ral, segédkonténerrel

A fájlokat tartalmazó köteteket egy rövid életű segédkonténer csomagolja be, amely a kötetet és az aktuális mappát is megkapja. Előtte állítsd le azt a szolgáltatást, amely a kötetbe ír, hogy a mentés közben ne változzanak a fájlok:

cd ~/wordpress
docker compose stop wordpress
docker run --rm -v wordpress_wp_data:/data:ro -v "$PWD":/backup alpine \
  tar czf /backup/wp_data-$(date +%F).tar.gz -C /data .
docker compose start wordpress

A kötet teljes neve a projektnév és a kötet neve aláhúzással (wordpress_wp_data); a docker volume ls kiírja. A mentési fájl tulajdonosa a root lesz, mert a segédkonténer rootként fut.

Visszaállítás: töröld a régi kötetet, hozd létre újra a Compose-zal (a create a konténereket és a köteteket elindítás nélkül hozza létre), csomagold ki bele a mentést, majd indítsd el a projektet:

docker compose down
docker volume rm wordpress_wp_data
docker compose create
docker run --rm -v wordpress_wp_data:/data -v "$PWD":/backup:ro alpine \
  tar xzf /backup/wp_data-2026-11-08.tar.gz -C /data
docker compose up -d

A teszten a visszaállított WordPress-fájlok a tulajdonosukkal (www-data) együtt kerültek vissza, és az oldal a visszaállítás után azonnal válaszolt.

A mentés mellé tedd el a compose.yaml-t és a .env fájlt is, és a mentéseket rendszeresen másold egy másik gépre (lásd: Fájlok másolása szerverek között). Ütemezett futtatáshoz a Crontab szintaxis és ütemezett feladatok Linuxon cikk ad segítséget.

Gyakori hibák

  • „no configuration file provided: not found”: nem a projekt mappájában adtad ki a parancsot, vagy a fájl neve eltér a megszokottaktól. Lépj a mappába, vagy add meg a fájlt a -f kapcsolóval.
  • „required variable … is missing a value”: a .env fájl hiányzik, más mappában van, vagy hiányzik belőle a változó. A .env-nek a compose.yaml mellett kell lennie.
  • „port is already allocated” vagy „address already in use”: a szerveren már más használja a portot (egy másik konténer vagy egy natív webszerver). Válassz másik portot, vagy állítsd le a másik szolgáltatást.
  • „permission denied while trying to connect to the docker API”: a felhasználó nem tagja a docker csoportnak, vagy a csoporthoz adás óta nem jelentkezett be újra. Használd a sudo-t, vagy jelentkezz ki és be.
  • A konténer újra és újra elindul (Restarting állapot a ps-ben): nézd meg a naplóját (docker compose logs --tail 50 <szolgáltatás>); többnyire hiányzó változó, rossz jelszó vagy jogosultsági hiba áll a háttérben. A rendszerszintű naplózásról a Naplófájlok olvasása: journalctl és /var/log cikk szól.

Kapcsolódó cikkek

Vissza: Linux leírások (76)