Docker in CI/CD Pipelines
Was dieser Artikel über Docker in CI/CD behandelt
- Was CI/CD mit Docker leistet.
- GitHub Actions und GitLab CI für Docker-Builds.
- Multi-Stage-Builds und Caching.
- Testing, Scanning und Deployment in Pipelines.
- Tipps für lokale und selbstgehostete Runner.
Einleitung: Docker in CI/CD Pipelines
Continuous Integration und Continuous Delivery, kurz CI/CD, automatisieren das Bauen, Testen und Verteilen von Software. Docker eignet sich hervorragend dafür, weil Builds reproduzierbar sind und die gleiche Umgebung für Tests, Staging und Produktion genutzt wird. Wer Docker-Images automatisch bei jedem Commit bauen, testen und in eine Registry pushen lässt, spart Zeit und reduziert Fehler.
Dieser Artikel zeigt, wie man Docker in GitHub Actions und GitLab CI integriert und worauf beim selbstgehosteten Betrieb zu achten ist.
Wichtige Begriffe
- CI: Continuous Integration, regelmässiges Zusammenführen und Testen.
- CD: Continuous Delivery oder Deployment, automatische Auslieferung.
- Pipeline: Ablauf aus mehreren Schritten.
- Runner: Rechner, der die Pipeline ausführt.
- Multi-Stage-Build: Dockerfile mit mehreren Bauabschnitten.
- Layer Caching: Zwischenspeichern von Docker-Layern.
- Registry: Speicherort für Images.
- Artifact: Zwischenprodukt einer Pipeline.
Warum Docker in CI/CD?
- Gleiche Umgebung für Build, Test und Produktion.
- Reproduzierbare Builds.
- Einfache Skalierung über Runner.
- Schnelle Rollbacks durch versionierte Images.
- Isolation von Abhängigkeiten.
- Einfache Bereitstellung in verschiedenen Umgebungen.
GitHub Actions Beispiel
name: Docker Build and Push
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
GitLab CI Beispiel
stages:
- build
- test
- deploy
variables:
IMAGE_NAME: $CI_REGISTRY_IMAGE:latest
build_image:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker build -t $IMAGE_NAME .
- docker push $IMAGE_NAME
only:
- main
test_image:
stage: test
image: $IMAGE_NAME
script:
- pytest
deploy_image:
stage: deploy
image: docker:24
script:
- docker pull $IMAGE_NAME
- docker run -d -p 8080:8080 $IMAGE_NAME
Multi-Stage-Builds
Multi-Stage-Builds reduzieren Imagegrösse und verbessern Sicherheit:
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY . .
CMD ["python", "main.py"]
Tests in Docker
- name: Test in Docker
run: |
docker build -t myapp:test .
docker run --rm myapp:test pytest
Image-Scanning
Sicherheitslücken im Image finden:
- name: Scan image
uses: anchore/scan-action@v3
with:
image: "ghcr.io/user/repo:latest"
Caching
Caching beschleunigt Builds erheblich:
cache-fromundcache-toin GitHub Actions.- Docker Layer Caching mit BuildKit.
- Registry als Cache-Ziel.
- Lokale Cache-Verzeichnisse auf selbstgehosteten Runnern.
Selbstgehostete Runner
Für grössere Workloads oder private Infrastruktur bieten sich selbstgehostete Runner:
# GitHub Actions Runner herunterladen und konfigurieren
./config.sh --url https://github.com/USER/REPO --token TOKEN
./run.sh
Auf dem Runner muss Docker installiert sein. Für GPU-Builds braucht es das entsprechende Container Toolkit.
Deployment
Images können nach dem Build automatisch deployt werden:
- Auf einen Docker-Host via SSH.
- In ein Kubernetes-Cluster.
- Über Docker Swarm.
- Auf einen eigenen Server mit
docker compose up -d.
Tipps
- Keine Secrets in Images speichern.
- Tags aus Git-Hash oder Datum generieren.
- Failing Tests sofort abbrechen.
- Layer Caching aktivieren.
- Images regelmässig aktualisieren.
- Privileged Runner vermeiden, wenn möglich.
- Build-Kontext klein halten.
Typische Stolpersteine
- Grosse Images: Keine Multi-Stage-Builds.
- Fehlende Registry-Anmeldung: Push schlägt fehl.
- Langsame Builds: Kein Caching.
- Secrets in Umgebungsvariablen: Werden in Logs preisgegeben.
- Runner ohne Docker: Pipeline bricht ab.
- Falsche Tags: Überschreiben oder verlorene Images.
- Zu grosse Build-Kontexte: .dockerignore nutzen.
Weiterführende Links und Infos
- BotServ.de Docker Registry
- BotServ.de Docker Sicherheit
- BotServ.de Docker Backup
- BotServ.de Kubernetes
FAQ: Docker in CI/CD
Brauche ich GitHub Actions oder GitLab? Beide funktionieren. Auch selbstgehostete Lösungen wie Jenkins oder Woodpecker sind möglich.
Soll ich Images bei jedem Commit bauen?
Für main oder getaggte Releases ja, für jeden Zwischencommit optional.
Wie schnell werden Builds? Mit Caching meist Minuten statt jedes Mal mehrere Minuten.
Kann ich GPU-Tests in CI/CD laufen lassen? Nur mit Runnern, die über eine GPU verfügen.
Sind selbstgehostete Runner sicher? Wenn sie isoliert und gepflegt werden. Nie in öffentlichen Repos ohne Absicherung nutzen.
Quellen und weiterführende Literatur
- GitHub Actions: https://docs.github.com/en/actions
- GitLab CI: https://docs.gitlab.com/ee/ci/
- Docker BuildKit Caching: https://docs.docker.com/build/cache/
- Docker Build-Push Action: https://github.com/docker/build-push-action
Zusammenfassung: Docker in CI/CD Pipelines
Docker passt hervorragend in CI/CD-Workflows. GitHub Actions und GitLab CI ermöglichen automatisierte Builds, Tests und Deployments von Container-Images. Multi-Stage-Builds, Caching und regelmässiges Scanning verbessern Geschwindigkeit und Sicherheit. Selbstgehostete Runner bieten Flexibilität für spezielle Hardware wie GPUs. Wer Secrets schützt, Layer Caching nutzt und saubere Tags verwendet, bekommt einen robusten Container-Workflow.


