Docker Secrets Management
Securely manage secrets and credentials in Docker containers.
By EMEPublished: February 20, 2025
dockersecretssecurityenvironment variablescredentials
A Simple Analogy
Docker secrets are like a safe for sensitive data. They're stored securely and only given to containers that need them.
Why Secrets?
- Security: Don't hardcode credentials
- Access control: Grant to specific services
- Rotation: Change secrets easily
- Audit: Track secret access
- Compliance: Meet security standards
Environment Variables
# Dockerfile - NOT RECOMMENDED for secrets
FROM node:18-alpine
ENV DB_HOST=localhost
ENV DB_PORT=5432
# Never put secrets here - they're visible in image
WORKDIR /app
COPY . .
CMD ["node", "app.js"]
.env Files
# .env (local development only)
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=securepass
API_KEY=sk_test_1234567890
# .dockerignore
.env
.env.local
// Load environment variables
require('dotenv').config();
const dbConfig = {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD
};
Docker Compose Secrets
version: '3.8'
services:
app:
image: myapp:latest
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
API_KEY_FILE: /run/secrets/api_key
secrets:
- db_password
- api_key
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- postgres_data:/var/lib/postgresql/data
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
file: ./secrets/api_key.txt
volumes:
postgres_data:
Reading Secrets in Code
// Read secret from file
const fs = require('fs');
function getSecret(secretName) {
try {
return fs.readFileSync(`/run/secrets/${secretName}`, 'utf8').trim();
} catch (err) {
console.error(`Secret not found: ${secretName}`);
return null;
}
}
const dbPassword = getSecret('db_password');
const apiKey = getSecret('api_key');
Docker Swarm Secrets
# Create secret
echo "supersecretpassword" | docker secret create db_password -
# Create service with secret
docker service create \
--name myapp \
--secret db_password \
-e DB_PASSWORD_FILE=/run/secrets/db_password \
myapp:latest
# List secrets
docker secret ls
# Remove secret
docker secret rm db_password
Vault Integration
# Store secrets in Vault
vault kv put secret/myapp/db \
password=supersecret \
username=admin
# Retrieve in application
curl --header "X-Vault-Token: s.XXXXXXXXXXXXXX" \
http://127.0.0.1:8200/v1/secret/data/myapp/db
Best Practices
- Never commit secrets: Add to .gitignore
- Use secret management: Vault, AWS Secrets Manager
- Rotate regularly: Change secrets periodically
- Least privilege: Grant minimal access
- Audit access: Monitor who accesses secrets
Related Concepts
- Vault and HashiCorp
- AWS Secrets Manager
- Kubernetes secrets
- Key rotation
Summary
Manage Docker secrets through environment files, Docker Secrets, or external vaults. Never hardcode credentials in images or repositories.