Design wechseln

Docker Secrets – vollständiger Leitfaden: Passwörter und API-Schlüssel in Containern sicher verwalten

Easton editorial illustration: registry transfer crane

Das Handy vibriert ununterbrochen – 24 SMS, alle Datenbank-Alarme. Per SSH auf den Server: Die Verbindungsanzahl zur Datenbank ist voll, jemand führt Brute-Force-Angriffe durch.

In den Logs zeigt sich: Der Angreifer nutzte das richtige Passwort – das MySQL-Passwort, das vor drei Monaten in der docker-compose.yml stand. Letzten Monat hat ein Praktikant das Projekt in sein öffentliches Repository geforkt, um zu üben – so wurde das Passwort geleakt.

Selbst ohne Code-Leak reicht es, wenn jemand docker inspect ausführen kann: Alle Umgebungsvariablen sind im Klartext sichtbar. Dieser Artikel behandelt die Verwaltung von Container-Passwörtern – welche gefährlichen Vorgehensweisen Sie vermeiden sollten und welche Tools sensible Daten wirklich schützen.

Warum sind Umgebungsvariablen unsicher?

Drei häufige unsichere Vorgehensweisen

Ich erzähle zuerst von Fehlern, die ich selbst gemacht habe – vielleicht kennen Sie das auch.

Erste Variante: Direkt im Dockerfile

FROM node:18
ENV DATABASE_PASSWORD=MyS3cr3tP@ssw0rd
ENV API_KEY=sk-1234567890abcdef

Das ist die schlechteste Variante. Jede Anweisung im Dockerfile erzeugt eine Image-Schicht. Selbst wenn Sie später ENV DATABASE_PASSWORD="" setzen, bleibt das Passwort in den History-Layern. Wer Ihr Image hat, findet es mit docker history <image-name>.

Glauben Sie es nicht? Ich auch nicht – bis ein Kollege es mir vorführte. Er zog ein internes Firmen-Image, ein paar Befehle – und der AWS Access Key war sichtbar. Der Key stammte von einem ehemaligen Kollegen vor drei Jahren, den wir vergessen hatten zu löschen.

Zweite Variante: In docker-compose.yml

version: '3.8'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: SuperSecretPassword123
      MYSQL_DATABASE: myapp

Damit habe ich lange gearbeitet. Der Grund: Bequem. Ein docker-compose up -d – fertig, effizient für Entwicklung und Debugging.

Das Problem? Die Datei landet in Git. Auch bei privaten Repos reicht schlechtes Berechtigungsmanagement – oder, wie bei mir, ein Fork in ein öffentliches Repository – und alle Passwörter sind draußen.

Dritte Variante: .env-Datei, aber in der Versionskontrolle

# .env-Datei
DB_PASSWORD=password123
API_SECRET=abcdef123456

Das wirkt schlauer: Sensible Daten in eine separate .env-Datei, in docker-compose per ${DB_PASSWORD} referenziert.

Viele (auch ich früher) committen .env trotzdem in Git – „das Team muss das Projekt ja starten können“. Ergebnis: kein Unterschied zu docker-compose.yml.

Richtig: .env in .gitignore und eine .env.example-Vorlage bereitstellen. Ehrlich gesagt denkt man am Anfang selten so weit.

Drei zentrale Sicherheitsrisiken von Umgebungsvariablen

Selbst mit .env in .gitignore und ohne Code-Leak bleiben Umgebungsvariablen unsicher. Warum?

Risiko 1: docker inspect zeigt alles

Probieren Sie:

docker inspect <container-id> | grep -A 20 "Env"

Alle Umgebungsvariablen – inklusive Passwörter – im Klartext.

Was bedeutet das? Jeder mit Zugriff auf den Docker-Daemon – Ops, DevOps, Entwickler mit Server-Rechten – sieht Ihre Passwörter. Kein Cracken, keine Spezialtechnik – ein Befehl.

In einem Startup hatten alle SSH-Zugriff auf die Produktion – aus Bequemlichkeit. Eines Tages tippte ein neuer Frontend-Entwickler neugierig docker inspect – und das Datenbankpasswort stand auf dem Bildschirm. Zum Glück war es ein Kollege. Was wäre bei jemandem mit bösen Absichten passiert?

Risiko 2: Prozesse im Container können lesen

Nicht nur Docker sieht Umgebungsvariablen – alle Prozesse im Container auch. Unter Linux liegen sie in /proc/<PID>/environ.

Hat eine Abhängigkeit Ihrer Anwendung eine Schwachstelle und wird Code injiziert, kann ein Angreifer Umgebungsvariablen auslesen und an Passwörter kommen.

Letztes Jahr wurde bei einer Node.js-Bibliothek ein Backdoor entdeckt, der AWS-Credentials aus Umgebungsvariablen las und nach außen sendete. Betroffen: Zehntausende Projekte.

Risiko 3: Leaks in Logs

Das ist subtiler.

Beim Start loggen Anwendungen oft Konfiguration; bei Fehlern werden manchmal Umgebungsvariablen in Logs geschrieben. Log-Dateien haben oft lockere Rechte oder gehen in zentrale Systeme wie ELK.

Ich kenne Teams, die alle Container-Logs in einen Elasticsearch-Cluster schicken. Beim Security-Audit: Hunderte Datenbankpasswörter in den Logs – weil Entwickler beim Debuggen console.log(process.env) nutzten und es vergaßen.

Schlimmer: Ist ein Passwort einmal in Logs, ist es schwer vollständig zu entfernen – Backups, Archive, Kopien überall.

Echte Fälle

Solche Vorfälle gibt es häufiger, als Firmen öffentlich zugeben. Ein paar Beispiele:

Fall 1: Leak über öffentliches GitHub-Repository

2023 zeigte eine Auswertung: Über eine Million öffentliche GitHub-Repositories enthielten API-Schlüssel, Datenbankpasswörter und ähnliche sensible Daten. Nicht weil die Entwickler dumm wären – oft Test-Konfigurationen, die nicht gelöscht wurden, oder versehentlich committede .env-Dateien.

Ein Bekannter aus dem ML-Bereich: Das Team veröffentlichte Trainingscode auf GitHub – und pushte AWS-Credentials mit. Innerhalb von 24 Stunden nutzte jemand die Credentials für GPU-Instanzen zum Mining. Rechnung: über 20.000 US-Dollar.

Fall 2: Leak in CI/CD-Pipeline-Historie

Build-Historien in Jenkins, GitLab CI usw. speichern oft Umgebungsvariablen-Logs. Ohne Maskierung sind das Passwort-Sammlungen.

Ein Projekt mit GitLab CI-Auto-Deploy: Ein Kollege gab vor dem Ausscheiden einem Outsourcing-Team Repo-Zugriff. Jemand durchsuchte alte Build-Logs und fand Produktions-Datenbank-Zugangsdaten. Zum Glück wollten sie helfen und meldeten es – bei böser Absicht?

Fall 3: Docker-Hub-Image-Scan

Ein Alibaba-Security-Bericht: Beim Scan öffentlicher Docker-Images hatten 76 % Sicherheitslücken, viele mit hardcodierten Credentials.

Manche Unternehmen pushen interne Images auf öffentliches Docker Hub – „wer soll schon unser kleines Unternehmen scannen“. Heute gibt es automatisierte Crawler und Scanner dafür. Minuten nach dem Push kann Ihr Image durchsucht sein.

Das soll nicht Angst machen – sondern zeigen: Diese Probleme passieren wirklich, häufiger als gedacht. Und sie lassen sich vermeiden.

Was sind Docker Secrets? Wie nutzt man sie?

Funktionsweise von Docker Secrets

Jetzt zur Lösung.

Docker Secrets ist das offizielle Schlüssel-Management von Docker. Kurz gesagt: Secrets sind keine Klartext-Strings, sondern verschlüsselte Dateien.

Der Ablauf:

  1. Sie erstellen ein Secret – Docker speichert es verschlüsselt im Raft-Log des Clusters
  2. Braucht ein Container das Secret, überträgt Docker es per verschlüsselter TLS-Verbindung
  3. Das Secret wird als Datei unter /run/secrets/ gemountet
  4. Das Verzeichnis ist tmpfs – reines RAM-Dateisystem, nichts auf Disk
  5. Nach Container-Stopp verschwindet das Secret aus dem Speicher

Der Kernpunkt: Secrets erscheinen nicht in Umgebungsvariablen, nicht in docker inspect, nicht in Images via docker commit.

Klingt abstrakt? Mir ging es beim ersten Docker-Dokument genauso. Am besten direkt ausprobieren.

Einschränkung: Docker Secrets funktionieren nativ nur im Swarm-Modus. Am Anfang nervte mich das – lokale Entwicklung, Single-Node – warum nicht?

Später: docker-compose unterstützt file secrets (schwächer, aber nutzbar). In Produktion: Swarm oder Kubernetes.

Schritt-für-Schritt: MySQL + WordPress

Ein vollständiges Beispiel: WordPress-Blog mit geschützten MySQL-Root- und Benutzerpasswörtern.

Schritt 1: Secret-Dateien anlegen

Passwörter in lokale Dateien (nicht in Git committen):

echo "MyRootPassword123" > db_root_password.txt
echo "MyUserPassword456" > db_password.txt

Schritt 2: Swarm initialisieren (falls noch nicht geschehen)

docker swarm init

Ein Befehl reicht. Swarm auch auf Single-Node möglich – kein Multi-Machine-Cluster nötig.

Schritt 3: Docker Secrets erstellen

docker secret create mysql_root_password db_root_password.txt
docker secret create mysql_password db_password.txt

Danach lokale Passwort-Dateien sofort löschen:

rm db_root_password.txt db_password.txt

Wichtig: Nach verschlüsselter Speicherung in Docker gehört Klartext lokal weg.

Prüfen:

docker secret ls

Ausgabe etwa:

ID                          NAME                  CREATED         UPDATED
abc123...                   mysql_root_password   5 seconds ago   5 seconds ago
def456...                   mysql_password        3 seconds ago   3 seconds ago

Sie sehen den Secret-Inhalt nicht – nur Name und Metadaten. Selbst Admins bekommen keinen Klartext.

Schritt 4: docker-compose.yml erstellen

version: '3.8'

secrets:
  mysql_root_password:
    external: true
  mysql_password:
    external: true

services:
  db:
    image: mysql:8.0
    secrets:
      - mysql_root_password
      - mysql_password
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
      MYSQL_PASSWORD_FILE: /run/secrets/mysql_password
      MYSQL_USER: wordpress
      MYSQL_DATABASE: wordpress
    volumes:
      - db_data:/var/lib/mysql

  wordpress:
    image: wordpress:latest
    depends_on:
      - db
    ports:
      - "8080:80"
    secrets:
      - mysql_password
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD_FILE: /run/secrets/mysql_password
      WORDPRESS_DB_NAME: wordpress

volumes:
  db_data:

Wichtige Punkte:

  1. secrets auf Top-Level: Welche Secrets genutzt werden; external: true = bereits vorhanden, nicht von Compose erstellt
  2. services.db.secrets: Welche Secrets dieser Service nutzt
  3. MYSQL_ROOT_PASSWORD_FILE: Offizielles MySQL-Image unterstützt _FILE-Suffix – Passwort aus Datei statt Umgebungsvariable

Nicht jedes Image unterstützt _FILE. Dann im Start-Skript selbst lesen:

# entrypoint.sh Beispiel
export DB_PASSWORD=$(cat /run/secrets/db_password)
# Anwendung starten

Schritt 5: Deploy

docker stack deploy -c docker-compose.yml myapp

Hier docker stack deploy, nicht docker-compose up – Swarm-Modus.

Schritt 6: Verifizieren

In den MySQL-Container und Secrets prüfen:

docker exec -it <container-id> sh
ls -la /run/secrets/

Ausgabe:

total 8
-r--r--r-- 1 root root 18 Dec 18 10:00 mysql_password
-r--r--r-- 1 root root 18 Dec 18 10:00 mysql_root_password

Lesen:

cat /run/secrets/mysql_root_password

Das Passwort ist da – aber nur im RAM, nicht auf Disk, nicht in Umgebungsvariablen.

docker inspect ohne Klartext-Passwort:

docker inspect <container-id> | grep -i password

Nur Pfade wie MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_passwordkein Passwort selbst.

Das ist die Stärke von Docker Secrets: Die Anwendung kann lesen, von außen gibt es keinen Klartext.

Einschränkungen und Alternativen

Docker Secrets ist nicht perfekt. Hauptlimits:

Limit 1: Swarm-Modus erforderlich

Nervig für lokale Single-Node-Entwicklung: erst docker swarm init. Dann docker stack deploy statt docker-compose up – Gewohnheiten ändern sich.

Limit 2: Secrets sind nach Erstellung unveränderlich

Passwort ändern = löschen und neu anlegen:

docker secret rm mysql_password
echo "NewPassword789" | docker secret create mysql_password -

Dann alle Services aktualisieren:

docker service update --secret-rm mysql_password --secret-add mysql_password myapp_db

Umständlicher als Umgebungsvariable ändern und Container neu starten.

Limit 3: Nicht für standalone docker run

Direkt mit docker run gestartete Container nutzen Docker Secrets nicht. Nur Services via docker service create oder docker stack.

Für schnelle Tests unpraktisch – manchmal will man nur kurz eine DB hochfahren.

Alternative für lokale Entwicklung: docker-compose file secrets

docker-compose bietet file secrets ohne Swarm – lokale Datei als Secret gemountet.

version: '3.8'

secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  db:
    image: mysql:8.0
    secrets:
      - db_password
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password

Lokale Passwort-Datei:

mkdir secrets
echo "MyPassword123" > secrets/db_password.txt

Wichtig: secrets/ in .gitignore!

Sicherer als Umgebungsvariablen – kein Klartext in docker inspect, nicht im Image. Schwächer als echte Docker Secrets:

  • Klartext-Datei auf lokaler Disk
  • Keine verschlüsselte Übertragung
  • Keine zentrale Verwaltung

Für lokale Entwicklung oft ausreichend. In Produktion: Swarm oder Kubernetes.

Fortgeschrittene Tipps

Tipp 1: Eigenen Mount-Pfad setzen

Standard: /run/secrets/<secret_name>. Anpassbar:

services:
  myapp:
    image: myapp:latest
    secrets:
      - source: db_password
        target: /app/config/database.pwd
        mode: 0400

mode: 0400 = nur Owner lesbar.

Tipp 2: Multi-Environment

Dev, Test, Produktion – verschiedene Passwörter, gleicher Secret-Name:

# Produktion
docker secret create db_password prod_password.txt

# Test (anderer Swarm-Cluster)
docker secret create db_password test_password.txt

Code liest /run/secrets/db_password – Wert egal. Gleicher Code, verschiedene Cluster.

Tipp 3: Secret-Rotation

Passwörter regelmäßig wechseln. Bei Docker etwas umständlich, aber machbar:

# 1. Neues Passwort
echo "NewPassword" | docker secret create db_password_v2 -

# 2. Service aktualisieren
docker service update \
  --secret-rm db_password \
  --secret-add source=db_password_v2,target=/run/secrets/db_password \
  myapp_db

# 3. Nach erfolgreicher Prüfung altes Secret löschen
docker secret rm db_password

Neues Secret heißt db_password_v2, Mount-Pfad bleibt /run/secrets/db_password – kein Code-Change nötig.

Tipp 4: Secret aus stdin

Keine Spuren auf Disk:

echo "MySecretPassword" | docker secret create db_password -

Das - = stdin. Oder sicherer, manuelle Eingabe (nicht in Shell-History):

docker secret create db_password -
# Passwort einfügen, Ctrl+D

Vergleich anderer Schlüsselverwaltungs-Tools

Vergleichsmatrix

Docker Secrets ist nicht die einzige Option. Je nach Projektgröße und Infrastruktur brauchen Sie vielleicht andere Tools:

ToolEinsatzVorteileNachteileEinstieg
Docker SecretsDocker-Swarm-ClusterNative Unterstützung, keine Extra-Kosten, einfache KonfigurationNur Swarm, relativ basic, nicht plattformübergreifend⭐ Niedrig
Kubernetes SecretsK8s-ProduktionNative K8s-Integration, an Pod-Lebenszyklus gebundenetcd standardmäßig unverschlüsselt, basic, Extra-Konfiguration für Sicherheit⭐⭐ Mittel
HashiCorp VaultEnterprise, Multi-Cloud, ComplianceSehr mächtig, dynamische Secrets, feingranulare Rechte, Audit-Logs, viele BackendsKomplex, eigener Betrieb, steile Lernkurve⭐⭐⭐ Hoch
AWS Secrets ManagerAWS, RDS/LambdaTiefe AWS-Integration, Auto-Rotation für RDS, Managed ServiceAWS-gebunden, Multi-Cloud schwierig, Kosten⭐⭐ Mittel

Kurz:

  • Kleines Projekt, Docker Swarm → Docker Secrets reicht, kostenlos und einfach
  • Kubernetes-Produktion → K8s Secrets, mit External Secrets Operator für Vault-Anbindung
  • Großunternehmen, Multi-Cloud, hohe Sicherheit → Vault, langfristig lohnend
  • AWS-Stack → Secrets Manager, gute Integration mit RDS, Lambda

Kein bestes Tool – nur das passende. Mein Weg: docker-compose file secrets → Docker Swarm + Docker Secrets → K8s, Vault-Evaluierung läuft.

Jede Migration kostet – Sicherheit steigt schrittweise.

Auswahl-Empfehlungen

Persönlicher Entwickler / kleines Projekt:

  • Lokal: docker-compose file secrets
  • VPS mit wenigen Services: Docker Swarm + Docker Secrets
  • Kleines Budget: Vault ist Overkill

Startup (10–50 Personen):

  • Docker: Docker Secrets
  • K8s: K8s Secrets + External Secrets Operator (später Vault)
  • Alles auf AWS: Secrets Manager

Großunternehmen:

  • Multi-Cloud: Vault fast Pflicht
  • Audit/Compliance: Vault
  • Eigenes Security-Team: Vault
  • Budget vorhanden: Vault

Entscheidungsbaum:

Nutzen Sie K8s?
 └─ Ja → K8s Secrets, bei Bedarf Vault
 └─ Nein → Docker Swarm?
      └─ Ja → Docker Secrets
      └─ Nein → AWS?
           └─ Ja → AWS Secrets Manager
           └─ Nein → file secrets (Dev) / Vault (Prod)

Praxisbeispiele

Fall 1: Evolution eines Startups

SaaS-Firma, anfangs 5 Leute, alles Docker auf einem VPS. docker-compose + file secrets, Passwort-Dateien manuell auf dem Server.

Nach 6 Monaten und Angel-Runde: 15 Leute, Microservices. Docker Swarm + Docker Secrets – zentral statt Passwort-Dateien auf jedem Server.

Ein Jahr später, A-Runde, Umzug auf K8s: K8s Secrets, AWS RDS/S3 mit Secrets Manager, External Secrets Operator synchronisiert.

Jetzt Vault-Evaluierung wegen Multi-Cloud (GCP-Backup) – Secrets Manager bindet an AWS.

Sicherheitsarchitektur wächst mit dem Business – am Anfang nicht gleich das Komplexeste.

Fall 2: Bank – direkt Vault

Containerisierung in der Finanzbranche, strenge Compliance – von Anfang an Vault.

Steile Lernkurve, aber:

  • Vollständige Audit-Logs bei jedem Secret-Zugriff
  • Dynamische Secrets (temporäre DB-Credentials)
  • LDAP-Anbindung für Berechtigungen

Zwei Personenmonate Setup und Training – danach niedrige Wartungskosten.

Unterschiedliche Szenarien, unterschiedliche Wahl. Vault für Kleinfirmen oft zu schwer, Docker Secrets für Konzerne oft zu wenig.

Checkliste: Best Practices für die Produktion

Sofort-Maßnahmen

Unabhängig von Docker Secrets – das sollten Sie jetzt tun:

✅ Git-Historie auf sensible Daten prüfen

# Nach Passwort-Schlüsselwörtern suchen
git log -p -S 'password' -S 'secret' -S 'api_key'

# Prüfen, ob .env committed wurde
git log --all --full-history -- .env

Gefunden? Mit git filter-repo oder BFG Repo-Cleaner Historie bereinigen – und sofort alle geleakten Passwörter wechseln.

✅ .gitignore konfigurieren

# .gitignore
.env
*.env
secrets/
db_password.txt
*_password.txt
*_secret.txt
*.pem
*.key

Keine Ausnahmen – unbedingt eintragen.

✅ GitHub Secret Scanning aktivieren

Bei GitHub: Repository-Einstellungen → Security → Secret scanning alerts. Bei versehentlichem Push warnt GitHub.

Kostenlos für öffentliche Repos; private brauchen Pro/Team/Enterprise. Öffentliche Repos brauchen es am dringendsten.

✅ Alle möglicherweise geleakten Credentials wechseln

Inventar:

  • Datenbankpasswörter
  • API-Schlüssel (AWS/OpenAI/Stripe usw.)
  • JWT Secret
  • OAuth Client Secrets
  • SSL-Private Keys

Alles Wechselbare wechseln. Nach Leak ist Reparieren noch möglich.

Docker Secrets umsetzen

Schritt 1: Sensible Daten inventarisieren

✓ MySQL-Root-Passwort
✓ App-Datenbankpasswort
✓ Redis-Passwort
✓ JWT-Signatur-Schlüssel
✓ Drittanbieter-API-Schlüssel (Zahlung/SMS usw.)
✓ SSL-Zertifikat-Private Keys
✓ OAuth Client Secret

Schritt 2: Tool wählen

Docker Secrets, K8s Secrets oder Vault – nicht zu lange zögern, später migrierbar.

Schritt 3: Secrets erstellen

# Docker Swarm
docker swarm init
docker secret create db_password <(echo "Passwort")
docker secret create api_key <(echo "Schlüssel")

# docker-compose file secrets
mkdir secrets
echo "Passwort" > secrets/db_password.txt
echo "Schlüssel" > secrets/api_key.txt
chmod 600 secrets/*

Schritt 4: Konfiguration anpassen

environment in docker-compose.yml durch secrets ersetzen:

# Vorher
services:
  app:
    environment:
      DB_PASSWORD: "hardcoded_password"  # ❌

# Nachher
services:
  app:
    secrets:
      - db_password
    environment:
      DB_PASSWORD_FILE: /run/secrets/db_password  # ✅

Schritt 5: Anwendungscode (falls nötig)

Ohne _FILE-Unterstützung im Framework:

// Node.js Beispiel
const fs = require('fs');
const dbPassword = process.env.DB_PASSWORD_FILE
  ? fs.readFileSync(process.env.DB_PASSWORD_FILE, 'utf8').trim()
  : process.env.DB_PASSWORD;

Schritt 6: Testen

In Testumgebung prüfen:

  • Service startet
  • Passwort wird korrekt gelesen
  • docker inspect zeigt keinen Klartext
  • Funktionen laufen

Schritt 7: Produktions-Deploy

Erst in Produktion, wenn stabil. Optional alte Umgebungsvariablen als Fallback behalten, bis das neue Setup sicher läuft.

Laufende Sicherheit

Docker Secrets ist kein Set-and-Forget:

Regelmäßige Rotation (empfohlen: alle 90 Tage)

Kalender-Erinnerung, quartalsweise Passwörter wechseln. Nach Austritt Mitarbeiter: zugehörige Passwörter sofort tauschen.

Secret-Zugriffs-Logs überwachen

Bei Vault: Audit-Logs prüfen, ungewöhnliche Muster erkennen.

Docker Secrets und K8s Secrets haben standardmäßig keine Audit-Logs – dann Tools wie Falco ergänzen.

Principle of Least Privilege

Nicht jeder Service alle Secrets – nur was nötig ist:

services:
  frontend:
    secrets:
      - api_key  # Frontend braucht nur API key

  backend:
    secrets:
      - db_password  # Backend braucht DB-Passwort
      - api_key

Schlüssel-Scanner in CI/CD

Im pre-commit hook – fängt viele Fehlcommits ab.

Fünf typische Fallstricke

1. Keine sensiblen Daten über ARG

# ❌ Falsch
ARG DB_PASSWORD=secret
ENV DATABASE_URL=postgres://user:${DB_PASSWORD}@db/myapp

ARG bleibt in der Build-Historie – docker history zeigt es.

2. Secrets nicht nach stdout loggen

# ❌ Falsch
password = open('/run/secrets/db_password').read()
print(f"Using password: {password}")  # landet in docker logs!

Log-Systeme erfassen stdout. Passwort in Logs ist schwer zu entfernen.

3. Nicht dasselbe Secret über Umgebungen teilen

Dev, Test, Prod getrennt. Ein Leak in Test darf Prod nicht treffen.

4. Secret nicht in Container auf andere Pfade kopieren

# ❌ Falsch
cp /run/secrets/db_password /app/config/password.txt

/run/secrets ist tmpfs – beim Stopp weg. Kopie kann auf Disk landen – unsicherer.

Direkt aus /run/secrets lesen.

5. Ablauf und Rotation dynamischer Secrets nicht vergessen

Bei Vault mit Ablaufzeit: Auto-Renewal oder Rotation konfigurieren. Nicht erst nachts merken, dass alles abgelaufen ist.

Fazit

Kernbotschaft: Legen Sie Passwörter nicht dort ab, wo sie sichtbar sind.

Umgebungsvariablen wirken bequem – docker inspect zeigt alles. ENV im Dockerfile ist schlimmer – permanent in Image-Layern. Viele Vorfälle entstehen durch solche „Bequemlichkeiten“.

Docker Secrets ist nicht perfekt – Swarm nötig, keine nachträgliche Änderung, lokal umständlich. Aber es löst das Kernproblem: verschlüsselte Speicherung, verschlüsselte Übertragung, nicht in Umgebungsvariablen und Images. Für Docker-Swarm-Cluster die einfachste Lösung.

Kubernetes? K8s Secrets. Enterprise? Vault. Alles AWS? Secrets Manager. Kein bestes Tool – nur das passende.

Handeln Sie heute:

  • Passwörter in der Git-Historie?
  • .env in .gitignore?
  • Zeigt docker inspect Ihre Passwörter?

Bei „ja“, „nein“, „ja“ – Zeit zum Umbauen. Nicht gleich Vault – schon file secrets statt Umgebungsvariablen ist ein Fortschritt.

Sicherheit ist ein Prozess, keine einmalige Konfiguration. Rotation, Monitoring, Scanner – diese Gewohnheiten zählen mehr als das Tool.

Teilen Sie das mit Ihrem Team. Schlüsselverwaltung ist Teamarbeit – einheitliche Standards und regelmäßige Reviews senken das Risiko.

Alles Gute – und hoffentlich keine Alarm-SMS um 3 Uhr nachts mehr.


Referenzen:

Vollständiger Ablauf zur sicheren Verwaltung mit Docker Secrets

Container-Passwörter und API-Schlüssel sicher verwalten, Docker/K8s/Vault vergleichen, mit vollständiger Checkliste für die Produktion

⏱️ Estimated time: 1 hr

  1. 1

    Step 1: Sicherheitsprobleme und falsche Vorgehensweisen verstehen

    Sicherheitsproblem:
    • Angreifer nutzten das richtige Passwort – das MySQL-Passwort aus der docker-compose.yml
    • Letzten Monat hat ein Praktikant das Projekt in sein öffentliches Repository geforkt
    • Passwort-Leak führte zu Brute-Force-Angriffen auf die Datenbank

    Falsche Vorgehensweise:
    • Passwörter direkt in Konfigurationsdateien schreiben
    • Umgebungsvariablen als ausreichend betrachten
    • Argument: „Mein Repository ist privat, das ist egal“
    • Das alles sind Sicherheitsrisiken

    Häufige Fehler:
    • Passwort im Dockerfile
    • Passwort in docker-compose.yml
    • Passwort in Umgebungsvariablen, die in Git committed wurden
    • .env-Datei genutzt, aber nicht in .gitignore eingetragen
  2. 2

    Step 2: Schlüssel mit Docker Secrets verwalten

    Docker-Secrets-Lösung:
    • Secret mit docker secret create anlegen: docker secret create mysql_password -
    • In docker-compose.yml secrets konfigurieren: secrets: - mysql_password
    • Im Container über /run/secrets/ zugreifen: cat /run/secrets/mysql_password
    • Schlüssel verschlüsselt in Docker Swarm gespeichert

    Secret erstellen:
    • echo "your-password" | docker secret create mysql_password -
    • In docker-compose.yml referenzieren: secrets: - mysql_password
    • Im Container lesen: cat /run/secrets/mysql_password
  3. 3

    Step 3: Alternativen vergleichen und Best Practices

    Vergleich anderer Lösungen:
    • Docker Secrets (für Docker Swarm, verschlüsselte Speicherung)
    • Kubernetes Secrets (für K8s, Base64-kodiert)
    • HashiCorp Vault (Enterprise-Schlüsselverwaltung, dynamische Secrets)
    • AWS Secrets Manager (AWS-Umgebung, Integration mit AWS-Diensten)
    • Umgebungsvariablen-Datei (.env, für Produktion nicht empfohlen)

    Best Practices:
    • In der Produktion Secrets für sensible Daten nutzen
    • Schlüssel regelmäßig rotieren
    • Git-Repositories mit Schlüssel-Scannern (trufflehog) prüfen
    • Zugriffskontrolle konfigurieren, Leaks vermeiden
    • Passwörter nicht im Code hardcoden

FAQ

Warum sollte man Passwörter nicht in Dockerfile oder docker-compose.yml schreiben?
Sicherheitsproblem: Angreifer nutzten das richtige Passwort – das MySQL-Passwort aus der docker-compose.yml. Letzten Monat hat ein Praktikant das Projekt in sein öffentliches Repository geforkt, das Passwort wurde geleakt und die Datenbank per Brute-Force angegriffen.

Falsche Vorgehensweise:
• Passwörter direkt in Konfigurationsdateien schreiben
• Umgebungsvariablen als ausreichend betrachten
• Argument: „Mein Repository ist privat, das ist egal“
• Das alles sind Sicherheitsrisiken

Häufige Fehler:
• Passwort im Dockerfile
• Passwort in docker-compose.yml
• Passwort in Umgebungsvariablen, die in Git committed wurden
• .env-Datei genutzt, aber nicht in .gitignore eingetragen
Wie verwaltet man Schlüssel mit Docker Secrets?
Docker-Secrets-Lösung:
• Secret mit docker secret create anlegen (docker secret create mysql_password -)
• In docker-compose.yml secrets konfigurieren (secrets: - mysql_password)
• Im Container über /run/secrets/ zugreifen (cat /run/secrets/mysql_password)
• Schlüssel verschlüsselt in Docker Swarm gespeichert

Secret erstellen:
• echo "your-password" | docker secret create mysql_password -
• In docker-compose.yml referenzieren: secrets: - mysql_password
• Im Container lesen: cat /run/secrets/mysql_password
Was ist der Unterschied zwischen Docker Secrets und anderen Schlüsselverwaltungslösungen?
Vergleich anderer Lösungen:
• Docker Secrets (für Docker Swarm, verschlüsselte Speicherung)
• Kubernetes Secrets (für K8s, Base64-kodiert)
• HashiCorp Vault (Enterprise-Schlüsselverwaltung, dynamische Secrets)
• AWS Secrets Manager (AWS-Umgebung, Integration mit AWS-Diensten)
• Umgebungsvariablen-Datei (.env, für Produktion nicht empfohlen)

Auswahl-Empfehlung:
• Docker Swarm → Docker Secrets
• K8s → Kubernetes Secrets
• Enterprise-Anforderungen → Vault
• AWS → Secrets Manager
Was sind Best Practices für Schlüsselverwaltung in der Produktion?
Best Practices:
• In der Produktion Secrets für sensible Daten nutzen
• Schlüssel regelmäßig rotieren
• Git-Repositories mit Schlüssel-Scannern (trufflehog) prüfen
• Zugriffskontrolle konfigurieren, Leaks vermeiden
• Passwörter nicht im Code hardcoden

Regelmäßige Prüfung:
• Git-Repositories mit trufflehog scannen
• Auf Schlüssel-Leaks prüfen
• CI/CD-Pipeline für automatisches Scannen konfigurieren
• Bei Leak sofort Schlüssel rotieren

14 Min. Lesezeit · Veröffentlicht am: 18. Dez. 2025 · Aktualisiert am: 14. Juli 2026

Ähnliche Beiträge

Kommentare

Melde dich mit GitHub an, um einen Kommentar zu hinterlassen

Easton BlogEaston Blog