Help! My Node.js Docker Image Has Python 🐍 — Uncovering the Right Base Image for Your Node.js App


Hey there,

I’ve just finished putting together everything I know about Node.js container images and figured you might find the write-up useful.

If you’re working with Node.js in Docker, chances are you’ve been hit by the dilemma of which base image to use. Do you go for the default node:latest, the slimmer node:22-slim, or something super minimal like a distroless image? What about Bitnami’s alternative — how does it stack up?

Before you jump headfirst into your next build, you might want to check out my latest iximiuz Labs post, where I dive into some unexpected quirks (like finding a full Python installation in certain Node.js images 😱), the trade-offs between different image types, and best practices for keeping your containers secure and efficient.

Here’s a little taste of what you’ll find inside:

Why Not All Node.js Images Are Created Equal

Did you know that Docker's "official" node:<version> (e.g., node:22), node:lts, and node:latest images include far more than just Node.js? This "fat" image variant has Python, GCC, and hundreds of other packages. That’s why it can balloon up to over 1GB! But if your app doesn’t need to compile native Node.js modules during the npm install step, all that extra bulk is just wasted space and unjustified security risk.

If you’re looking for something more streamlined, the node:<version>-slim image trims a lot of the fat while keeping things fully functional. It’s perfect for most cases where you don’t need to compile your Node.js modules from C++ (read, in 99% of the time).

But Wait… Distroless Images?

For those of you chasing after the smallest, most secure image possible, distroless might sound like the best option. These images come with just the essentials — no shell, no OS package manager, just Node.js and its minimal dependencies. The gcr.io/distroless/nodejs image weighs in at under 150MB and has almost zero CVEs. But the trade-off? The build process gets more complicated, and you also lose debugging flexibility. Want to exec into your container and poke around? Sorry, no shell here. It’s a perfect fit for production, but you need to plan for it.

Bitnami: A Worthy Contender?

Did you know that Bitnami offers a repackaged Node.js container image that, functionality-wise, is very close to Docker's "official" node:<version> but slightly smaller? It comes with many of the same development tools (like Python and GCC), and it’s worth a look if you’re already in the Bitnami ecosystem. However, just like the Docker "official" images, it’s best left for development and build stages and only if you're compiling that C++ code... Otherwise, you'd better steer clear of the unnecessary bloat.

Practical Tips for Node.js Docker Images:

Here are some quick takeaways to keep your Docker images lean, mean, and secure:

For Development/Build: Use node:<version> or bitnami/node:<version> only if you’re compiling native Node.js modules from C++. Otherwise, the node:<version>-slim image is your best bet.

For Production: If you’re running in production, start with node:<version>-slim to reduce most of the bloat with the least amount of effort. But if security and/or size efficiency is a top priority, consider distroless images like gcr.io/distroless/nodejs or Chainguard’s hardened node image, especially if you’re fine with their operational trade-offs (and, in Chainguard's case, pricing).

Avoid the Pitfalls: Never run production applications in the "fat" node:<version> image, and steer clear of node:latest unless you’re just playing around or running demos. And if you’re unfamiliar with Alpine Linux’s quirks (hello musl vs. glibc), approach node:<version>-alpine with caution.

Curious about all the details? Check out the iximiuz Labs post and get the full scoop, including practical examples, security scan results, and tips for using multi-stage builds to keep your containers lightweight.

👉 A Deeper Look into Node.js Docker Images: Help, My Node Image Has Python!

Stay lean, stay secure, and happy building!

Cheers,

Ivan

P.S. My traditional reminder - if you want to learn the Server Side craft faster and support my work, consider getting iximiuz Labs Premium. There is a very good chance you will be able to expense it using your learning and development budget.

Ivan Velichko

Building labs.iximiuz.com - a place to help you learn Containers and Kubernetes the fun way 🚀

Read more from Ivan Velichko
Diagram showing desired network policy configuration between frontend and backend pods

Hey, fellow server dweller 👋 Ivan here with an exciting iximiuz Labs update! The month isn't over yet, so it's not quite time for the traditional monthly roundup. However, there have been so many updates on the platform in the past couple of weeks that they couldn't possibly fit into a single email. So, let's dive in 🚀 Backend Revamp: Faster, Smarter, Stronger Over the past few weeks, I rolled out a significant backend rewrite at iximiuz Labs, and I couldn't be more excited to share the...

Hello 👋 Ivan's here with November's roundup of all things Linux, Containers, Kubernetes, and Server Side 🧙 What I was working on This month was (extremely) development-heavy. Two-thirds of it went into the implementation of custom playground machinery and a new Kubernetes "Omni" playground, and in the last part, I was unexpectedly busy with expanding the platform's capacity and launching a new server in India 🎉 The latter became possible thanks to the support of all of you who got the premium...

Hello, fellow server dweller 👋 I've got two exciting announcements to make. Starting with the shorter one, this year, I decided to give Black Friday a try. This is an experiment - iximiuz Labs hasn't done sales before and won't have any in the foreseeable future, at least not until next November. So, if you wanted to get a premium membership but the price felt too high, this is your rare chance to get it with a 50% discount. The offer is limited to exactly one week. Now, to the second, much...