$docker.recipes
·12 min read·Updated February 2026

Secrets Management for Docker Compose in Production

Move beyond .env files: practical approaches to managing passwords, API keys, and certificates in Docker Compose deployments — from Docker secrets to external vaults.

secretssecuritydocker-composeproductionvault

01Your .env File Is a Liability

Let me be blunt: if your production database password lives in a .env file on the same server as your application, your security posture is weaker than you think. The .env file is readable by anyone with SSH access, it shows up in docker inspect output, and it's one accidental git push away from being public. For personal projects and home labs, .env files are fine. For anything handling real user data or processing payments, you need something better. This guide covers the progression from basic .env files to proper secrets management, with practical Docker Compose examples at each level.

02Level 1: Docker Compose Secrets

Docker Compose supports file-based secrets that are mounted into containers as files in /run/secrets/. The advantage over environment variables: secrets don't appear in docker inspect, process listings, or container logs.
[docker-compose.yml]
1services:
2 db:
3 image: postgres:16-alpine
4 secrets:
5 - db_password
6 - db_user
7 environment:
8 POSTGRES_PASSWORD_FILE: /run/secrets/db_password
9 POSTGRES_USER_FILE: /run/secrets/db_user
10
11 app:
12 image: myapp:latest
13 secrets:
14 - db_password
15 - api_key
16 environment:
17 DB_PASSWORD_FILE: /run/secrets/db_password
18 API_KEY_FILE: /run/secrets/api_key
19
20secrets:
21 db_password:
22 file: ./secrets/db_password.txt
23 db_user:
24 file: ./secrets/db_user.txt
25 api_key:
26 file: ./secrets/api_key.txt

Not all applications support reading secrets from files (_FILE suffix). Check the image documentation. If the app only reads environment variables, you may need a wrapper script that reads the file and sets the variable.

03Level 2: Encrypted Secrets Files

Store your secrets files encrypted at rest using SOPS (Secrets OPerationS) or age encryption. This lets you safely commit encrypted secrets to Git — only someone with the decryption key can read them:
[terminal]
1# Install SOPS and age
2# Create an age key pair
3age-keygen -o key.txt
4
5# Encrypt your secrets directory
6sops --encrypt --age age1... secrets/db_password.txt > secrets/db_password.txt.enc
7
8# Decrypt before deploying
9sops --decrypt secrets/db_password.txt.enc > secrets/db_password.txt
10
11# Or use SOPS exec-env to decrypt into environment
12sops exec-env secrets.enc.yaml 'docker compose up -d'

Store the age private key separately from your repository — ideally in a password manager or hardware security key. The encrypted secrets files can safely live in Git.

04Level 3: HashiCorp Vault

For production deployments managing multiple applications, HashiCorp Vault provides centralized secrets management with access control, audit logging, automatic rotation, and dynamic secrets. Vault itself runs as a Docker container and can be part of your compose stack. Applications retrieve secrets from Vault at runtime rather than reading files or environment variables. The setup cost is higher — Vault needs its own storage backend, initialization, and unsealing. But for teams or production SaaS applications, the security benefits justify the complexity.
[docker-compose.yml]
1services:
2 vault:
3 image: hashicorp/vault:1.17
4 container_name: vault
5 restart: unless-stopped
6 cap_add:
7 - IPC_LOCK
8 volumes:
9 - vault_data:/vault/data
10 - ./vault-config.hcl:/vault/config/config.hcl
11 ports:
12 - "8200:8200"
13 command: server
14
15volumes:
16 vault_data:

05Which Level Do You Need?

Home lab / personal projects: .env files with proper file permissions (chmod 600) and .gitignore rules. Don't overcomplicate it. Small business / side project with users: Docker Compose secrets (file-based). Encrypted secrets files in Git with SOPS if you want version control. Production SaaS / handling sensitive data: HashiCorp Vault or a cloud provider's secrets manager (AWS Secrets Manager, GCP Secret Manager). The audit trail and automatic rotation are essential for compliance. The most important thing isn't which method you choose — it's that you have a method at all. Any secrets management is better than passwords hardcoded in docker-compose.yml files pushed to public GitHub repositories. And yes, I still see that happen regularly. Browse our security category for Vault configurations and other security-focused Docker Compose setups.

About the Author

Frank Pegasus

DevOps engineer and self-hosting enthusiast with over a decade of experience running containerized workloads in production. Creator of docker.recipes.