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
Related reading
Homelab Documentation: Wiki.js vs BookStack for Self-Hosted Wikis
Document your homelab setup with self-hosted wikis. Compare Wiki.js and BookStack for creating searchable documentation of your infrastructure and procedures.
Docker Security Scanning: Trivy and Dockle for Safe Containers
Scan your Docker images for vulnerabilities before deploying. Learn to use Trivy and Dockle to secure your self-hosted homelab container infrastructure.
Docker Compose Reverse Proxy: Traefik vs Nginx Proxy Manager
Set up a reverse proxy for your homelab. Compare Traefik and Nginx Proxy Manager for automatic SSL, domain routing, and secure access to self-hosted services.

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.txtMethod 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