Back to Blog

Docker Compose Secrets: Secure Your Self-Hosted Services

Learn to manage secrets in Docker Compose securely. Best practices for passwords, API keys, and sensitive configuration in your homelab containers.

Posted by

Docker Compose secrets management

The Secrets Problem

Hardcoding passwords in docker-compose.yml is a security risk. If you commit that file to git or share your configuration, your secrets are exposed. Let's fix that.

Method 1: Environment Files

The simplest approach - store secrets in a .env file:

# .env file (add to .gitignore!)
POSTGRES_PASSWORD=super_secret_password_123
REDIS_PASSWORD=another_secret
JWT_SECRET=your_jwt_signing_key

# docker-compose.yml
services:
  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}

Always add .env to your .gitignore!

Method 2: Docker Secrets

More secure - secrets are stored encrypted and mounted as files:

# Create secret files
echo "my_password" > ./secrets/db_password.txt

# docker-compose.yml
version: "3.8"
services:
  db:
    image: postgres:15
    secrets:
      - db_password
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

Method 3: External Secret Managers

For advanced setups, use dedicated secret managers:

  • HashiCorp Vault: Enterprise-grade secret management
  • Infisical: Open-source, great for teams
  • SOPS: Encrypt secrets in git

Security Best Practices

  • Never commit secrets to version control
  • Use strong, unique passwords for each service
  • Rotate secrets periodically
  • Limit secret access to necessary containers only
  • Use _FILE suffix for container-native secret support

Generate Strong Secrets

# Generate random password
openssl rand -base64 32

# Generate multiple secrets at once
for secret in db_pass redis_pass jwt_secret; do
  openssl rand -base64 32 > ./secrets/${secret}.txt
done

Continue Reading