Docker a CI/CD-ben: egységes szállítószalag a fejlesztéstől az élesig
A konténerek a modern CI/CD pipeline építőkövei: buildelj egyszer, futtasd mindenhol. Megnézzük, hogyan illeszkedik a Docker egy automatizált szállítószalagba.
Ha valaha is azt mondtad (vagy hallottad), hogy “nálam működik”, akkor pontosan tudod, miért született a Docker és a CI/CD ötvözete. A konténerek pont azt a problémát oldják meg, amitől a folyamatos integráció és szállítás igazán hatékony lesz: egy egyszer megépített, megváltoztathatatlan artefaktumot adsz tovább a fejlesztéstől egészen az éles környezetig. Ebben a cikkben végigvesszük, hogyan illeszkedik a Docker egy automatizált szállítószalagba, és építünk egy valódi, működő GitHub Actions pipeline-t is.
Mi az a CI/CD röviden?
A CI/CD két, egymásra épülő gyakorlat rövidítése:
- CI (Continuous Integration) – folyamatos integráció. Minden commit után automatikusan lefuttatod a buildet és a teszteket, így a hibák azonnal kiderülnek, nem hetekkel később.
- CD (Continuous Delivery / Deployment) – folyamatos szállítás vagy telepítés. A sikeresen tesztelt változás automatikusan eljut egy registrybe, majd onnan a staging vagy az éles környezetbe.
A lényeg az automatizálás: az ember helyett a gép végzi a monoton, hibára hajlamos lépéseket, te pedig a kódra koncentrálhatsz.
Miért illik a Docker a CI/CD-be?
A hagyományos pipeline-ok egyik örök fájdalma, hogy a fejlesztői gép, a CI runner és a szerver környezete sosem egyezik pontosan. Más a Node verzió, hiányzik egy rendszerkönyvtár, eltér a locale. A Docker ezt felszámolja egyetlen alapelvvel:
💡 Tipp: Build once, run anywhere. Egyszer megépíted az image-et, és pontosan ugyanaz a bájtsorozat fut a tesztkörnyezetben, a stagingen és az éles szerveren is. Nem buildelsz újra minden lépésben.
Az image egy megváltoztathatatlan (immutable) artefaktum. Amit leteszteltél, az fog éles üzemben futni — nincs “csak gyorsan átfordítom a szerveren” típusú meglepetés. Ha még nem vagy tisztában az alapokkal, érdemes elolvasni, Mi az a Docker? és átfutni a Hogyan működik oldalt.
Egy tipikus konténeres pipeline
A legtöbb Docker-alapú szállítószalag négy nagy szakaszra bomlik:
- Build – a forráskódból
docker buildparanccsal image készül. - Test – a tesztek magában a frissen épített konténerben futnak, így pontosan azt teszteled, ami élesbe kerül.
- Push – a zöld build image-ét feltöltöd egy registrybe (Docker Hub, GitHub Container Registry, GitLab Registry stb.).
- Deploy – a célkörnyezet lehúzza és elindítja az új image-et.
A kulcs a második lépés: nem a runner csupasz gépén tesztelsz, hanem a konténerben. Így a tesztkörnyezet bitre azonos a produkcióssal.
Konkrét példa: GitHub Actions pipeline
Nézzünk egy valódi, copy-paste-elhető workflow-t, amely megépíti és feltölti az image-et a GitHub Container Registrybe (ghcr.io). Hozd létre a .github/workflows/docker.yml fájlt:
name: Build and push image
on:
push:
branches: [main]
tags: ["v*"]
env:
IMAGE_NAME: ghcr.io/${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=,format=short
type=ref,event=branch
type=semver,pattern={{version}}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
Ez a workflow minden main-re érkező push és minden v* tag esetén lefut, bejelentkezik a registrybe, kiszámolja a megfelelő tageket, majd megépíti és feltölti az image-et.
Tesztelés a buildelt konténerben
A build előtt érdemes egy külön lépésben lefuttatni a teszteket. Ha multi-stage Dockerfile-od van egy test célállomással, ezt akár így is megteheted:
- name: Run tests in container
run: |
docker build --target test -t app:test .
docker run --rm app:test
Így a teszt pontosan abban a környezetben fut, amit utána szállítasz.
Image tagging: a git SHA a barátod
A tagelési stratégia fontosabb, mint elsőre tűnik. A leggyakoribb hibákról külön is olvashatsz a 10 gyakori Docker hiba cikkben, de a CI/CD szempontjából a legfontosabb szabály:
⚠️ Figyelem: Soha ne támaszkodj a
latesttagre a pipeline-odban! Alatestváltozik, nem reprodukálható, és lehetetlen visszakövetni, melyik kód fut éppen. Mindig használj egyedi, megváltoztathatatlan tageket.
A bevett gyakorlat, hogy minden image-et a hozzá tartozó git commit SHA-jával tagelsz (a fenti workflow type=sha sora pontosan ezt csinálja). Így bármikor egyértelmű, melyik forráskódból készült egy adott image.
| Tag típus | Példa | Mire jó |
|---|---|---|
| Git SHA | a1b2c3d | Pontos, reprodukálható azonosítás |
| Semver | 1.4.2 | Emberek számára olvasható kiadás |
| Branch | main | Mozgó mutató a legutóbbi állapotra |
latest | latest | Kényelmes, de ne a deployhoz |
A deployban a SHA-s vagy a semver tagre hivatkozz, a main/latest legfeljebb kényelmi mutató maradjon.
Build cache: gyorsabb pipeline-ok
A CI runner minden futáskor tiszta lappal indul, így alapból minden réteget újraépítene. A fenti példában a cache-from/cache-to sorok a GitHub Actions cache-ét (type=gha) használják, így a változatlan rétegek a következő futásnál a cache-ből jönnek.
A cache hatékonysága azon múlik, mennyire jól van rendezve a Dockerfile-od. Az alapszabály: a ritkán változó dolgok (függőségek telepítése) kerüljenek előre, a gyakran változó forráskód hátra. Erről részletesen is írunk a Dockerfile írása lépésről lépésre cikkben — ott látható az a minta is, amikor a package.json-t a forrás előtt másolod be, hogy a függőség-réteg cache-elhető maradjon.
# A függőségek réteg ritkán változik -> cache-elhető
COPY package*.json ./
RUN npm ci
# A forrás gyakran változik -> ez a réteg invalidálódik csak
COPY . .
Összefoglalás
A Docker és a CI/CD természetes partnerek: a konténer az a megváltoztathatatlan artefaktum, amit egyszer megépítesz, leteszteled, majd változatlanul szállítasz tovább. Egy jól felépített pipeline a forrásból image-et épít, a konténerben tesztel, SHA-val tagelve registrybe tölt, majd onnan deployol — mindezt automatikusan, a latest tag csapdáját elkerülve és a build cache-t kihasználva. Ettől lesz a “nálam működik” helyett “mindenhol ugyanúgy működik”.
Ha most kezded a Docker-utadat, nézd meg a Kezdő lépések útmutatót, vagy ha kíváncsi vagy, miért érdemes egyáltalán belevágni, olvasd el a Miért a Docker? oldalt. Aztán fogd a saját projekted, írj rá egy Dockerfile-t, és kösd be egy pipeline-ba — meglátod, mennyivel nyugodtabb lesz a deploy.