Secrets in containers need special handling. Baking them into images or passing them as plain environment variables creates security risks. Here are the approaches from basic to production-grade.
Environment Variables (Basic)
# Docker run
docker run -e DB_PASSWORD=secret my-app
# Docker Compose
services:
api:
environment:
DB_PASSWORD: secretProblems:
- Visible in docker inspect
- Visible in /proc/PID/environ
- May leak into logs
- Stored in shell history
Slightly Better: .env Files
# .env (gitignored!)
DB_PASSWORD=secret
API_KEY=sk-prod-abc123services:
api:
env_file:
- .envStill visible in docker inspect, but not in compose files or shell history.
Docker Swarm Secrets
Built-in secret management for Docker Swarm:
# Create secret
echo "S3cur3P@ss!" | docker secret create db_password -
# From file
docker secret create tls_cert ./cert.pem
# List
docker secret ls# docker-compose.yml (Swarm mode)
services:
api:
image: my-api
secrets:
- db_password
- api_key
secrets:
db_password:
external: true
api_key:
external: trueInside the container, secrets are mounted as files:
cat /run/secrets/db_password
# S3cur3P@ss!# Read in application
with open("/run/secrets/db_password") as f:
db_password = f.read().strip()Docker Compose Secrets (Non-Swarm)
services:
api:
image: my-api
secrets:
- db_password
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txtMany official images support *_FILE variants that read from file paths instead of env vars.
Master this topic with hands-on labs
Go beyond reading — build real projects in sandboxed environments with expert video guidance.
Browse Courses →Build Secrets (Docker BuildKit)
Pass secrets during build without baking them into image layers:
# syntax=docker/dockerfile:1
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
# Mount secret during build only
RUN --mount=type=secret,id=npm_token \
NPM_TOKEN=$(cat /run/secrets/npm_token) \
npm ci
COPY . .
CMD ["node", "server.js"]DOCKER_BUILDKIT=1 docker build \
--secret id=npm_token,src=$HOME/.npmrc \
-t my-app .The secret is available during build but NOT in the final image. It does not appear in any layer.
Mounted Secret Files
services:
api:
image: my-api
volumes:
- type: bind
source: ./secrets/config.json
target: /app/config/secrets.json
read_only: true# Docker run
docker run -v $(pwd)/secrets/config.json:/app/config/secrets.json:ro my-appExternal Vault Integration
HashiCorp Vault Agent
services:
vault-agent:
image: hashicorp/vault
command: agent -config=/vault/config.hcl
volumes:
- vault-secrets:/vault/secrets
- ./vault-agent.hcl:/vault/config.hcl
api:
image: my-api
volumes:
- vault-secrets:/app/secrets:ro
depends_on:
- vault-agent
volumes:
vault-secrets:AWS Secrets Manager (In Code)
import boto3
import json
def get_secret(name):
client = boto3.client("secretsmanager", region_name="eu-west-1")
response = client.get_secret_value(SecretId=name)
return json.loads(response["SecretString"])
secrets = get_secret("production/api")
db_password = secrets["db_password"]Get weekly IT automation tips
Docker, Ansible, Terraform, MLOps — curated insights delivered to your inbox. No spam.
Subscribe Free →Kubernetes Secrets
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
db-password: UzNjdXIzUEBzcyE= # base64 encoded
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: api
# As environment variable
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: db-password
# Or as mounted file
volumeMounts:
- name: secrets
mountPath: /app/secrets
readOnly: true
volumes:
- name: secrets
secret:
secretName: app-secretsComparison
| Method | Security | Complexity | Best For |
|---|---|---|---|
| Env vars | Low | Low | Development |
| .env files | Low-Medium | Low | Local development |
| Docker secrets (Swarm) | High | Medium | Docker Swarm |
| Compose file secrets | Medium | Low | Docker Compose |
| Build secrets | High | Low | Private packages |
| Mounted files | Medium | Low | Simple deployments |
| Vault | Highest | High | Production |
| K8s Secrets | Medium-High | Medium | Kubernetes |
Best Practices
| Practice | Why |
|---|---|
| Never bake secrets into images | Images are shared and cached |
Use *_FILE variants | Avoid env var exposure |
| Gitignore secret files | Prevent accidental commits |
| Rotate secrets regularly | Limit exposure window |
| Use build secrets for private deps | Not stored in layers |
| Prefer mounted files over env vars | Less exposure surface |
| Encrypt at rest | K8s secrets are base64, not encrypted |
What's Next?
Our Docker Fundamentals course covers secret management in containerized applications. SELinux for System Admins teaches OS-level security. First lessons are free.
---
Ready to go deeper? Check out our hands-on course: Docker Fundamentals — practical exercises you can follow along on your own machine.
Ready to learn by doing?
Stop reading tutorials — start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
Vault Secrets Management Guide
Manage secrets with HashiCorp Vault. KV engine, dynamic credentials, auth methods, policies, and Kubernetes integration patterns.
Sops Encrypted Secrets in Git
SOPS encrypts secret values in YAML, JSON, and dotenv files while keeping keys readable. Learn how to use SOPS with age, AWS KMS, or GCP KMS.
Container Runtime Security Guide
Secure container runtimes in production. Non-root users, read-only filesystems, seccomp profiles, AppArmor, and automated vulnerability scanning.
Docker Tutorial for Beginners 2026
Complete Docker tutorial for beginners. Learn containers, images, Dockerfiles, volumes, networking, and Docker Compose step by step.
Docker Volumes and Persistent Data
Manage persistent data in Docker with named volumes and bind mounts. Backup strategies, restore procedures, and container data sharing.
Domain-Specific AI Models Guide
Build and deploy domain-specific AI models with fine-tuning, RAG, and specialized training data for healthcare, finance, and DevOps applications.
Explore topics
Browse more articles on the topics covered here.