Docker Security Best Practices
Avoid Environment Variables for Sensitive Data & Use a Secret Manager
While the ENV instruction is convenient for configuring application behavior, it should never be used for sensitive information like API keys, database passwords, or private certificates.
Environment variables in Docker are notoriously "leaky" for several reasons: They're visible (docker inspect shows them), they persist in image layers, and they can be inherited by child processes.
In this example, the database password is hardcoded into the image. This password will be visible to anyone who has the image file, even without running it.
# BAD PRACTICE
FROM python:3.9-slim
ENV DB_PASSWORD="super-secret-password-123"
CMD ["python", "app.py"]
If you build this and run docker inspect, the password appears in plain text under the Config.Env section.
The Secure Alternative: Using Docker Secrets or Volume Mounts
The professional approach is to provide sensitive data at runtime using files. This keeps the secret out of the image metadata and out of the process environment list.
Here is an example with Docker Compose using Docker Secrets.
The app code needs to read the secret from a file (standard path for Docker Secrets is ):
# app.py
import os
def get_secret(secret_name):
try:
# Check if running in a container with secrets
with open(f'/run/secrets/{secret_name}', 'r') as f:
return f.read().strip()
except IOError:Painless Docker - 2nd Edition
A Comprehensive Guide to Mastering Docker and its EcosystemEnroll now to unlock all content and receive all future updates for free.
Hurry! This limited time offer ends in:
To redeem this offer, copy the coupon code below and apply it at checkout:
