Isaac.

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

  1. Never commit secrets: Add to .gitignore
  2. Use secret management: Vault, AWS Secrets Manager
  3. Rotate regularly: Change secrets periodically
  4. Least privilege: Grant minimal access
  5. 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.