A modern szoftverfejlesztés egyik alapköve a konténerizáció, amely lehetővé teszi alkalmazásaink és azok függőségeinek egységes, izolált környezetben történő futtatását. A Docker ebben az ökoszisztémában vezető szerepet tölt be, és bár egyetlen konténer kezelése viszonylag egyszerű, a komplex, több szolgáltatásból álló alkalmazások esetében hamar szükségessé válik egy magasabb szintű orkesztrációs eszköz. Itt lép színre a Docker Compose, amely leegyszerűsíti a többkonténeres Docker alkalmazások definiálását és futtatását egyetlen YAML fájl segítségével. Azonban még a Compose is merevvé válhat, ha a konfigurációs értékeket közvetlenül beleírjuk a docker-compose.yml
fájlba. Ezen a ponton válnak nélkülözhetetlenné a Docker Compose változók, amelyek biztosítják a szükséges rugalmasságot, újrafelhasználhatóságot és biztonságot.
Miért van szükség rugalmas konfigurációra?
Képzeljünk el egy webalkalmazást, amely egy webkiszolgálóból, egy adatbázisból és egy cache rétegből áll. Ez az alkalmazás valószínűleg különböző beállításokat igényel fejlesztés, tesztelés (staging) és éles (production) környezetben:
- Fejlesztés (Development): Könnyen debugolható, helyi adatbázis, esetleg lassabb erőforrásokkal.
- Tesztelés (Staging): Produkcióhoz hasonló környezet, tesztadatokkal, valósághűbb erőforrásokkal.
- Éles (Production): Magas rendelkezésre állás, biztonságos jelszavak, optimalizált erőforrás-kihasználás, publikus portok.
Ha minden környezethez külön docker-compose.yml
fájlt hoznánk létre, az hamar karbantarthatatlanná válna. A kódban lévő hardkódolt értékek (pl. adatbázis jelszavak, API kulcsok) biztonsági kockázatot jelentenek, és megnehezítik az alkalmazás áthelyezését más környezetekbe. A változók használata a megoldás ezekre a problémákra, lehetővé téve, hogy ugyanazt a docker-compose.yml
fájlt használjuk minimális módosításokkal, vagy anélkül is, a különböző környezetekhez.
A Docker Compose változók alapjai: Hogyan működik az interpoláció?
A Docker Compose képes behelyettesíteni (interpolálni) a változókat a docker-compose.yml
fájlban. Ez azt jelenti, hogy a Compose futtatásakor keresi a ${VÁLTOZÓ_NÉV}
formátumú kifejezéseket, és behelyettesíti azok értékét. Ezek az értékek különböző forrásokból származhatnak:
- **Környezeti változók (Environment Variables):** A shell környezetben beállított változók, vagy a
docker compose
parancs előtt definiáltak. - **`.env` fájl (Dotenv file):** Egy speciális fájl, amelyet a Docker Compose automatikusan betölt a futtatás során.
- **`environment` direktíva a szolgáltatáson belül:** Specifikusan egy adott szolgáltatás számára definiált környezeti változók.
- **`env_file` direktíva a szolgáltatáson belül:** Egy fájlból betöltött környezeti változók egy adott szolgáltatáshoz.
1. Környezeti változók használata
Ez a legegyszerűbb módszer. A shellben beállított változók közvetlenül felhasználhatók a docker-compose.yml
fájlban. Ha például a PORT
nevű változót szeretnénk használni:
# docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "${PORT:-80}:80" # Ha a PORT nincs beállítva, alapértelmezésben 80-at használ
# Terminálban
export PORT=8080
docker compose up
# Az Nginx a 8080-as porton fog futni.
# Vagy közvetlenül a parancs elé:
PORT=8080 docker compose up
Ebben a példában láthatjuk a ${PORT:-80}
szintaxist. Ez azt jelenti: „használja a PORT
változó értékét, de ha az nincs definiálva, akkor használja a 80
-at alapértelmezettként”. Ez a default érték megadása egy rendkívül hasznos funkció a robusztus konfigurációkhoz.
2. A `.env` fájl ereje
A .env
fájl a leggyakoribb és legkényelmesebb módszer a változók kezelésére a Docker Compose-ban. Amikor a docker compose
parancsot futtatjuk egy könyvtárban, a Compose automatikusan keres egy .env
nevű fájlt ugyanabban a könyvtárban (vagy a szülőkönyvtárakban), és betölti az abban definiált változókat. A .env
fájl formátuma egyszerű:
# .env fájl
DATABASE_USER=myuser
DATABASE_PASSWORD=mysecretpassword
APP_PORT=8000
ENVIRONMENT=development
Ezután a docker-compose.yml
fájlban hivatkozhatunk ezekre a változókra:
# docker-compose.yml
version: '3.8'
services:
webapp:
image: myapp:latest
environment:
DB_USER: ${DATABASE_USER}
DB_PASS: ${DATABASE_PASSWORD}
APP_ENV: ${ENVIRONMENT}
ports:
- "${APP_PORT}:80"
db:
image: postgres:13
environment:
POSTGRES_USER: ${DATABASE_USER}
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
A .env
fájl nagy előnye, hogy központi helyen tárolhatjuk az összes konfigurációs változót, és nem kell exportálnunk őket minden alkalommal. Fontos megjegyezni, hogy a .env
fájlba soha ne tegyünk érzékeny adatokat, amelyeket nem szeretnénk verziókövetés alá vonni! Mindig adjuk hozzá a .gitignore
fájlhoz:
# .gitignore
.env
Éles környezetben (production) a .env
fájl helyett inkább a környezeti változókat vagy a titkosítási (secrets management) megoldásokat érdemes használni.
3. `environment` direktíva szolgáltatáson belül
Ez a direktíva lehetővé teszi, hogy közvetlenül a docker-compose.yml
fájlban, egy adott szolgáltatáshoz definiáljunk környezeti változókat. Ezek a változók csak az adott szolgáltatás konténerében lesznek elérhetők. Itt is használhatunk interpolációt:
# docker-compose.yml
version: '3.8'
services:
web:
image: myapp:latest
environment:
APP_NAME: MyAwesomeApp
DB_HOST: db
API_KEY: ${API_KEY_FROM_ENV_OR_DOTENV} # Itt is lehet interpolálni
Fontos: az itt definiált változók felülírják a globális környezeti változókat, ha azonos nevük van.
4. `env_file` direktíva
Az env_file
direktíva lehetővé teszi, hogy egy külső fájlból töltsünk be környezeti változókat egy adott szolgáltatásba. Ez különösen akkor hasznos, ha egy szolgáltatásnak sok specifikus változóra van szüksége, vagy ha különböző fájlokat szeretnénk használni az érzékeny adatokhoz a kevésbé érzékenyekhez képest.
# docker-compose.yml
version: '3.8'
services:
worker:
image: myworker:latest
env_file:
- ./config/worker_variables.env
- ./config/secrets.env
# ./config/worker_variables.env
WORKER_THREADS=4
QUEUE_NAME=processing_queue
# ./config/secrets.env (ezt természetesen nem commiteljük!)
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=myverysecretkey
A env_file
és a .env
fájlok közötti kulcsfontosságú különbség, hogy a .env
fájlt a Compose automatikusan betölti az összes szolgáltatáshoz (és magához a Compose folyamathoz is), míg az env_file
csak az adott szolgáltatás konténerébe tölti be a változókat.
Fejlett interpolációs szintaxis
A Docker Compose további finomításokat is kínál az interpolációhoz:
${VARIABLE}
: A változó értékét használja. Ha nincs beállítva, hibát dob.${VARIABLE:-default_value}
: A változó értékét használja, de ha az nincs beállítva vagy üres, akkor azdefault_value
-t.${VARIABLE-default_value}
: A változó értékét használja, de ha az nincs beállítva, akkor azdefault_value
-t (az üres stringet nem tekinti alapértelmezettnek).${VARIABLE:?error_message}
: A változó értékét használja, de ha az nincs beállítva vagy üres, hibát dob azerror_message
-vel.${VARIABLE?error_message}
: A változó értékét használja, de ha az nincs beállítva, hibát dob azerror_message
-vel.
Ezek a kiegészítések rendkívül hasznosak a robusztusabb és hibatűrőbb konfigurációk létrehozásához. Például, ha egy adatbázis jelszó hiánya kritikus, használhatjuk a ${DB_PASSWORD:?Adatbázis jelszó szükséges!}
formátumot.
Gyakorlati használati esetek és példák
1. Különböző környezetek kezelése több `docker-compose.yml` fájllal
A Docker Compose igazi ereje abban rejlik, hogy több konfigurációs fájlt is összefűzhetünk. Ez lehetővé teszi, hogy legyen egy alap konfigurációnk, majd erre ráépítsünk környezet-specifikus felülírásokat.
docker-compose.yml
(Alap konfiguráció):
# docker-compose.yml
version: '3.8'
services:
web:
image: myapp:${IMAGE_TAG:-latest}
build: .
ports:
- "${PORT:-8000}:80"
environment:
APP_ENV: ${APP_ENV:-development}
DATABASE_URL: ${DATABASE_URL:-postgres://user:password@db:5432/myapp_dev}
db:
image: postgres:13
environment:
POSTGRES_DB: myapp_${APP_ENV:-development}
POSTGRES_USER: user
POSTGRES_PASSWORD: password
docker-compose.prod.yml
(Produkciós felülírás):
# docker-compose.prod.yml
version: '3.8'
services:
web:
ports:
- "${PROD_PORT}:80" # Produkcióban más portot használunk
environment:
APP_ENV: production
DATABASE_URL: ${PROD_DATABASE_URL:?Production database URL is required!} # Kötelező változó
deploy: # Skálázás és újraindítási stratégia
replicas: 3
restart_policy:
condition: on-failure
db:
image: postgres:13-alpine # Kisebb image
volumes:
- prod_db_data:/var/lib/postgresql/data # Perzisztens tároló
volumes:
prod_db_data:
Futtatás fejlesztési környezetben:
docker compose up
Futtatás produkciós környezetben (feltételezve, hogy a PROD_PORT
és PROD_DATABASE_URL
változók be vannak állítva a környezetben vagy egy `.env` fájlban):
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Ez a megközelítés fantasztikus rugalmas konfigurációt biztosít anélkül, hogy duplikálnánk a kódot.
2. Adatbázis kapcsolódási adatok kezelése
Az adatbázisok felhasználóneve és jelszava érzékeny adat. Ezeket soha nem szabad közvetlenül a docker-compose.yml
fájlba írni. Helyette használjunk környezeti változókat vagy .env
fájlt.
.env
(fejlesztéshez):
DB_USER=devuser
DB_PASSWORD=devpass
docker-compose.yml
:
version: '3.8'
services:
app:
image: myapp:latest
environment:
DB_USERNAME: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
db:
image: postgres:13
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
Éles környezetben ezeket a változókat a környezetből (pl. CI/CD pipeline, titkosítási szolgáltatások) kaphatja meg a Docker Compose, nem pedig egy .env
fájlból.
3. Képverziók dinamikus kezelése
Gyakori eset, hogy egy szolgáltatás Docker képének verzióját szeretnénk könnyedén módosítani frissítéskor vagy visszaállításkor.
.env
:
NGINX_VERSION=1.23.3
REDIS_VERSION=6.2.7
docker-compose.yml
:
version: '3.8'
services:
webserver:
image: nginx:${NGINX_VERSION}
ports:
- "80:80"
cache:
image: redis:${REDIS_VERSION}
Így egyetlen .env
fájl módosításával frissíthetjük az alkalmazás függőségeit, anélkül, hogy magát a docker-compose.yml
fájlt módosítanánk.
Legjobb gyakorlatok a Docker Compose változók használatához
- Ne commitelj érzékeny adatokat! A jelszavak, API kulcsok és egyéb titkok soha ne kerüljenek verziókövetés alá (Git)! Használj
.gitignore
-t a.env
fájlokhoz, vagy használj külső titkosítási megoldásokat éles környezetben (pl. Docker Secrets, HashiCorp Vault, Kubernetes Secrets). - Használj
.env
fájlokat alapértelmezésekhez. A.env
fájl ideális hely a fejlesztési környezet alapértelmezett konfigurációs értékeinek tárolására. Ez gyors és egyszerű indítást tesz lehetővé a csapat új tagjai számára. - Használj világos és következetes változóneveket. A jól elnevezett változók megkönnyítik a konfiguráció megértését és karbantartását.
- Dokumentáld a változóidat. Különösen nagyobb projektek esetén érdemes egy
.env.example
fájlt biztosítani, amely felsorolja az összes szükséges változót a leírásukkal és egy minta értékkel, vagy részletes dokumentációt mellékelni. - Kombináld a konfigurációs fájlokat a rugalmasságért. Az
-f
(vagy--file
) opcióval többdocker-compose.yml
fájlt is megadhatsz. Ez rendkívül erőteljes a környezet-specifikus konfigurációk kezelésében. - Teszteld a konfigurációkat. Győződj meg róla, hogy az alkalmazásod megfelelően működik minden környezetben a változókkal.
- Kerüld a felesleges interpolációt. Csak akkor használj változókat, ha valóban szükség van a rugalmasságra. A túl sok változó csökkentheti az olvashatóságot.
Összegzés
A Docker Compose változók nem csupán egy kényelmi funkció, hanem alapvető eszközök a rugalmas konfiguráció megvalósításához a konténerizált alkalmazások világában. Segítségükkel elválaszthatjuk az alkalmazás logikáját a környezet-specifikus beállításoktól, növelve a kód újrafelhasználhatóságát, biztonságát és a karbantarthatóságot. Legyen szó fejlesztési, tesztelési vagy éles környezetről, az okosan használt változók egyszerűsítik a munkafolyamatokat és lehetővé teszik a gyorsabb, hibamentesebb telepítéseket.
A .env
fájlok, a shell környezeti változók és a fejlett interpolációs szintaxis elsajátítása kulcsfontosságú ahhoz, hogy a legtöbbet hozd ki a Docker Compose-ból. Ezáltal nemcsak hatékonyabbá válsz a konténerek kezelésében, hanem felkészíted alkalmazásaidat a jövőbeni kihívásokra és a különböző üzemeltetési környezetekre is. Ne feledd: a jól átgondolt konfiguráció az egyik alapköve a sikeres, skálázható és biztonságos szoftverrendszereknek.
Leave a Reply