Using Docker Secrets Properly
What this article covers
- Why secrets need protection in Docker.
- Available options and approaches.
- How Docker Secrets work in Swarm mode.
- Handling
.envfiles securely. - Alternatives like Vault, Infisical, and dotenvx.
Introduction: using Docker Secrets properly
Containers frequently need passwords, API keys, tokens, or certificates. These secrets must never end up in images, build contexts, or version control. Docker provides several mechanisms to protect sensitive data. Understanding the differences helps prevent secrets from leaking through images, logs, or backups.
This article shows how to handle secrets safely in Docker and Compose.
Key terminology
- Secret: Sensitive information such as a password or API key.
- Docker Secret: A secret managed within Swarm.
- Env file: A file containing environment variables.
- Build Secret: A secret available only during the build process.
- Mount: Attaching a secret into a container.
- Vault: A specialized secrets management solution.
- Rotation: Regularly renewing secrets.
- Secret Injection: Providing secrets at runtime.
What to avoid
These practices should be prevented:
- Setting secrets in the Dockerfile using
ENV. - Writing passwords directly in
compose.yaml. - Committing
.envfiles to the repository. - Outputting secrets to logs.
- Pushing images with embedded secrets.
Any of these mistakes can lead to a security incident.
Env files
A .env file is the simplest way to provide environment variables:
services:
app:
image: mein-image
env_file:
- .env
Add .env to .gitignore and back it up or encrypt it regularly.
Compose example with env files
services:
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txt
The password is stored in plaintext in db_password.txt. Keep this file out of the repository.
Docker Secrets in Swarm
In Swarm mode, secrets can be managed centrally:
echo "meinpasswort" | docker secret create db_password -
In Compose:
services:
db:
image: postgres:16
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true
Secrets are then provided as files in /run/secrets/.
Build Secrets
Build Secrets are available only during the build and do not remain in the final image:
# syntax=docker/dockerfile:1.7
FROM python:3.11-slim
RUN --mount=type=secret,id=pipconf \
PIP_CONFIG_FILE=/run/secrets/pipconf \
pip install -r requirements.txt
Build:
docker build --secret id=pipconf,src=./pip.conf .
Preventing secrets in container logs
- Never output secrets in
printorechocommands. - Set the logging level to
INFOor higher. - Scan logs for sensitive patterns.
Alternatives
HashiCorp Vault
Centralized management, dynamic secrets, and rotation.
Infisical
Open-source alternative with strong Docker integration.
dotenvx
Encrypted .env files with a shared key.
Mozilla SOPS
Encrypting secrets files in Git.
Rotation strategy
- Renew secrets regularly.
- Use automated rotation where possible.
- Deactivate old keys before rolling out new ones.
- Establish emergency procedures in case of a suspected leak.
Tips
- Protect
.envfiles on the host. - Principle of least privilege: provide only required secrets to containers.
- Restrict permissions:
chmod 600 .env. - Never store secrets in backups without encryption.
- Maintain an audit trail.
- Use a centralized Vault for larger setups.
Common pitfalls
.envin Git: Anyone with repository access sees secrets.- Secrets in build cache: Build Secrets misconfigured.
- Logs expose secrets: Passwords appear in error messages.
- Wrong permissions:
.envis readable by everyone. - Static Secrets: Passwords are never rotated.
- Container dumps: Memory dumps contain secrets.
Further reading and resources
- BotServ.de Docker Security
- BotServ.de Docker Swarm
- BotServ.de Secret Management
- BotServ.de Mozilla SOPS
- BotServ.de dotenvx
FAQ: Docker Secrets
What are Docker Secrets? Specially managed sensitive values, particularly within Swarm.
Are .env files secure?
Only if they remain local, are protected, and are not committed to Git.
Can I use Secrets in Compose without Swarm?
Yes, by using files in /run/secrets and Bind Mounts.
What is a Build Secret? A secret available only during the build process that does not end up in the final image.
Should I use Vault?
For larger or professional setups, yes. For small home labs, .env files or SOPS are sufficient.
Sources and further reading
- Docker Secrets: https://docs.docker.com/engine/swarm/secrets/
- Docker BuildKit Secrets: https://docs.docker.com/build/building/secrets/
- HashiCorp Vault: https://www.vaultproject.io/
- Infisical: https://infisical.com/
Summary: using Docker Secrets properly
Secrets should never end up in images, repositories, or logs. For simple setups, protected .env files and Swarm Secrets are sufficient. For more demanding requirements, consider Vault, Infisical, or SOPS. Clean permissions, regular rotation, and minimal distribution within containers are essential. By keeping secrets consistently out of the build and runtime context, you significantly reduce the risk of leaks and make container environments much more robust.


