Skip to main content

Command Palette

Search for a command to run...

Codeforge Lessons: Containerization Struggles and Security Fixes

Updated
3 min read
Codeforge Lessons: Containerization Struggles and Security Fixes

In this blog, I’m going to talk about the challenges I faced while containerizing my project, CodeForge (a coding platform) where I implemented DevSecOps practices to make the application more secure.

Getting Started with Docker

The main goal was to create Docker images that are both secure and lightweight. I started with a .dockerignore file to exclude unnecessary files like node_modules, log files, and other things that don’t need to be inside the image.

For the backend, I initially used the node:20-alpine image. But when I built it, the image size ended up being 400+ MB, which was way more than expected.

Optimizing and Securing the Image

From there, I started applying best practices to reduce the size and improve security. I converted the Dockerfile into a multi-stage build, and used node:20-slim in the final stage. This helped reduce the image size quite a bit.

Next, I added another security layer by using a non-root user inside the container. This way, even if the container gets compromised, the attacker won’t have full access, which adds an extra level of safety.

Vulnerability Challenges

As a third step, I used Trivy to scan the image for vulnerabilities. Surprisingly, the scan reported 60+ vulnerabilities in the backend image. Most of them were coming from dependencies that had known security issues.

To fix this, I tried switching between different base images like node:22-slim, and even newer Alpine and slim versions. While this did reduce the number of vulnerabilities, I wasn’t able to bring it down to zero.

After some more digging, I reached a point where only one vulnerability was left. The issue was related to a package called picomatch. Interestingly, I had version 4.0.4 in my package.json, which was safe but another vulnerable version was being pulled in as a Nested dependency by a different package.

I tried updating and forcing versions inside the Dockerfile, but the vulnerable version was still there.

Final Fix and Results

At this point, I decided to try an AI tool for help. It suggested using Chainguard images, which are known for having minimal or zero vulnerabilities. I gave it a shot, and it actually worked the Trivy scan came back clean.

The image size at that stage was around 193 MB, which was decent, but I wanted to push it further.

That’s when I came across distroless images. I tried switching to those, and the results were honestly impressive. The image size dropped to around 58 MB, almost 4x smaller, and the Trivy scan still reported zero vulnerabilities.

Final Thoughts

I didn’t expect to go this deep while working on it, but it ended up teaching me a lot about image optimization and security. Definitely a good learning experience that I’ll carry forward.