Skip to content
Ercan Ermis
Ercan Ermis

notes for everyone about cloud technology

  • Cloud
    • AWS
    • GCP
  • Container
    • Kubernetes
    • Docker
  • Linux
  • DevOps
  • Privacy Policy
  • Contact
Ercan Ermis

notes for everyone about cloud technology

Securing Docker Containers: Best Practices for Container Security

Ercan, September 20, 2024September 27, 2024

When we talk about containerization, Docker is often the first tool that comes to mind. It’s revolutionized how we develop, ship, and deploy applications. But with great power comes great responsibility, right? As much as Docker can streamline processes, security should always be top of mind. A vulnerable container can put your whole system at risk.

So, how do you secure your Docker containers? Let’s break it down with some best practices!


1. Keep Your Docker Engine Updated

It sounds basic, but you’d be surprised how often this is overlooked. Docker regularly releases updates, patching vulnerabilities and introducing security features. Running outdated versions of Docker leaves you exposed to known exploits.

Tip: Set up automatic notifications or version checks to stay on top of new releases.


2. Minimize the Attack Surface with Lightweight Base Images

The bigger the image, the bigger the risk. Large images with unnecessary tools increase your attack surface. Stick with minimal base images like alpine or scratch, and only add what’s necessary for your application to run.

Example:

FROM alpine:3.12

This small, lightweight image minimizes unnecessary packages, reducing vulnerabilities.


3. Use Multi-Stage Builds

Multi-stage builds allow you to separate the build environment from the final image, meaning you only include what’s essential in your final Docker image.

Here’s a quick example:

Stage 1 – Build the app

FROM golang:alpine as builder
WORKDIR /app
COPY . .
RUN go build -o myapp

Stage 2 – Use a lightweight image for the final stage

FROM scratch
COPY –from=builder /app/myapp /app/myapp
ENTRYPOINT [“/app/myapp”]

Notice how the second stage is using scratch? This creates a smaller, more secure image by excluding unnecessary build dependencies.


4. Set User Permissions

By default, Docker containers run as root. Big no-no! Running as root gives an attacker unnecessary privileges if they manage to exploit your container. Always run your container processes as a non-root user.

Example:

# Add user and switch to it
RUN useradd -m nonrootuser
USER nonrootuser

This simple tweak can prevent privilege escalation attacks.


5. Limit Container Capabilities

Containers don’t need full privileges to do their job. Docker has Linux capabilities by default, but you can strip them down to the bare minimum. Use the --cap-drop flag to drop unnecessary privileges.

Example:

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE myapp

Here, we drop all capabilities except for NET_BIND_SERVICE, which is necessary to bind to network ports below 1024.


6. Scan Images for Vulnerabilities

Docker Hub images are great, but they’re not always secure. Vulnerabilities can sneak in. Regularly scan your images using tools like:

  • Clair (by CoreOS)
  • Anchore
  • Trivy (from Aqua Security)

Trivy is an excellent, lightweight tool for scanning images. You can integrate it into your CI/CD pipeline to ensure every image is secure.

Example:

trivy image myapp:latest

7. Enable Docker Content Trust (DCT)

Docker Content Trust (DCT) ensures the integrity and authenticity of the images you pull. It uses digital signatures to verify the source of the image. With DCT enabled, you can’t pull unsigned or tampered images.

To enable Docker Content Trust, simply set the environment variable:

export DOCKER_CONTENT_TRUST=1

8. Use Read-Only File Systems

If your application doesn’t need to write to the filesystem, make it read-only! This reduces the ability for an attacker to modify files if they gain access to the container.

Example:

docker run --read-only myapp

9. Limit Network Exposure

By default, containers are networked and reachable. But do they need to be? Avoid publishing unnecessary ports, and consider using Docker’s network namespaces or private Docker networks for internal communications.

Example:

docker run -d --network my-priv-network myapp

In this case, you’re isolating your container to a private network, limiting exposure to external threats.


10. Enable Logging and Monitoring

Log everything! Tools like Falco, Prometheus, and Grafana can help you monitor container activity and detect unusual behavior in real-time.

Tip: Combine monitoring with alerting. It’s not enough to log – you need to know when something suspicious happens.


11. Use Secrets Management Tools

Storing sensitive data (like API keys or passwords) directly in your container is a bad practice. Use secrets management tools like Docker Secrets, Vault, or AWS Secrets Manager to handle secrets securely.

Example (Docker Secrets):

echo "my-secret-password" | docker secret create db_password -

Then, in your Docker Compose file:

version: "3.1"
services:
  db:
    image: mysql
    secrets:
      - db_password
secrets:
  db_password:
    external: true

12. Regularly Update Your Dependencies

It’s not just your base image that needs updates – don’t forget about your application’s dependencies. Regularly update and patch your libraries and tools to avoid being compromised by known vulnerabilities.

Tip: Use Dependabot or similar tools to automatically check for updates in your dependencies.


Wrapping Up

Securing Docker containers isn’t just a “set it and forget it” task. It’s an ongoing process that requires continuous monitoring, regular updates, and a security-first mindset. By following these best practices, you can dramatically reduce the risk of vulnerabilities while taking advantage of all the benefits Docker has to offer.

The security landscape is constantly evolving, and keeping up with the latest recommendations and tools is key to staying protected. If you’ve got any more tips or questions about container security, feel free to share — we’re all in this containerized world together! 🚀

Share on Social Media
x facebook linkedin reddit
Docker

Post navigation

Previous post
Next post
  • AWS (45)
    • Serverless (4)
  • Best (9)
  • DevOps (16)
  • Docker (10)
  • GCP (3)
  • Kubernetes (3)
  • Linux (13)
  • Uncategorized (6)

Recent Posts

  • Automating AWS CloudWatch Log Group Tagging with Python and Boto3
  • Automating AWS ECR Tagging with Python and Boto3
  • Automating ECR Image Cleanup with Bash
  • Update ECR Repositories with Bash Script
  • Why Automated Tests Are Essential in Your CI/CD Pipeline and Development Flow
  • Streamline Your AWS ECR Management with This Powerful Bash Script
  • Setting up DKIM for Google Workspace (Gmail) using Terraform and AWS Route 53
  • Automate AWS Site-to-Site VPN Monitoring
  • Optimizing Docker Images: Tips for Reducing Image Size and Build Time
  • Monitoring EC2 Disk Space with a Simple Bash Script and Slack Alerts
  • Securing Docker Containers: Best Practices for Container Security
  • Mastering Dockerfile: Writing Efficient, Scalable Container Builds
  • Migrating a Git Repository from GitLab to GitHub with GPG-Signed Commits
  • Accessing AWS Services in Private Subnets Without 0.0.0.0/0
  • Understanding AWS Regions, Availability Zones, and VPCs: A Comprehensive Guide
©2025 Ercan Ermis | WordPress Theme by SuperbThemes