Secure Your Passwords in 5 Minutes with Docker Secrets
You probably don’t want your database password showing up plainly in the system logs, right? Never throw API keys directly into the environment section of your docker-compose.yml file. Instead, use Docker Secrets to properly secure them, starting from your local environment.
Step 1: Create a file containing the password (e.g., db_password.txt). Remember to add this file to .gitignore immediately to avoid pushing it to public servers.
echo "my-super-secret-password" > db_password.txt
Step 2: Declaring secrets in docker-compose.yml is extremely simple:
services:
db:
image: postgres
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./db_password.txt
Step 3: Run the command docker compose up -d and you’re done. Your password is now securely located at /run/secrets/db_password. If someone curiously runs docker inspect, they will only see a blank space instead of the actual password.
Environment Variables: A Bigger Loophole Than You Think
The truth is, with just one docker inspect <container_id> command, all your secrets will be visible to colleagues or anyone with server access. I’ve witnessed a system where all sensitive information was leaked because these environment variables were overwritten into the logs of a centralized monitoring tool.
Docker Secrets completely solves this problem through the following mechanisms:
- Stored in RAM: In Docker Swarm, secrets are stored in an encrypted Raft log and only mounted into the container’s RAM (tmpfs) when needed. Data never touches the hard drive.
- Access Control: Only specifically designated services have the right to ‘see’ that secret.
- Centralized Management: Easily deploy the same configuration across multiple environments without worrying about mixing up data between Dev and Prod.
Actual Operating Mechanism
When you attach a secret to a service, Docker mounts it as a file in the /run/secrets/ directory inside the container. Most major images like MariaDB, Postgres, or WordPress have a built-in _FILE suffix option. This allows the application to read data directly from the file instead of from a standard environment variable.
Level Up Security with Docker Swarm
If you are operating a cluster with Docker Swarm, secret management becomes even more professional. All sensitive data is synchronized between Manager nodes via an encrypted mTLS channel with high security.
Pushing Secrets Directly from the CLI
You don’t need to create a physical file on the server. Push the value directly into Swarm’s database with a single command:
echo "serect_key_2024" | docker secret create api_key -
Deploying with Stack Deploy
In the stack.yml file, use the external keyword to leverage secrets that already exist on the system:
version: '3.8'
services:
app:
image: my-app:latest
secrets:
- api_key
secrets:
api_key:
external: true
Finally, deploy the system with the familiar command: docker stack deploy -c stack.yml my_web_app.
Lessons from the Field
Switching from docker-compose v1 to v2 provides a very smooth experience. In version 2 (using the docker compose command without a hyphen), the secrets feature has become a standard even if you aren’t running Swarm. You no longer need to use complex emulation tricks as before.
Writing More Flexible Code
To ensure the application runs well on both local and production, I often write a small Python function to prioritize reading the secret from a file before checking environment variables:
import os
def get_config(key, default=None):
# Prioritize reading from Docker's secret path
secret_path = f"/run/secrets/{key}"
if os.path.exists(secret_path):
with open(secret_path, 'r') as f:
return f.read().strip()
# Fallback to environment variables if the file is not found
return os.getenv(key, default)
Don’t Let Secrets Expire (Secret Rotation)
Many people have the habit of using a single password for 2-3 years without changing it. With Docker Swarm, secrets are immutable, so you need to create a new version when updating. The standard process is: Create api_key_v2, update the compose file, redeploy so Docker automatically replaces the container, and finally delete api_key_v1 once everything is stable.
Checklist for Better Sleep
- Never commit secret files: Always check
.gitignoreto ensure no.txtor.keyfiles make it into Git. - Use Docker Configs where appropriate: For standard configuration files like
nginx.conf, useconfigsinstead ofsecretsfor optimal performance. - Principle of Least Privilege: A Frontend container must never be allowed to access the database master’s secret.
- Leverage RAM: Remember that in Swarm, secrets reside only in RAM. This protects data even if the physical hard drive of the server is compromised.
Security management isn’t hard; the key is to make it a daily habit. Good luck building systems that are both powerful and secure!

