Best Practices for Handling Secrets in Docker
Managing secrets such as API keys, passwords, and certificates in Docker is critical for secure applications. Hardcoding secrets in images or environment variables can expose sensitive data. This guide explores best practices for handling secrets in Docker with practical examples.

Why Secrets Management Matters
Secrets are sensitive data that grant access to critical systems. If they are leaked, attackers could gain full control over databases, APIs, or production servers. Common mistakes include:
- Storing secrets directly in
Dockerfile. - Committing
.envfiles to Git. - Printing secrets in logs.
Use Docker Secrets (for Swarm Mode)
Docker Swarm provides a built-in way to store secrets safely. Instead of environment variables, secrets are mounted into containers as files.
Example:
version: "3.9"
services:
web:
image: nginx:alpine
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txt
Inside the container, the secret is available at:
/run/secrets/db_password
This way, the password never appears in environment variables or images.
Use Environment Variables Carefully
If you are not using Swarm, environment variables can be used but must be handled with care:
- Never commit
.envfiles to Git. - Use
.gitignoreto exclude them. - Prefer external secret managers (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault).
Example .env file:
DB_USER=admin
DB_PASSWORD=supersecret
Load it safely with:
docker run --env-file .env myapp
Mount Secrets as Files Instead of ENV
Instead of passing secrets via ENV, you can mount them as volumes. This avoids accidental leaks in docker inspect or logs.
Example:
docker run -v /host/path/secret.txt:/run/secrets/db_password myapp
Inside your app, read from /run/secrets/db_password.
Avoid Hardcoding Secrets in Dockerfiles
Never put secrets directly in Dockerfile:
Bad Example
ENV DB_PASSWORD=supersecret
Good Example
Use environment variables or mounted files instead of hardcoding values in image layers.
Rotate and Revoke Secrets
- Use short-lived credentials when possible.
- Rotate database and API keys regularly.
- Revoke unused secrets immediately.
This limits the damage if a secret is compromised
Example: Flask App with Secrets
Imagine a Flask app connecting to MySQL. Instead of hardcoding credentials:
import os
from flask import Flask
import mysql.connector
app = Flask(__name__)
db_user = os.getenv("DB_USER")
db_pass = open("/run/secrets/db_password").read().strip()
@app.route("/")
def hello():
conn = mysql.connector.connect(
host="db", user=db_user, password=db_pass, database="appdb"
)
return "Connected to DB successfully!"
The app reads DB_USER from env and DB_PASSWORD from Docker secrets.
Conclusion
Handling secrets in Docker securely is essential to protect your systems and data. Always avoid hardcoding secrets, prefer Docker secrets or external secret managers, and practice regular rotation. By following these best practices, you minimize the risk of leaks while maintaining a secure containerized environment.
This is the end of the Best Practices for Handling Secrets in Docker.
You can read more useful articles like How to Debug “Connection Refused” Between Docker Compose Services.
Follow us for the more helpful posts!
We hope this is a useful post for you.
Â