Master Container Security in 2025 — Best Practices & Live Demo
By Vladimir Mikhalev · Solutions Architect · Docker Captain · IBM Champion
This is a practical guide to container security. Protecting your applications, securing your supply chain, and staying ahead of new threats.
It’s 2025. The threats are more frequent now, smarter, and they do more damage. Compromised servers and stolen databases used to be the whole story. Not anymore. Container security sits at the center of it. Over 85% of organizations currently run containerized applications in production.
Container adoption keeps growing, and the security risks grow with it. Attackers know this. So every one of us, whether you write code, run security, design systems, or do DevOps, has to take container security seriously.
Here’s what we’ll cover:
- Why container security matters in 2025
- Key best practices that every team should follow
- Practical examples using Docker Scout for local scanning and Snyk for continuous security checks in GitHub Actions.
Time is short. Let’s get into it.
Container Security in 2025
Why does any of this matter in 2025? Look at the architecture. Microservices are everywhere. A single application might be dozens or hundreds of containers, all talking to each other. That blows up your attack surface.
The reason is simple. Every container is its own little environment, with its own OS packages, libraries, and config. One misconfigured container, or one running unpatched software, is enough. That single weakness can turn into a major breach.
Supply chain attacks are climbing too. Attackers stopped going after your code alone. Now they go after whatever you depend on: base images, external libraries, third-party integrations.
Put plainly, the container image itself is a place where things can go wrong. So we have to pay attention to:
- What’s in our base image
- Our runtime environment
- The pipeline that builds and ships these containers
My goal here is to give you a practical way to shift security left. Catch issues early in development, where fixing them is cheap, and bake the checks into the work you already do every day
Key Best Practices in Container Security
So how do you actually secure containers? Below are seven core principles. They apply to Docker, to Kubernetes, and to any containerized setup you run.
1. Use Minimal Base Images
Bigger images carry more dependencies. More dependencies means more for an attacker to chew on. Reach for lightweight images like Alpine or distroless instead of a full Linux distribution whenever you can.
Consider the size. Alpine is around 5 megabytes. Ubuntu or Debian run tens or hundreds of megabytes.
Fewer packages, fewer security risks, smaller attack surface. That’s the whole point.
2. Pin Your Versions
When you pull an image, don’t write this:
FROM python:3Be specific. Like this:
FROM python:3.13.2-alpineThat locks you to a known version and keeps surprise updates from breaking things or sneaking in a vulnerability. And never use latest as a tag. Pull FROM python:latest and you have no idea what you’re actually getting. It can shift under you and break your app.
Worse, an attacker can push a poisoned image under latest, and your system pulls it without anyone noticing.
Pin your versions. Stay in control.
3. Scan Early and Often
Scanning is not a one-and-done step. You scan for risk at every stage:
✅ Development
✅ Staging
✅ Production
Tools like Docker Scout and Snyk handle this for you.
Take Docker Scout. One command scans an image and shows you the risks right there.
Build security into your pipeline on day one. Not as a patch you bolt on at the end.
4. Use Multi-Stage Builds
Leftover dependencies, libraries, and build tools sitting in your container? That’s more surface for an attacker to use.
Multi-stage builds fix this. Build your app in one stage, then copy only what you need into a final, smaller image.
That strips out:
🚫 Debugging tools
🚫 Compilers
🚫 Temporary files
What you’re left with is smaller, cleaner, and harder to attack.
5. Drop Unnecessary Privileges
Containers run as root by default. That’s a big problem. An attacker who takes over a root container can move out across your system.
Run as a non-root user instead. Specify it like this:
USER 1000:1000What does that actually do?
- The first one thousand is the user ID. Just a regular non-root user in Linux.
- The second one thousand is the group ID, which puts it in a restricted group.
Run as a low-privilege user and a break-in stays contained. No system-wide access for whoever got in.
6. Keep Secrets Out of Images
Don’t bake sensitive data into an image. It’s a common mistake, and it leaks your secrets the moment the image gets pulled by the wrong person or shared where it shouldn’t be.
Keep secrets somewhere safe instead:
✅ Environment variables
✅ A secrets manager like AWS Secrets Manager, HashiCorp Vault, or Kubernetes Secrets
And if a secret does get hard-coded by accident, tools like TruffleHog or GitLeaks will catch it before it leaks.
No secrets in images. None in repos. None in logs.
7. Monitor Runtime Behavior
Build-time scanning only gets you so far. You also have to watch what’s actually happening in production.
Falco and Sysdig catch suspicious activity inside running containers.
Here’s a concrete case. Falco can alert you the moment a container starts a shell out of nowhere, which often means someone is now driving it.
Other things to watch for:
🚨 Unexpected file modifications
🚨 High network activity from a container
🚨 Containers trying to escalate privileges
Watch the runtime and you catch threats while they’re still small, before they turn into an incident.
Final Thoughts on Key Best Practices in Container Security
Follow these seven principles and you’re already ahead of plenty of organizations still fumbling container security.
Less is more here. Less complexity, lower privileges, fewer secrets. That’s a more secure container.
Docker Scout for Local Image Scanning
Enough theory. Let’s run Docker Scout for real.
Docker Scout scans your Docker images for security issues and hands you best-practice recommendations.
Before we start, make sure you have:
- Docker Desktop 4.38 or later installed
- A Docker Account, and that you’re signed in using
docker login
Say we have a sample Node.js application. This is the Dockerfile.
# Use a lightweight Node.js image based on Alpine LinuxFROM node:22.13.0-alpine
# Set the working directory inside the containerWORKDIR /usr/src/app
# Copy only the package files first (for efficient layer caching)COPY package*.json ./
# Install Node.js dependenciesRUN npm install
# Copy the entire project (including index.js) into the containerCOPY . .
# Expose port 3000 for the Node.js serverEXPOSE 3000
# The default command to run the appCMD ["node", "index.js"]I’m using node:22.13.0-alpine here because it’s smaller than node:22. Better for containers. Smaller doesn’t mean safe, though, so we still scan.
Now build the image.
docker build -t my-node-app:1.0.0 .That packages the application into a Docker image named my-node-app, version 1.0.0.
Next, point Docker Scout at it.
docker scout cves my-node-app:1.0.0Docker Scout analyzes the image and flags whatever looks risky.
When the scan finishes, you get a report. It lists the issues it found, their severity, and how to fix them.
Those issues might trace back to system libraries, base packages, or your own application dependencies. Docker Scout will often tell you to upgrade a component or apply a patch.
Why bother locally? Because you catch problems here, before the image ever hits a registry or a production cluster. Fix them now and your environment is more secure immediately.
That’s the short version of using Docker Scout to tighten up your containerized applications.
Snyk in GitHub Actions
Let’s take it further and automate scanning in the pipeline with Snyk and GitHub Actions.
Before we start, make sure you:
-
Sign up for a free Snyk account at snyk.io.
-
Go to your Snyk account settings page, find your Access Token (Key), and copy it.
-
In your GitHub repo, go to Settings → Secrets and variables → Actions, and create a new secret named
SNYK_TOKEN.
Say we have a Node.js project. The goal is straightforward. A developer pushes code or opens a pull request, and Snyk scans for security issues on its own.
- Snyk will check the container image to detect risks in the base image and OS packages.
- It will also check application dependencies to find security flaws in
package.jsonand other libraries.
Create a GitHub Action Workflow
For this we need a new GitHub Actions workflow file. It goes inside the .github folder, then workflows, and we name it snyk.yml.
name: Snyk Security Scan
on: push: branches: ["main"] pull_request: branches: ["main"]
jobs: security: runs-on: ubuntu-latest steps: - name: Check out the repository uses: actions/checkout@v2
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v2
- name: Build Docker image run: docker build -t my-node-app:1.0.0 .
- name: Snyk Container Scan uses: snyk/actions/docker@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: image: "my-node-app:1.0.0" args: "--file=Dockerfile"
- name: Snyk Code & Dependency Scan uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: "--file=package.json"This workflow scans both the Docker image and the application dependencies for risk, automatically. Notice it pulls SNYK_TOKEN from GitHub Secrets. That’s the right way to do it. Your credentials stay out of the code, and nothing leaks by accident.
Wrap-Up and Final Tips
We got through a lot:
- Why container security matters in 2025
- Seven core principles—from minimal images to least privilege
- A live demo of Docker Scout for local image scanning
- How to automate security scans using Snyk in GitHub Actions
But here’s the key takeaway: Container security isn’t just about tools or settings—it’s a mindset. Everyone on your team plays a role in keeping things secure.
A few more practical things you can do right now:
- Monitor runtime with tools like Falco or Sysdig to detect suspicious activity.
- Keep everything up to date—patching OS packages and dependencies is one of the simplest and most effective security steps.
- Enforce security policies, like blocking deployments if there are serious security issues. A single rule like this can make a big impact.
- Educate your team—security isn’t just for DevOps or engineers; it’s a shared responsibility across developers, QA, and security teams.
Thank you for reading! Don’t forget to check out the video version for additional insights and visuals.
The Verdict
Inconvenient truths about shipping in the AI era
Container security, platform engineering, and the agentic shift — tested in production, argued without the hype. The verdict reaches your inbox the moment there's one worth sending.
Related Posts
- 1Docker supply chain hardening — from Scout D to OpenSSF 7.8 on a 730K-pull imageDevOps & Cloud · How I hardened a 730K-pull public Docker image from Scout grade D to OpenSSF Scorecard 7.8. Multi-stage build, cosign signing, SLSA provenance, non-root default, and the incident that changed how I ship attestations.
- 2Cloudflare Web Analytics on Astro — Why Removing GA4 Unlocked Lighthouse 100DevOps & Cloud · How removing Google Analytics 4 from an Astro site unlocked Lighthouse 100, why Cloudflare Web Analytics replaced it, and what the tradeoffs actually cost.
- 3Platform Engineering — The Complete, Practical Guide to Building Internal Developer Platforms That ScaleDevOps & Cloud · A deep, practical guide to Platform Engineering. Learn how to build internal developer platforms, golden paths, GitOps workflows, and scalable cloud foundations.
- 4Amazon Q vs DevOps Chaos — Can This AI Fix AWS Faster Than You?DevOps & Cloud · Fix AWS issues faster with Amazon Q, the AI assistant built for DevOps. Real-world examples, limitations, and how it compares to ChatGPT.
Random Posts
- 110 Real Terraform Interview Questions (and Expert Answers!) — 2025 DevOps GuideDevOps & Cloud · Ace your Terraform interview with 10 real questions, expert answers, and best practices on state, drift, modules, and security.
- 2Install Active Directory Domain Services on Windows Server 2008 R2SysAdmin & IT Pro · Step-by-step guide to install Active Directory Domain Services (AD DS) on Windows Server 2008 R2. Configure DNS, static IP, and promote to domain controller.
- 3Enable the Active Directory Recycle Bin in Windows Server 2012 R2SysAdmin & IT Pro · Learn how to enable the Active Directory Recycle Bin in Windows Server 2012 R2 to easily recover deleted AD objects. Step-by-step admin guide.
- 4Amazon Q vs DevOps Chaos — Can This AI Fix AWS Faster Than You?DevOps & Cloud · Fix AWS issues faster with Amazon Q, the AI assistant built for DevOps. Real-world examples, limitations, and how it compares to ChatGPT.