Titkok kezelése Dockerben: jelszavak és API-kulcsok biztonságosan
Soha ne süsd bele a jelszavakat az image-be! Megnézzük az environment változók buktatóit, a Docker secrets-et, a build secrets-et és a .env fájlok helyes használatát.
Szinte minden valós alkalmazásnak szüksége van titkokra: adatbázis-jelszóra, API-kulcsra, tokenekre, privát kulcsokra. A kérdés nem az, hogy vannak-e titkaid, hanem hogy hogyan kezeled őket. Ez az a terület, ahol nagyon könnyű hibázni, és a hibák költségesek lehetnek — egy publikus registry-be feltöltött image-ben felejtett API-kulcs órákon belül vissza is élhet vele valaki. Ebben a cikkben végigvesszük, miért veszélyes a titkokat az image-be sütni, milyen buktatói vannak az environment változóknak, és milyen biztonságos megoldások közül választhatsz.
Miért ne süsd bele a titkokat az image-be?
A legrosszabb, amit tehetsz, hogy a titkot közvetlenül a Dockerfile-ba írod:
# SOHA ne csináld ezt!
ENV DB_PASSWORD=szupertitkos123
RUN curl -H "Authorization: Bearer abc123token" https://api.pelda.hu/setup
A probléma alapvető és nem megkerülhető: a Docker image rétegekből áll, és minden réteg megőrzi a tartalmát. Még ha egy későbbi rétegben “törlöd” is a titkot, az ott marad egy korábbi rétegben. Bárki, aki hozzáfér az image-hez, ki tudja nyerni:
docker history --no-trunc myapp:latest
docker save myapp:latest | tar -xf -
A docker history megmutathatja az ENV és RUN sorokat a beégetett értékekkel, a docker save pedig kicsomagolja a teljes réteg-tartalmat. Ha az image bekerül egy publikus vagy megosztott registry-be, a titok gyakorlatilag nyilvános.
⚠️ Figyelem: Egy image-be sütött titkot nem lehet “visszavonni” azzal, hogy építesz egy újabb verziót. Ha egyszer kiszivárgott, a titkot magát kell lecserélned (rotálnod) — a jelszót, a kulcsot, a tokent.
Az environment változók buktatói
Sokan az ENV helyett futásidejű környezeti változókra váltanak, ami már jobb, de nem hibátlan:
docker run -e DB_PASSWORD=szupertitkos123 myapp
Ez nem kerül bele az image rétegeibe, de így is van néhány szivárgási kockázat:
- A környezeti változók láthatók a
docker inspectkimenetében bárki számára, aki hozzáfér a daemonhoz. - A folyamatok
/proc/<pid>/environfájljából kiolvashatók a konténeren belül. - Gyakran bekerülnek a logokba, hibajelentésekbe, crash dumpokba.
- A parancssorban (
-ekapcsoló) megjelennek a shell history-ban és a futó folyamatok listájában.
Az environment változók tehát kényelmesek, de nem ideálisak igazán érzékeny titkokhoz. Konfigurációhoz (pl. LOG_LEVEL, PORT) tökéletesek, de jelszavakhoz és kulcsokhoz érdemes robusztusabb megoldást keresni.
.env fájlok Compose-szal
Fejlesztés közben kényelmes a titkokat egy .env fájlban tartani, amit a Docker Compose automatikusan beolvas:
# .env
POSTGRES_PASSWORD=fejlesztoi_jelszo
API_KEY=helyi_teszt_kulcs
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
A legfontosabb szabály: a .env fájl soha ne kerüljön verziókezelésbe. Mindig vedd fel a .gitignore-ba és a .dockerignore-ba is:
# .gitignore és .dockerignore
.env
*.env
💡 Tipp: A
.envfájl remek fejlesztői kényelmi megoldás, de éles környezetben gyenge. Ott válts valódi secret-kezelésre — Docker secrets vagy külső titokkezelő. A Compose alapokhoz nézd meg a Docker Compose bevezető cikket.
Docker secrets
A Docker secrets mechanizmus a titkokat nem környezeti változóként, hanem fájlként teszi elérhetővé a konténer számára, jellemzően a /run/secrets/ könyvtárban. Ez kikerüli az environment változók legtöbb szivárgási kockázatát. Compose-ban így néz ki:
services:
app:
image: myapp:latest
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txt
A konténerben az alkalmazás a /run/secrets/db_password fájlból olvassa ki az értéket. Mivel ez fájl, nem szerepel a docker inspect környezeti változói között, és nem szivárog be olyan könnyen a logokba. Sok hivatalos image (például a postgres) támogatja a _FILE utótagú változatot, amely közvetlenül egy fájlból olvas:
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txt
Docker Swarm módban a secrets ráadásul titkosítva tárolódik és titkosított csatornán jut el a node-okhoz, ami éles környezetben jelentős előny.
BuildKit build secrets
Mi van akkor, ha a build során van szükséged egy titokra — például egy privát csomagregisztrációhoz kell egy token, de nem akarod, hogy az bekerüljön az image-be? Erre való a BuildKit build secrets. A titok csak az adott RUN lépés idejére, memóriában érhető el, és nem kerül bele egyetlen rétegbe sem.
A Dockerfile-ban a RUN --mount=type=secret szintaxist használod:
# syntax=docker/dockerfile:1
FROM alpine:3.20
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) && \
echo "Token használata a buildhez..." && \
# itt használod a tokent, pl. privát csomag letöltéséhez
true
A buildet pedig a --secret kapcsolóval indítod:
docker build --secret id=npm_token,src=./npm_token.txt -t myapp .
A titok így átmenetileg felcsatolódik a /run/secrets/npm_token útvonalra a build alatt, de a kész image-ben semmi nyoma. Ellenőrizheted is: a docker history nem fogja megmutatni. Ez a build során használt titkok kezelésének helyes módja.
💡 Tipp: A
# syntax=docker/dockerfile:1sor a Dockerfile elején biztosítja, hogy a modern BuildKit szintaxis (köztük a--mount=type=secret) elérhető legyen. A Docker Engine 23+ alapból BuildKit-tel buildel.
Külső titokkezelők
Nagyobb, éles rendszerekben érdemes dedikált titokkezelőt használni, amely központilag tárolja, titkosítja, auditálja és rotálja a titkokat. A leggyakoribbak:
- HashiCorp Vault — sokoldalú, dinamikus titkokkal és szigorú hozzáférés-szabályozással.
- AWS Secrets Manager / GCP Secret Manager / Azure Key Vault — felhőszolgáltatói megoldások, mély integrációval.
- Kubernetes Secrets (külső kezelővel kombinálva) — ha Kubernetesen futtatsz.
Ezek lényege, hogy a titok soha nem kerül se az image-be, se a verziókezelésbe; az alkalmazás futásidőben, hitelesítve kéri le a titokkezelőtől. Cserébe a titkokat egy helyen kezeled, könnyen rotálod, és pontosan tudod, ki mikor fért hozzá.
Összefoglalás
A titokkezelés aranyszabálya egyszerű: soha ne süsd bele a titkokat az image-be, mert a rétegek megőrzik őket. Az environment változók kényelmesek, de szivárognak (inspect, logok, /proc), ezért érzékeny adathoz csak óvatosan. Fejlesztéshez használj .env fájlt, amit kihagysz a verziókezelésből; futás közben Docker secrets-et fájl alapú átadással; buildhez BuildKit build secrets-et a --secret és RUN --mount=type=secret párossal; éles, nagyobb rendszerekben pedig dedikált titokkezelőt.
Nézd át a saját Dockerfile-jaidat és Compose fájljaidat még ma — keress beégetett jelszavakat és kulcsokat, és cseréld le őket biztonságos megoldásra! A tágabb képhez olvasd el a Docker biztonsági alapok cikket, és ha a Dockerfile felépítését csiszolnád, a Dockerfile írása lépésről lépésre útmutató segít.