Docker Secrets – bezpieczne zarządzanie hasłami i kluczami w kontenerach
W każdym środowisku produkcyjnym pojawia się ten sam problem:
Gdzie przechowywać dane dostępowe aplikacji?
Przykłady:
- hasła do baz danych,
- klucze API,
- certyfikaty TLS,
- tokeny dostępowe,
- klucze SSH,
- dane uwierzytelniające do usług zewnętrznych.
Najczęstszy błąd wygląda tak:
environment:
DB_PASSWORD: SuperHaslo123
Na środowisku testowym może działać. W produkcji jest to poważny problem bezpieczeństwa.
Docker Secrets powstał właśnie po to, aby oddzielić sekrety od konfiguracji aplikacji.
Czym są Docker Secrets?
Docker Secrets to mechanizm przechowywania poufnych danych poza obrazem kontenera i poza zwykłą konfiguracją Compose.
Sekret jest:
- przechowywany zaszyfrowany,
- przekazywany tylko do wybranych usług,
- montowany wewnątrz kontenera jako plik,
- dostępny tylko podczas działania aplikacji.
Schemat:
id="h7d9ax"
Administrator
↓
Docker Secret
↓
Encrypted Storage
↓
Container
↓
/run/secrets/
Dlaczego zmienne środowiskowe są problemem?
Popularne rozwiązanie:
environment:
MYSQL_PASSWORD: password123
Problem:
Sekrety mogą trafić do:
- historii powłoki,
- logów,
- backupów,
- systemów CI/CD,
- paneli administracyjnych,
- narzędzi monitorujących.
Przykład:
docker inspect container
Może pokazać:
{
"MYSQL_PASSWORD": "password123"
}
Czyli osoba z dostępem do Dockera może zobaczyć hasło.
Jak Docker Secrets działa od środka?
Docker przechowuje sekret w wewnętrznym magazynie.
W trybie Swarm:
id="9f0r5a"
Secret
↓
Raft Store
↓
Encrypted Manager Nodes
↓
Worker Node
↓
Container
Sekret nie jest zapisywany jako zwykły plik na hoście.
Tworzenie Docker Secret
Najpierw aktywujemy Docker Swarm:
docker swarm init
Tworzymy sekret:
echo "MyPassword123" | docker secret create db_password -
Sprawdzenie:
docker secret ls
Wynik:
NAME
db_password
Użycie sekretu w kontenerze
Tworzymy usługę:
docker service create \
--name database \
--secret db_password \
mysql
W kontenerze pojawi się:
/run/secrets/db_password
Sprawdzenie:
cat /run/secrets/db_password
wynik:
MyPassword123
Docker Secrets w Docker Compose
W Compose wygląda to tak:
services:
database:
image: mysql:8
secrets:
- db_password
environment:
MYSQL_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true
Ważna różnica:
Nie używamy:
MYSQL_PASSWORD=password
tylko:
MYSQL_PASSWORD_FILE=/run/secrets/db_password
Aplikacja sama odczytuje plik.
Dlaczego plik zamiast zmiennej środowiskowej?
Ponieważ system plików można lepiej kontrolować.
Przykład:
Container
/run/secrets/
└── db_password
↓
tylko odczyt
Zalety:
- brak w historii ENV,
- ograniczony dostęp,
- łatwiejsza rotacja.
Docker Secrets a uprawnienia
Domyślnie:
/run/secrets/
jest:
- tylko do odczytu,
- dostępny tylko dla kontenera,
- usuwany po zatrzymaniu kontenera.
Przykład:
ls -la /run/secrets
wynik:
-r--r----- db_password
Przykład produkcyjnej aplikacji
Architektura:
Docker Secret
|
↓
Application
|
-----------------------
| |
Database API Key
Aplikacja nie zna sekretów zapisanych w:
- Git,
- Dockerfile,
- Compose.
Docker Secrets vs ENV Variables
| Cecha | ENV | Docker Secrets |
|---|---|---|
| Widoczne przez inspect | Tak | Nie |
| W repozytorium | Często | Nie |
| Rotacja | trudniejsza | łatwiejsza |
| Kontrola dostępu | słaba | lepsza |
| Produkcja | odradzane | zalecane |
Docker Secrets i Kubernetes Secrets
Koncepcja jest bardzo podobna.
Docker:
/run/secrets/password
Kubernetes:
Secret Object
↓
Volume Mount
Przykład Kubernetes:
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
Docker Secrets a HashiCorp Vault
W większych organizacjach Docker Secrets może być niewystarczający.
Często stosuje się:
HashiCorp Vault.
Schemat:
id="k0q5v1"
Vault
↓
Dynamic Secret
↓
Docker Container
Zalety:
- automatyczna rotacja,
- audyt dostępu,
- krótkotrwałe tokeny.

Rotacja sekretów
Dobre praktyki:
Nie zmieniamy:
database_password
w miejscu.
Lepszy proces:
id="m4r8wz"
db_password_v1
↓
db_password_v2
↓
Update container
↓
Remove old secret
Przykład rotacji
Nowy sekret:
echo "NewPassword" | docker secret create db_password_v2 -
Aktualizacja usługi:
docker service update \
--secret-rm db_password \
--secret-add db_password_v2 \
database
Docker Secrets i CI/CD
Sekrety nie powinny być w:
❌ GitHub repository
❌ Dockerfile
❌ docker-compose.yml
❌ obrazie Docker
Lepszy model:
Developer
↓
Git Repository
↓
CI/CD Secret Store
↓
Build
↓
Deploy
↓
Docker Secret
Docker Secrets w GitHub Actions
Przykład:
env:
DATABASE_PASSWORD:
${{ secrets.DB_PASSWORD }}
Pipeline pobiera sekret dopiero podczas wykonania.
Najczęstsze błędy
1. Sekrety w Dockerfile
Źle:
ENV API_KEY=123456
Dlaczego?
Warstwa obrazu zostaje na zawsze.
2. Sekrety w repozytorium
Źle:
config.yaml
password=admin123
Nawet po usunięciu:
Git może zachować historię.
3. Logowanie sekretów
Błąd:
print(database_password)
Efekt:
log systemu
↓
hasło
4. Jeden sekret dla wszystkiego
Źle:
MASTER_PASSWORD
↓
wszystkie usługi
Lepsze:
app_database_password
api_token
smtp_password
Docker Secrets i zasada Least Privilege
Każda usługa powinna dostać tylko swoje sekrety.
Złe:
Frontend
↓
wszystkie sekrety
Dobre:
Frontend
↓
brak sekretów
API
↓
API_KEY
Database
↓
DB_PASSWORD
Audyt Docker Secrets
Warto sprawdzić:
docker secret ls
oraz:
docker service inspect service_name
Kontrola:
- kto ma dostęp,
- czy sekrety są używane,
- czy stare zostały usunięte.
Docker Secrets w bezpiecznej architekturze
Profesjonalne środowisko:
Secret Management
|
Docker Secrets
|
Docker Compose/Swarm
|
---------------------------------
App Database Worker
|
Seccomp/AppArmor
|
Linux Kernel
Najlepsze praktyki Docker Secrets
✅ nigdy nie zapisuj haseł w obrazach
✅ nie trzymaj sekretów w Git
✅ używaj osobnych sekretów dla usług
✅ rotuj klucze okresowo
✅ ogranicz dostęp do Docker API
✅ loguj dostęp administracyjny
✅ stosuj Vault przy dużej skali
✅ łącz z CI/CD Secret Management
Podsumowanie
Docker Secrets to jeden z podstawowych elementów bezpiecznej architektury kontenerowej.
Sam Docker nie jest problemem bezpieczeństwa – problemem jest sposób zarządzania danymi dostępowymi.
Dobrze zaprojektowane środowisko powinno wyglądać tak:
Kod aplikacji
↓
BuildKit
↓
Multi-stage Build
↓
Image
↓
Docker Secrets
↓
Runtime
↓
Monitoring + Audyt
Sekrety powinny żyć osobno od aplikacji. Kontener powinien otrzymać tylko to, czego potrzebuje i tylko na czas, kiedy faktycznie tego potrzebuje. To jest fundament podejścia Secret Management oraz Least Privilege w nowoczesnych środowiskach DevSecOps.






