Docker Secrets
Securely manage sensitive data without exposing it in images or environment variables.
Why Not Environment Variables?
# Problems with env vars:
# 1. Visible in docker inspect
docker inspect container --format '{{json .Config.Env}}'
# 2. Visible in process listings
cat /proc/1/environ
# 3. Often logged accidentallyDocker Compose Secrets
# docker-compose.yml
services:
api:
image: myapi
secrets:
- db_password
- api_key
environment:
# Tell app where to find secrets
DB_PASSWORD_FILE: /run/secrets/db_password
API_KEY_FILE: /run/secrets/api_key
db:
image: postgres:16
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
file: ./secrets/api_key.txtReading Secrets in Application
// Node.js
const fs = require('fs');
function getSecret(name) {
const file = process.env[`${name}_FILE`];
if (file) {
return fs.readFileSync(file, 'utf8').trim();
}
return process.env[name];
}
const dbPassword = getSecret('DB_PASSWORD');# Python
import os
def get_secret(name):
file_path = os.environ.get(f'{name}_FILE')
if file_path:
with open(file_path, 'r') as f:
return f.read().strip()
return os.environ.get(name)
db_password = get_secret('DB_PASSWORD')BuildKit Secrets
For build-time secrets (not stored in image):
# syntax=docker/dockerfile:1
FROM node:20-alpine
# Mount secret at build time
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) \
npm install# Build with secret
DOCKER_BUILDKIT=1 docker build \
--secret id=npm_token,src=./secrets/npm_token.txt \
-t myapp .External Secret Sources
secrets:
# From file
db_password:
file: ./secrets/db_password.txt
# External (pre-existing in Docker)
api_key:
external: true
name: prod-api-key
# From environment (for CI/CD)
jwt_secret:
environment: JWT_SECRETSecrets Directory Structure
secrets/
.gitignore # Ignore everything in this dir
db_password.txt
api_key.txt
jwt_secret.txt# secrets/.gitignore
*
!.gitignore
!*.exampleSecret Rotation
# Create versioned secrets
secrets:
db_password_v2:
file: ./secrets/db_password_v2.txt
services:
db:
secrets:
- source: db_password_v2
target: db_passwordBest Practices
- Never commit secrets - Add to .gitignore
- Use _FILE suffix - Standardize secret file pattern
- Limit access - Only mount where needed
- Rotate regularly - Use versioned secrets
- Encrypt at rest - Use encrypted storage for files
- docker
- secrets
- credentials
- passwords
- security