Private Registry

Von Code Sentinel, Technical Project Manager bei Java Fleet Systems Consulting
Serie: Enterprise CI/CD Mastery | Teil 7 von 12


📍 Wo stehst du in der Serie?

ModulTeilStatusThema
1: Foundations1✅ FertigErste Pipeline
2✅ FertigSecurity Gates (OWASP + Trivy)
3✅ FertigCoverage Gates (JaCoCo)
4✅ FertigQuality Gates (SonarQube)
2: Container5✅ FertigMulti-Stage Builds
6✅ FertigContainer Security (SBOM)
7👉 DU BIST HIERRegistry Integration
3: Deployment8⏳offenBlue-Green Deployments
9⏳ offenCanary & Kubernetes
10⏳offenGitOps & Environments
4: Enterprise11⏳ offenJenkins Enterprise
12⏳ offenMulti-Platform & Finale

🔄 Serie-Rückblick: Der Container-Journey

Teil 6 :
Container Security → SBOM generiert, Distroless Images, Supply Chain abgesichert.

Diese Woche:
Registry-Management → Wo speichern wir unsere Images? Wie taggen wir richtig? Wie bauen wir für verschiedene Architekturen?


⚡ 30-Sekunden-Summary

Du lernst heute:

  • ✅ GitHub Container Registry (GHCR) statt Docker Hub nutzen
  • ✅ Image-Tagging-Strategien die Production nicht killen
  • ✅ Multi-Architecture Builds (AMD64 + ARM64)
  • ✅ Registry-Security & Access-Management
  • ✅ Automated Push in CI/CD Pipeline

Nach diesem Teil kannst du:

  • Private Registry aufsetzen & absichern
  • Images intelligent taggen (nicht nur :latest)
  • Multi-Arch Images für Cloud & Edge bauen
  • Registry in deine Pipeline integrieren

Zeit: ~15-20 Minuten Lesezeit


👋 Hey! Code Sentinel hier

Schön, dass du wieder da bist! Heute ist Private Registry angesagt.😊

Real Talk: Diese Woche wird’s entspannter als die letzten beiden. Nachdem wir Container-Security und SBOM durchgenommen haben, machen wir heute was Praktisches: Wohin mit den Images?

Letzte Woche haben wir Container abgesichert. Das Team hat’s bemerkt:

  • Nova: „Code, du hast diese Woche dreimal gelächelt!“
  • Kofi: „Bro ist in good mood!“
  • Elyndra: „Hat er gerade die 18-Uhr-Regel durchgesetzt? Respect!“

Vielleicht hab ich gemerkt, dass gute Systeme auch einfach sein können. Und dass man auch mal um 18 Uhr gehen darf. 😉

Heute geht’s um Registry-Management. Klingt trocken? Ist es nicht! Denn jeder der schonmal :latest in Production gepusht hat und dann debugging musste, weiß: Tagging ist WICHTIG.

Story aus der Community:

Stefan aus Hamburg schreibt:

„Unser Team hatte 200+ Images in Docker Hub. Alle getaggt mit :latest, :v1, :final, :final-final. Nach 6 Monaten wusste keiner mehr welches Image in Production läuft. Beim Rollback haben wir das falsche Image deployed. Downtime: 4 Stunden. Chef war… not amused.“

Yeah. Das können wir besser. Lass uns loslegen! 🚀


📚 GRUNDLAGEN: Warum überhaupt eine Registry?

Das Problem mit lokalem Docker

# Du entwickelst lokal
docker build -t myapp:latest .

# Alles funktioniert! 🎉
docker run myapp:latest

# Dein Kollege klont das Repo
git clone ...
docker run myapp:latest  # ❌ "Unable to find image"

Warum scheitert’s?

  • Images sind nur lokal auf deinem Rechner
  • Keine zentrale Quelle der Wahrheit
  • Jeder muss selbst bauen (unterschiedliche Versionen möglich!)
  • CI/CD Server haben das Image nicht

Die Lösung: Container Registry

Private Registry

Eine Registry ist wie ein Git-Repo für Docker Images.

# Du pushst dein Image
docker push ghcr.io/username/myapp:1.2.3

# Dein Kollege pullt es
docker pull ghcr.io/username/myapp:1.2.3

# CI/CD Server pullt es
kubectl set image deployment/myapp myapp=ghcr.io/username/myapp:1.2.3

Vorteile:

  • ✅ Zentrale Image-Verwaltung
  • ✅ Versionierung & Historisierung
  • ✅ Access-Control (wer darf was?)
  • ✅ CI/CD Integration
  • ✅ Multi-Arch Support
  • ✅ Image-Scanning & Security

🏪 Registry-Optionen: Was passt zu dir?

1. Docker Hub (Public/Free)

Pro:

  • ✅ Einfach & kostenlos
  • ✅ Große Community
  • ✅ Millionen Public Images

Contra:

  • ❌ Rate-Limits (100 Pulls / 6h ohne Login)
  • ❌ Private Repos limitiert (1 gratis)
  • ❌ Keine Enterprise-Features
  • ❌ Langsam bei größeren Teams

Wann nutzen: Hobby-Projekte, Open Source, Experimente


2. GitHub Container Registry (GHCR) – EMPFOHLEN!

Pro:

  • ✅ Kostenlos für Public & Private Repos
  • ✅ Direkt an GitHub gekoppelt
  • ✅ GitHub Actions Integration perfekt
  • ✅ Fine-grained Access-Control
  • ✅ Schnell & zuverlässig
  • ✅ Multi-Arch Support

Contra:

  • ⚠️ GitHub-Account nötig
  • ⚠️ Storage-Limits (bei Free: 500 MB)

Wann nutzen: 90% aller Projekte! Vor allem wenn du schon GitHub nutzt.

URL-Schema:

ghcr.io/USERNAME/IMAGE:TAG
ghcr.io/ORGANIZATION/IMAGE:TAG

3. GitLab Container Registry

Pro:

  • ✅ Integriert in GitLab
  • ✅ Unbegrenzter Storage (self-hosted)
  • ✅ GitLab CI Integration

Contra:

  • ⚠️ Nur sinnvoll wenn du GitLab nutzt

4. AWS ECR / Azure ACR / GCP Artifact Registry

Pro:

  • ✅ Enterprise-Grade
  • ✅ Integration mit Cloud-Services
  • ✅ Unlimited Storage (bezahlt)

Contra:

  • ❌ Kostet Geld
  • ❌ Cloud-Vendor Lock-in
  • ❌ Komplexere Authentifizierung

Wann nutzen: Production bei Cloud-Native Apps, große Unternehmen


5. Self-Hosted Registry (Harbor, GitLab Registry)

Pro:

  • ✅ Volle Kontrolle
  • ✅ On-Premise
  • ✅ Keine Limits

Contra:

  • ❌ Du musst es selbst betreiben
  • ❌ Wartung, Updates, Backups
  • ❌ Security ist deine Verantwortung

Wann nutzen: Wenn du musst (Compliance, Air-Gap), nicht weil du willst.


🎯 Unsere Entscheidung: GitHub Container Registry

Warum GHCR?

  1. Du nutzt schon GitHub → Keine neue Platform
  2. Kostenlos → Auch für Private Repos
  3. GitHub Actions → Perfekte Integration
  4. Einfach → Wenig Setup
  5. Zuverlässig → Microsoft-Infrastructure

Real Talk: Ich empfehle GHCR für 90% aller Projekte. Es ist der sweet spot zwischen „einfach“ und „production-ready“.


🏗️ Teil 1: GHCR Setup – GitHub Container Registry nutzen

Step 1: Personal Access Token (PAT) erstellen

GitHub braucht einen Token um Images zu pushen.

1. GitHub Settings öffnen:

GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)

2. Neuen Token erstellen:

  • Note: „GHCR Push Token“
  • Expiration: 90 days (oder länger für Automation)
  • Scopes:
    • write:packages (Images pushen)
    • read:packages (Images pullen)
    • delete:packages (Images löschen)

3. Token kopieren (nur einmal sichtbar!)

# Token als Environment-Variable setzen
export CR_PAT=ghp_xxxxxxxxxxxxxxxxxxxx

Step 2: Bei GHCR anmelden

# Mit Token anmelden
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin

# Output:
# Login Succeeded

USERNAME = Dein GitHub-Username (z.B. stefanhh)


Step 3: Image taggen & pushen

# Lokales Image bauen
docker build -t myapp:latest .

# Für GHCR taggen
docker tag myapp:latest ghcr.io/stefanhh/myapp:1.0.0

# Nach GHCR pushen
docker push ghcr.io/stefanhh/myapp:1.0.0

# Output:
# The push refers to repository [ghcr.io/stefanhh/myapp]
# 1.0.0: digest: sha256:abc123... size: 2418

Step 4: Image-Visibility setzen

Standardmäßig sind Images PRIVATE.

Public machen:

  1. GitHub → Packages → Dein Image anklicken
  2. Package Settings → Change visibility → Public

Access-Control:

  • Public: Jeder kann pullen
  • Private: Nur du + ausgewählte User/Teams
  • Fine-grained: Per Repo/Team/User konfigurierbar

Step 5: Image pullen (testen)

# Public Image (kein Login nötig)
docker pull ghcr.io/stefanhh/myapp:1.0.0

# Private Image (Login erforderlich)
echo $CR_PAT | docker login ghcr.io -u stefanhh --password-stdin
docker pull ghcr.io/stefanhh/myapp:1.0.0

Funktioniert? Dann hast du’s geschafft! 🎉


🏷️ Teil 2: Image-Tagging-Strategien

Das :latest Problem

Häufiger Fehler:

docker build -t myapp:latest .
docker push ghcr.io/stefanhh/myapp:latest

Warum ist das schlecht?

  1. Keine Versionierung → Welches Image ist in Production?
  2. Schwieriger Rollback → Auf welche Version zurück?
  3. Cache-Probleme → Kubernetes pullt :latest nicht automatisch neu
  4. Debugging-Nightmare → „Hat bei mir lokal funktioniert!“

Stefan’s Horror-Story (von oben):

200 Images, alle :latest. Kein Mensch wusste mehr was was ist.


Tagging-Strategie: Semantic Versioning

Best Practice: SemVer + Git SHA

# Schema
<registry>/<namespace>/<image>:<version>-<git-sha>

# Beispiel
ghcr.io/stefanhh/myapp:1.2.3-abc123f

Vorteile:

  • Version → Semantic Versioning (1.2.3)
  • Git SHA → Exakte Zuordnung zum Code
  • Rollback → Einfach auf alte Version wechseln
  • Debugging → Sofort klar welcher Code

Multi-Tag-Strategy

Push mehrere Tags gleichzeitig:

VERSION=1.2.3
GIT_SHA=$(git rev-parse --short HEAD)

# Image bauen
docker build -t myapp .

# Mehrere Tags erstellen
docker tag myapp ghcr.io/stefanhh/myapp:${VERSION}
docker tag myapp ghcr.io/stefanhh/myapp:${VERSION}-${GIT_SHA}
docker tag myapp ghcr.io/stefanhh/myapp:latest

# Alle pushen
docker push ghcr.io/stefanhh/myapp:${VERSION}
docker push ghcr.io/stefanhh/myapp:${VERSION}-${GIT_SHA}
docker push ghcr.io/stefanhh/myapp:latest

Resultat:

  • 1.2.3 → Stabile Version
  • 1.2.3-abc123f → Exakt diese Version
  • latest → Für lokale Entwicklung

In Production nutzt du: 1.2.3 oder 1.2.3-abc123f, NIE latest!


Branch-basierte Tags

Für verschiedene Environments:

# Development-Branch
docker tag myapp ghcr.io/stefanhh/myapp:dev

# Staging-Branch
docker tag myapp ghcr.io/stefanhh/myapp:staging

# Production (Main-Branch)
docker tag myapp ghcr.io/stefanhh/myapp:1.2.3

Deployment-Workflow:

dev-branch    → :dev → Dev-Environment
staging-branch → :staging → Staging-Environment
main-branch   → :1.2.3 → Production

🏗️ Teil 3: GitHub Actions Integration

Automatisches Pushen bei jedem Commit

.github/workflows/build-and-push.yml:

name: Build and Push to GHCR

on:
  push:
    branches: [ main, develop ]
    tags: [ 'v*.*.*' ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    
    permissions:
      contents: read
      packages: write
    
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Extract Metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix={{branch}}-
      
      - name: Build and Push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Was passiert hier?

  1. Trigger: Push auf main/develop oder Git-Tag
  2. Login: Automatisch mit GITHUB_TOKEN
  3. Metadata: Automatisches Tag-Generierung
  4. Build: Mit Buildx & Caching
  5. Push: Zu GHCR

Automatische Tags:

  • mainghcr.io/user/repo:main
  • developghcr.io/user/repo:develop
  • v1.2.3ghcr.io/user/repo:1.2.3 + 1.2 + 1
  • Commit → ghcr.io/user/repo:main-abc123f

🌍 Teil 4: Multi-Architecture Builds

Warum Multi-Arch?

Szenario:

  • Entwicklung auf M1 Mac (ARM64)
  • Production auf AWS EC2 (AMD64)
  • Edge-Devices auf Raspberry Pi (ARM64)

Problem: Ein Image läuft nicht überall!

# Auf M1 gebaut
docker build -t myapp .

# Auf Intel-Server deployed
docker run myapp  # ❌ "exec format error"

Lösung: Multi-Platform Builds

Mit Docker Buildx:

# Buildx-Builder erstellen
docker buildx create --name multiarch --use

# Multi-Arch Build
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t ghcr.io/stefanhh/myapp:1.0.0 \
  --push \
  .

Resultat: Ein Tag, mehrere Architekturen!

# Docker pullt automatisch die richtige Architektur
docker pull ghcr.io/stefanhh/myapp:1.0.0

# Auf AMD64 → AMD64-Image
# Auf ARM64 → ARM64-Image

GitHub Actions mit Multi-Arch

Erweitere die Pipeline:

- name: Build and Push Multi-Arch
  uses: docker/build-push-action@v5
  with:
    context: .
    platforms: linux/amd64,linux/arm64
    push: true
    tags: ${{ steps.meta.outputs.tags }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

Build-Zeit: ~2x länger (beide Architekturen), aber nur einmal notwendig!


🔒 Teil 5: Registry-Security

1. Token-Security

❌ Niemals im Code:

# BAD!
docker login -u user -p ghp_xxxxxxxxxxxx

✅ Environment-Variables:

# GOOD!
echo $CR_PAT | docker login ghcr.io -u user --password-stdin

✅ GitHub Actions:

# Nutze GITHUB_TOKEN (automatisch verfügbar)
password: ${{ secrets.GITHUB_TOKEN }}

2. Access-Control

GHCR Permissions:

permissions:
  contents: read      # Code lesen
  packages: write     # Images pushen

Package-Level:

  • Read: Wer darf Images pullen?
  • Write: Wer darf Images pushen?
  • Admin: Wer darf Settings ändern?

Best Practice:

  • Production-Images → Private + Read-only für Teams
  • Development-Images → Private + Write für Entwickler
  • Public-Images → Nur nach Review

3. Image-Scanning vor Push

Trivy in Pipeline:

- name: Scan Image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
    format: 'sarif'
    output: 'trivy-results.sarif'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'  # Fail bei CRITICAL/HIGH

- name: Upload Scan Results
  uses: github/codeql-action/upload-sarif@v2
  with:
    sarif_file: 'trivy-results.sarif'

Flow:

  1. Build Image
  2. Scan mit Trivy
  3. ❌ CRITICAL/HIGH → Build failed
  4. ✅ Clean → Push zu GHCR

4. Image-Signing (Optional)

Cosign für vertrauenswürdige Images:

# Image signieren
cosign sign ghcr.io/stefanhh/myapp:1.0.0

# Signatur verifizieren
cosign verify ghcr.io/stefanhh/myapp:1.0.0

Wann nutzen: Enterprise, Compliance, Supply-Chain-Security


🗂️ Teil 6: Registry-Management Best Practices

1. Image-Cleanup

Problem: Alte Images sammeln sich an → Storage voll!

Lösung: Lifecycle-Policy

GitHub Actions Cleanup:

name: Cleanup Old Images

on:
  schedule:
    - cron: '0 2 * * 0'  # Jeden Sonntag 2 Uhr

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: Delete old images
        uses: actions/delete-package-versions@v4
        with:
          package-name: 'myapp'
          package-type: 'container'
          min-versions-to-keep: 10
          delete-only-untagged-versions: true

Policy:

  • Behalte letzten 10 Versionen
  • Lösche nur untagged Images
  • Automatisch jede Woche

2. Tag-Hygiene

Regeln:

  • ✅ Production → Semantic Version (1.2.3)
  • ✅ Staging → Branch-Tag (staging)
  • ✅ Development → Branch + SHA (dev-abc123f)
  • NIEMALS :latest in Production
  • NIEMALS :final, :final-v2 (Stefan’s Alptraum!)

3. Monitoring & Alerts

Was überwachen?

  • Pull-Häufigkeit (wie oft wird Image genutzt?)
  • Storage-Usage (läuft der Platz voll?)
  • Failed-Pulls (Permission-Probleme?)
  • Scan-Results (neue Vulnerabilities?)

GitHub Package-Insights:

GitHub → Packages → Dein Image → Insights

🎯 Checkpoint: Hast du’s geschafft?

Test 1: GHCR Push

# Image bauen
docker build -t myapp .

# Taggen
docker tag myapp ghcr.io/DEIN_USERNAME/myapp:test

# Pushen
docker push ghcr.io/DEIN_USERNAME/myapp:test

Ergebnis: Image auf GitHub sichtbar?


Test 2: GitHub Actions Integration

Pipeline pusht automatisch bei Git-Push?

git add .
git commit -m "Test GHCR pipeline"
git push origin main

Prüfen:

GitHub → Actions → Build and Push → ✅ Success
GitHub → Packages → Neues Image sichtbar

Test 3: Multi-Arch Pull

# Auf verschiedenen Systemen
docker pull ghcr.io/DEIN_USERNAME/myapp:1.0.0

# Architektur prüfen
docker inspect ghcr.io/DEIN_USERNAME/myapp:1.0.0 | grep Architecture

Ergebnis: Korrekte Architektur für dein System?


❓ FAQ

1. Docker Hub vs. GHCR – was ist schneller?

Kommt drauf an:

  • Docker Hub: Große CDN, aber Rate-Limits
  • GHCR: Schnell wenn du in GitHub-Actions bist, sonst ähnlich

Empfehlung: GHCR für GitHub-Projekte, Docker Hub für Public-Images


2. Kostet GHCR was?

Nein, für die meisten Use-Cases gratis:

  • Public Repos: Unlimited
  • Private Repos: 500 MB Free, dann $0.25/GB
  • Bandwidth: Gratis

Für 99% der Projekte ausreichend!


3. Kann ich von Docker Hub zu GHCR migrieren?

Ja, super einfach:

# Von Docker Hub pullen
docker pull username/myapp:1.0.0

# Für GHCR taggen
docker tag username/myapp:1.0.0 ghcr.io/username/myapp:1.0.0

# Nach GHCR pushen
docker push ghcr.io/username/myapp:1.0.0

Pipeline anpassen: Registry von docker.io auf ghcr.io ändern. Done!


4. Multi-Arch dauert ewig – geht’s schneller?

Ja, mit Caching:

cache-from: type=gha
cache-to: type=gha,mode=max

Erster Build: ~10 Min (beide Architekturen)
Zweiter Build: ~3 Min (nur geänderte Layer)


5. Wie viele Tags sollte ich pro Image haben?

Empfehlung:

  • 1x Semantic Version (1.2.3)
  • 1x Semantic + SHA (1.2.3-abc123f)
  • 1x Branch (main/staging/dev)
  • Optional: Major/Minor (1.2, 1)

Nicht: 20 Tags mit :final, :release, :prod-final 😅


6. Kann ich GHCR auch für non-Docker Artifacts nutzen?

Ja! GHCR ist eigentlich GitHub Packages:

  • Docker/OCI Images
  • Maven Artifacts (JAR/WAR)
  • npm Packages
  • NuGet Packages
  • RubyGems

7. Private Logs Easter Egg – was ist mit Lisa? 😉

Code Sentinel: „Lisa? Ähm… sie findet Container-Registries interessant. Glaube ich. Vielleicht. Haben wir nicht drüber geredet…“

Gateway (Katze): [Schaut wissend, sagt nichts]

Real Talk: Es gibt Dinge, die wichtiger sind als Tagging-Strategien. Zum Beispiel… naja, lies die Private Logs wenn du mehr wissen willst. 😊

Aber zurück zu den Images! 🐳


📦 Downloads & Ressourcen

Komplettes Maven-Projekt (ZIP):

📦 registry-integration-demo.zip

Enthält:

  • ✅ Spring Boot App mit REST API
  • ✅ Dockerfile (Multi-Stage, Multi-Arch)
  • .github/workflows/ – Komplette CI/CD Pipeline
    • Build & Push zu GHCR
    • Multi-Arch Support
    • Trivy Scanning
    • Automated Tagging
    • Cleanup-Job
  • scripts/ – Helper-Scripts
    • build-multiarch.sh – Lokaler Multi-Arch Build
    • cleanup-old-images.sh – Alte Images löschen
    • verify-image.sh – Image-Architektur prüfen
  • README.md – Setup-Guide
  • ✅ Beispiel-Kubernetes-Deployment

🔗 Externe Links – Teil 7: Container Registry & Image-Management

Für Einsteiger 🌱

RessourceBeschreibung
GHCR DokumentationGitHub Container Registry Schnellstart
Docker Hub DocsDocker Hub Grundlagen
Multi-Platform ImagesMulti-Arch Builds verstehen

GitHub Container Registry (GHCR) 🐙

RessourceBeschreibung
GHCR DocsKomplette GHCR-Dokumentation
GHCR AuthentifizierungLogin & Token-Setup
Package VisibilityPublic vs. Private Images

Docker Registry 🐳

RessourceBeschreibung
Docker Registry DocsOffizielle Registry-Dokumentation
Private Registry SetupEigene Registry betreiben
Registry APIREST API Referenz

Multi-Architecture Builds 🏗️

RessourceBeschreibung
Docker BuildxBuildx Dokumentation
Multi-Platform ImagesAMD64 + ARM64 Builds
QEMU ActionGitHub Action für Cross-Platform
Build-Push ActionGitHub Action für Registry Push

Image Tagging & Versioning 🏷️

RessourceBeschreibung
Docker Metadata ActionAutomatisches Tagging in CI/CD
OCI Image SpecContainer Image Standard
Semantic VersioningSemVer Spezifikation
OCI AnnotationsStandard-Labels für Images

Supply Chain Security 🔐

RessourceBeschreibung
Docker SBOMSoftware Bill of Materials
Sigstore CosignImage Signing
Docker Content TrustImage-Verifikation
SLSA FrameworkSupply Chain Levels for Software Artifacts

Alternative Registries 🌐

RegistryDokumentation
Azure Container RegistryMicrosoft ACR
AWS ECRAmazon Elastic Container Registry
Google Artifact RegistryGoogle Cloud Registry
GitLab Container RegistryGitLab integrierte Registry
HarborOpen Source Self-Hosted Registry

Vulnerability Scanning 🛡️

ToolBeschreibung
TrivyAqua Security Scanner
GrypeAnchore Vulnerability Scanner
Snyk ContainerSnyk Container Scanning
Docker ScoutDocker’s eigener Scanner

Kubernetes Integration ☸️

RessourceBeschreibung
Image Pull SecretsPrivate Registry in K8s nutzen
ImagePullPolicyAlways, IfNotPresent, Never
Kubernetes CRIContainer Runtime Interface

Cheat Sheet: GHCR Commands

# === Login ===
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin

# === Build & Tag ===
docker build -t myapp .
docker tag myapp ghcr.io/USERNAME/myapp:1.0.0

# === Push ===
docker push ghcr.io/USERNAME/myapp:1.0.0

# === Pull ===
docker pull ghcr.io/USERNAME/myapp:1.0.0

# === Multi-Arch ===
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t ghcr.io/USERNAME/myapp:1.0.0 \
  --push .

# === Inspect ===
docker inspect ghcr.io/USERNAME/myapp:1.0.0 | grep Architecture
docker manifest inspect ghcr.io/USERNAME/myapp:1.0.0

# === Cleanup ===
docker image prune -a  # Lokale unused Images

🏆 Community-Challenge

Challenge dieser Woche:

  1. Setup GHCR für ein bestehendes Projekt
  2. Implementiere Multi-Tag-Strategy (Version + SHA + Branch)
  3. Baue Multi-Arch Image (AMD64 + ARM64)
  4. GitHub Actions Pipeline die automatisch pusht
  5. Bonus: Lifecycle-Policy für Cleanup

Share auf Twitter/LinkedIn:

🐳 Mein erstes Multi-Arch Image in GHCR! 

Gelernt von @java_fleet_systems CI/CD Serie:
✅ Semantic Versioning
✅ Multi-Platform Support  
✅ Automated Pipeline

#Docker #GHCR #DevOps #CI_CD

Hashtag: #JavaFleetCICD #CodeSentinelSeries


🚀 Serie-Übersicht: Alle 12 Teile

TeilDatumThemaStatus
117.10.25Erste Pipeline
224.10.25Security Gates (OWASP + Trivy)
331.10.25Coverage Gates (JaCoCo)
407.11.25Quality Gates (SonarQube)
514.11.25Multi-Stage Builds
621.11.25Container Security (SBOM)
705.12.25Registry Integration👉 DU BIST HIER
812.12.25Blue-Green Deployments
919.12.25Canary & Kubernetes
1026.12.25GitOps & Environments
1102.01Jenkins Enterprise
1209.01Multi-Platform & Finale

📅 Nächste Woche : Blue-Green Deployments

Preview:

Du hast jetzt Images in GHCR. Perfekt!

Aber: Wie deployst du sie ohne Downtime?

Teil 8 zeigt dir:

  • ✅ Blue-Green Deployment-Strategy
  • ✅ Zero-Downtime Deployments
  • ✅ Automatischer Traffic-Switch
  • ✅ Rollback in Sekunden
  • ✅ Load-Balancer Integration

Teaser-Story:

Sarah aus Berlin schreibt:

„Unser Deployment-Window ist Freitag 2-4 Uhr nachts. Heißt: Ich stehe Freitag um 1:30 Uhr auf, deploye, hoffe dass nichts kaputt geht, und kann dann erst wieder um 10 Uhr schlafen. Gibt’s nicht einen besseren Weg?“

Code Sentinel: „Ja, Sarah. Blue-Green Deployments. Du deployest tagsüber, ohne Stress, und wenn’s schief geht: Switch zurück in 5 Sekunden. Keine nächtlichen Deployments mehr.“

Bis nächste Woche! 🚀


🎬 Abschluss

Was du heute gelernt hast:

  • ✅ GHCR Setup & Nutzung
  • ✅ Image-Tagging-Strategien (SemVer + SHA)
  • ✅ GitHub Actions Integration
  • ✅ Multi-Architecture Builds
  • ✅ Registry-Security & Access-Control
  • ✅ Lifecycle-Management & Cleanup

Was du jetzt kannst:

  • Private Registry aufsetzen
  • Images intelligent versionieren
  • Multi-Arch Images bauen
  • CI/CD Pipeline mit Registry-Push
  • Production-ready Image-Management

Real Talk: Registry-Management klingt langweilig. Ist es auch. Bis dein Deployment failed weil du das falsche Image gepullt hast. Dann ist es plötzlich sehr interessant.

Gute Tagging-Strategie + automatisiertes Pushen = weniger Stress, mehr Schlaf.

Gateway approved: 🐱✅


🔗 Ressourcen & Links

  • GitHub Container Registry Docs: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry
  • Docker Buildx Multi-Platform: https://docs.docker.com/buildx/working-with-buildx/
  • Semantic Versioning: https://semver.org/
  • Cosign (Image-Signing): https://github.com/sigstore/cosign

Viel Erfolg beim Registry-Setup! 🐳

Code Sentinel
Technical Project Manager @ Java Fleet Systems Consulting
„Security-first, pragmatisch, production-ready“

📧 code.sentinel@java-developer.online


🍀 Bernd’s Corner

„Es gibt zwei Arten von Entwicklern: Die, die ihre Images vernünftig taggen, und die, die um 3 Uhr nachts Production debuggen weil sie nicht wissen welches Image da läuft.“

:latest in Production ist wie ‚YOLO‘ im Code-Review: Theoretisch möglich, praktisch karrierebegrenzend.“

„Multi-Arch Builds sind wie Esperanto für Docker: Eine Sprache, alle Plattformen. Nur dass es tatsächlich funktioniert.“

Bernd’s Tipp der Woche:

„Wenn dein Image-Tag mehr als 3 Wörter hat und ‚final‘ vorkommt, hast du ein Problem. Und ich meine nicht technisch.“


Teil 7 von 12 – CI/CD Enterprise Mastery Serie
© 2025 Java Fleet Systems Consulting

Autor

  • Code Sentinel

    32 Jahre alt, Technical Project Manager und Security-Experte bei Java Fleet Systems Consulting. Code ist ein erfahrener Entwickler, der in die Projektleitung aufgestiegen ist, aber immer noch tief in der Technik verwurzelt bleibt. Seine Mission: Sicherstellen, dass Projekte termingerecht, sicher und wartbar geliefert werden.