Skip to main content

Command Palette

Search for a command to run...

Docker Basics Every Developer Should Know Before Touching Kubernetes

Updated
6 min read
Docker Basics Every Developer Should Know Before Touching Kubernetes

This article is part of the Cloud Native by Kushneet series — where I document my journey learning cloud native technologies from scratch, one concept at a time.

Start from the beginning: Containers vs Virtual Machines

Now. The tiffin box is complete. It has everything the person needs for lunch. It doesn't matter where that is going — the food inside is self-contained, ready to travel, and won't spill into anyone else's bag.

That's a Docker container.

And before we even look at Kubernetes — the delivery system — we need to understand what we're actually putting inside the box.

The Problem Docker Was Born To Solve

There's a phrase every developer has said at least once:
"But it works on my machine."

We build a Node.js app on a laptop, and it runs perfectly. However, when we push it to a server, it crashes. Why? There could be many reasons, such as the server running Node 16 but being built on Node 20. Or it's missing a library. Or the OS is slightly different.

In short, the code didn't change. The environment did.

Before Docker, the fix was a ten-page run book that said things like "make sure you have version 3.6.2 of this specific dependency installed, but not 3.6.3." Engineers spent more time fighting environments than writing code.

Docker said: what if the environment travelled with the code?

That was the idea. Deceptively simple. Completely transformative

So What Exactly Is a Container?

A container is a lightweight package that includes our application and everything it needs to run—libraries, dependencies, runtime, and configuration. It runs in isolation while sharing the host operating system's kernel.

Think of it like a tiffin box:
Box = Container
Food = App with all its dependencies.

Unlike VMs, containers don't need a full OS of their own. They share the host kernel, making them much faster to start and far more resource-efficient.

For a clearer understanding of how containers differ from VMs, check out the "Containers vs Virtual Machines" article.

The Dockerfile: Your Tiffin Recipe

Before you can run a container, you need to build an image. And to build an image, you write a Dockerfile — a plain text file that describes exactly how to construct your environment.

# Choose a lightweight Node.js environment
# Start with a base image (empty tiffin box)
FROM node:20-alpine

# Set where we'll work inside the container (active folder in our OS where all commands will run)
WORKDIR /app

# Copy the ingredient list first for better caching
COPY package*.json ./

# Install dependencies(external package libraries used by code)
RUN npm install

# Copy the actual app code
COPY . .

# Declare the port used by the application
EXPOSE 3000

# Default command that runs when the container starts
CMD ["node", "server.js"]

Each line in a Dockerfile creates a layer. Docker caches these layers — so if the code changes but the dependencies haven't, it skips reinstalling everything from scratch and only rebuilds what changed. This is why the order of instructions matters.

Building and Running: From Recipe to Tiffin

Once you have a Dockerfile, two commands do everything:

# Build the image — 'pack the tiffin'
# The -t flag tags image with a name and version. 
docker build -t my-app:v1 .

# Run a container from that image — 'open and eat'
# -p 3000:3000 maps port 3000 on machine to port 3000 inside the container as by default container is isolated and nothing can reach it from outside.
docker run -p 3000:3000 my-app:v1

And just like that — the app is running in a clean, isolated environment that you fully control and is the same everywhere.

Images vs. Containers: Recipe vs. Tiffin

CONCEPT

IMAGE

CONTAINER

What it is

A read-only snapshot of your app + environment

A running instance of an image

Mutable?

No — images are immutable

Yes — containers have a writable layer

Created by

docker build

docker run

Are multiple possible

Yes — store multiple versions

Yes — store multiple versions

Example

my-app:v1

abc123 (running)

Kubernetes can take a single Docker image and launch dozens of isolated containers from it.

For example, one API image can be used to run 50 independent containers, allowing the application to handle more traffic while keeping each instance isolated. Thus, a failure in one container does not affect the others.

This is the base of scaling concept in Kubernets.

Docker Hub: The Tiffin Template Store

We don't have to start Dockerfile from absolute scratch. The FROM instruction lets us pull a pre-built base image from Docker Hub — the world's largest container registry.

It's like a store where someone has already built the basic tiffin box and lined it with the right material. Just add your food on top.

# For a Node.js application
FROM node:20-alpine

#OR

# For a Python application
FROM python:3.12-slim

#OR

# For a full Ubuntu environment
FROM ubuntu:22.04

#OR

#Pull your own image from a private registry
FROM gcr.io/your-project/your-image:latest

Official images are maintained by the teams that build the software themselves. They are regularly updated, security-patched, and tested by millions of developers worldwide.

By using an official image as the base, we don't have to install everything from scratch. Instead, we start with a reliable foundation that already contains the tools our application needs, allowing us to focus on building our application rather than setting up the environment.

WHAT'S NEXT

The next article covers Docker Compose — what happens when your app needs more than one container running together.

f you found this helpful, share it with someone who's been putting off learning Docker.

Previous Article: The Open Source Republic "CNCF"

I'm documenting my entire cloud native journey publicly — follow along on Hashnode and connect with me on LinkedIn.