Turn insights into action: Bitwarden Access Intelligence now available Find out more >

Bitwarden Resources

Docker container security: A layered approach from build to runtime

Docker container security works best as a layered workflow rather than a single control. This guide breaks down what to control at each layer.

Docker container security works best as a layered workflow rather than a single control. Effective protection spans the entire container lifecycle, from image creation and least-privilege controls to secrets management, network segmentation, and continuous verification. Strengthening one layer while leaving others unaddressed still leaves gaps.

This guide breaks down what to control at each layer, with the exact commands and flags to apply.

Docker container security best practices: Workflow overview

How to secure the Docker image and build process

The image build process is the foundation of Docker container security. Image creation decisions directly shape runtime risk, patching complexity, and supply chain security.

Use minimal trusted base images and pin by digest. Start with the smallest trusted base image that meets application requirements. Slim distributions and distroless images reduce the attack surface by eliminating unnecessary packages and utilities. Pin images by digest rather than tag so future tag changes cannot silently introduce unreviewed code:

FROM debian:12-slim@sha256:7d3f4f...

Multi-stage builds add another layer of protection by excluding build tools and temporary artifacts from the final production image.

Scan images before they reach production. Docker container scanning should run automatically in continuous integration and delivery (CI/CD) pipelines, catching vulnerable packages early and keeping remediation costs low. This Trivy configuration fails the build on high or critical severity findings:

trivy image --exit-code 1 --severity HIGH,CRITICAL myimage:latest

Sign images and generate an SBOM. Image signing establishes provenance, and an SBOM adds visibility into dependencies. Sign an image with Cosign:

cosign sign myregistry/myimage:latest

Generate an SBOM with Syft:

syft scan myregistry/myimage:latest

Together, image signing and SBOM generation validate software provenance, support audits, and strengthen supply chain security before images reach production.

Image signing and SBOM generation validate software provenance and strengthen supply chain security before images ever reach production.


How to enforce least privilege in Docker containers

A hardened image is a strong starting point, and runtime privileges determine how contained a workload stays if something goes wrong. Container hardening through least privilege keeps that scope as narrow as possible.

Remove default root access with non-root users and rootless mode. Non-root containers should be the default whenever possible. The USER directive keeps applications off default root permissions inside the container:

USER 1000:1000

Reserve --privileged for cases that truly require it, since it grants broad access to host resources. Teams with compatible workloads should also evaluate rootless Docker, which reduces the need for host-level privileges.

Drop Linux capabilities and set no-new-privileges. Most containers don't need the full set of Linux capabilities available by default. Start by dropping all capabilities and adding back only what the application needs:

docker run \

 --cap-drop=ALL \

 --security-opt no-new-privileges:true \

 myimage

This prevents processes from gaining additional privileges during execution and more tightly contains workloads.

Restrict syscalls with seccomp and apply AppArmor or SELinux. The default Docker seccomp profile blocks many high-risk system calls and should remain enabled unless a workload has a documented requirement to the contrary. In higher-risk environments, AppArmor or SELinux policies provide enforcement for filesystem access, process behavior, and resource usage. Test these controls carefully, since some applications depend on operations they restrict.

Use read-only filesystems with explicit writable paths. Many applications only need write access to a small number of directories. Running containers with a read-only root filesystem restricts what can change at runtime:

docker run \

 --read-only \

 --tmpfs /tmp \

 myimage

Test framework-specific behaviors, such as temporary file creation, caching, or logging, before rollout to confirm that required writable paths remain available.

How to handle secrets in Docker without leaking credentials

Least privilege narrows what a container can do once it's running. Docker secrets handling determines what it can expose before that even matters.

Secrets should never live in images, Dockerfiles, build arguments, or long-lived environment variables. Once credentials are entered into image layers, they're difficult to remove and can persist in registries, caches, and build artifacts.

Keep credentials out of Dockerfiles and image history. Build-time secrets should use BuildKit secret mounts rather than ARG or ENV directives, both of which expose credentials through image history.

Less secure:

ARG API_TOKEN

ENV API_TOKEN=$API_TOKEN

Preferred:

RUN --mount=type=secret,id=token \

   export TOKEN=$(cat /run/secrets/token)

Production environments benefit from programmatic access to secrets rather than embedding credentials in build workflows.

Inject, rotate, and scope secrets at runtime. Keeping secrets out of images handles the build side; runtime injection covers the rest. External secret stores simplify credential rotation and scope access by workload. An application service should receive only the database credentials it needs, while an internal API service receives a separate, scoped credential set. Runtime injection with secure terminal access and a developer security API narrows credential exposure without slowing down delivery.

How to lock down internal services and container networking

Well-scoped credentials keep an affected secret from reaching far. Network configuration determines what is even in reach to begin with, and internal service exposure remains one of the more common gaps in Docker container security.

Containers should communicate over user-defined networks with only the necessary services reachable from each layer.

Segment frontend and backend traffic paths. Use separate networks for public-facing and internal services. In Compose, the database should be reachable only from the application tier, with no unnecessary published ports:

services:

 web:

   image: web:latest

   ports:

     - "443:443"

   networks:

     - frontend

     - backend


 db:

   image: postgres:16

   networks:

     - backend


networks:

 frontend:

 backend:

   internal: true

Restrict port exposure for admin and data services. Avoid relying on the default bridge network in production. Bind administrative ports to localhost when host access is required, and skip publishing ports that only internal services need.

Authenticate service-to-service traffic, not just network access. Network segmentation limits reachability but doesn't authenticate traffic. Mutual Transport Layer Security (mTLS) or signed service tokens add a layer that prevents one affected container from freely calling neighboring services.


How to verify Docker container security continuously

Segmentation, least privilege, and secrets hygiene reduce the attack surface, but the environment keeps changing. New CVEs surface, configurations drift, and images age. Verification works best as an ongoing practice rather than a one-time deployment check.

Schedule recurring scans as new CVEs emerge. Run Docker container scanning on a recurring cadence, not only during the initial build. Registry scans should run daily or weekly, and teams should rebuild images as soon as upstream base-image vulnerabilities surface:

trivy image --exit-code 1 --severity HIGH,CRITICAL myregistry/myimage:latest

Teams can also benchmark their practices against established standards such as the Center for Internet Security (CIS) Docker Benchmark.

Review daemon and host risk regularly. Container risk also depends on the host and Docker daemon configuration. Run docker-bench-security or CIS Docker Benchmark checks on a schedule, then review those findings alongside image CVEs and runtime alerts:

docker run --net host --pid host --userns host --cap-add audit_control \

 -v /etc:/etc:ro \

 -v /usr/bin/containerd:/usr/bin/containerd:ro \

 docker/docker-bench-security

Recurring scans, benchmark checks, and runtime alerts together provide teams with a complete, up-to-date view of Docker container security posture. For self-hosted deployments, a Docker deployment guide can help align operational setup with these practices.

Recurring scans, benchmark checks, and runtime alerts together provide teams with a complete, up-to-date view of Docker container security posture.

How Bitwarden Secrets Manager supports Docker container security

Verification catches issues across the stack, but the secrets layer covered earlier still needs a dedicated system. Bitwarden Secrets Manager strengthens the secrets management layer of Docker container security, reducing credential exposure across builds and runtime environments. Teams can centralize sensitive values, scope access by workload, and retrieve secrets programmatically through SDKs, command-line interface (CLI) workflows, or API-driven automation.

For DevOps teams, that means fewer hardcoded secrets, less credential reuse across services, and a cleaner rotation process as applications evolve. Developers never need to manually pass credentials via Dockerfiles, build arguments, or long-lived environment variables.

Fewer hardcoded secrets, less credential reuse, and a cleaner rotation process as applications evolve — without developers passing credentials manually through Dockerfiles or environment variables.

Start using Bitwarden Secrets Manager to remove credentials from Dockerfiles, build arguments, and environment variables for good.

Frequently asked questions

What is Docker container security?

Docker container security covers the practices, tools, and configurations that protect containerized applications across the build, deployment, and runtime stages. That includes image integrity, least privilege, secrets handling, network segmentation, and ongoing verification.

What are the most important Docker container security best practices?

Pin base images by digest, run containers as non-root users, drop unnecessary Linux capabilities, keep secrets out of image layers using BuildKit secret mounts, segment container networks, and scan images continuously for common vulnerabilities and exposures (CVEs).

How does Docker container scanning work?

Scanning tools like Trivy inspect image layers for known vulnerabilities. They can automatically fail a build when high- or critical-severity issues are detected, catching risk before it reaches production.

What is rootless Docker?

Rootless Docker runs the Docker daemon and containers without root privileges on the host, reducing the potential impact if a container is affected and limiting host-level privilege requirements.

How should secrets be managed in Docker?

Keep credentials out of build-time artifacts and image history by using BuildKit secret mounts instead of ARG or ENV directives. External secret managers, such as Bitwarden Secrets Manager, then handle scoped, rotatable access at runtime.

What is an SBOM, and why does it matter for container security?

A software bill of materials (SBOM) lists the dependencies and components inside a container image. It gives teams visibility for audits, vulnerability tracking, and supply chain verification, and tools like Syft can generate one automatically as part of the build pipeline.

Get powerful, trusted password security now. Pick your plan.