Addicted Arts

Introduction to Containerization with Docker for Newcomers

That `requirements_final_v3.txt` that only works on your laptop? Containerization exists to kill that exact problem. Here's the plain-language Docker guide—images, containers, and the 5 commands you actually need.

Introduction to Containerization with Docker for Newcomers

Somewhere in your project folder there's a file called something like requirements_final_v3_actually_final.txt. It works on your laptop. It has never once worked on a colleague's machine, on the staging server, or in CI. That's not a discipline problem. That's an environment problem, and it's the exact thing containerization was built to kill.

If you're new to this and someone just told you to "use Docker," you've probably already hit the wall of jargon — images, containers, daemons, volumes, compose files. This is the plain-language version I wish someone had handed me when I first typed docker run and watched a wall of output scroll past that I didn't understand.

Key Takeaways

  • Containerization packages your app with its dependencies so it behaves identically on your machine, a teammate's laptop, and a production server.
  • A container is not a small virtual machine. It shares the host's kernel, which is why it starts in under a second instead of a minute.
  • Learn five commands first: pull, run, build, ps, stop. Everything else can wait.
  • An image is the recipe, a container is the dish. You build an image once and run many containers from it.
  • Containers are not a security boundary by default — isolation is real but partial, and it deserves a moment of thought before you put anything sensitive inside one.

Introduction to containerization with Docker: what problem does it actually solve?

Picture the classic failure. You install Python 3.11, a specific version of PostgreSQL, and a system library that happens to be on your OS. You commit a .txt file listing dependencies, push it, and CI fails on a different libc version. Nobody changed the code. The code was never the problem.

Containerization flips the relationship. Instead of describing what to install on top of whatever machine you happen to have, you ship the whole environment as one unit. The runtime, the libraries, the config paths, the exact interpreter version. Everything travels together.

What is containerization in Docker?

Containerization is OS-level virtualization. One machine runs many isolated processes, each convinced it has the filesystem, network ports, and process tree to itself. They share the host's kernel — the core of the operating system that talks to hardware — but nothing else leaks between them.

Docker is the tooling layer that made this practical. It gave containerization a friendly command line, a registry to pull prebuilt environments from, and a file format (Dockerfile) simple enough to read in a single sitting. Before Docker, the underlying Linux features existed; using them by hand was a specialist's job.

How is a container different from a virtual machine?

This is the question that trips up nearly everyone at the start, and it's the one most tutorials skip.

A virtual machine emulates an entire computer. It runs through a hypervisor, boots a complete guest operating system, and takes a substantial slice of RAM and disk before your application even starts. Startup measured in minutes is normal. A container skips all of that. There's no guest OS to boot — your process just starts.

Virtual machine Container
What boots A full guest OS Just your process
Startup time Tens of seconds to minutes Under a second, typically
Disk footprint Gigabytes per instance Megabytes, thanks to shared layers
Isolation strength Strong — separate kernel Good, but kernel is shared
Typical use Running a different OS, hard multi-tenancy Shipping application code

When I first switched a small service from a VM to a container, the deploy step went from roughly ninety seconds to about four. Same code. Different packaging.

The four concepts you need before touching a keyboard

Docker's vocabulary is small, but the words get used loosely in tutorials, which is why beginners get stuck. Here's the honest version.

The four concepts you need before touching a keyboard

Image, container, Dockerfile — what's the difference?

An image is a read-only template: your code plus the exact environment it needs. A container is a running instance of that image. One image, many containers, no conflict between them.

A Dockerfile is the text file you write to produce an image. It's a build recipe, not a script that runs at startup. Confusing those two is the mistake I made for my entire first week.

The last piece is the registry — a storage service for images. Docker Hub is the default public one. When you type docker pull postgres, you're fetching a prebuilt image someone else assembled.

  • Image — the recipe, stored, versioned, shareable
  • Container — the dish, running or stopped, disposable
  • Dockerfile — the instructions that produce an image
  • Registry — where images live between builds and deploys
  • Volume — persistent storage that outlives a container's life

Under the hood there's a client-server split: the docker command you type talks to a background daemon that does the real work. You'll rarely think about the daemon, but knowing it exists explains why "Docker isn't running" is a real error message.

Your first container, in five commands

You don't need to write a Dockerfile on day one. Start by running something that already exists.

  1. docker pull nginx — download a web server image
  2. docker run -d -p 8080:80 nginx — start it, map port 8080 on your machine to port 80 inside the container
  3. docker ps — confirm it's running
  4. Open localhost:8080 in a browser
  5. docker stop <container-id> — shut it down

The -d flag detaches the container so it runs in the background. The -p flag is port mapping, and it's the single most common source of "why can't I reach it" confusion. Ports inside a container are private until you publish them.

A real Docker containerization example, build to run

Here's the smallest useful Dockerfile — a Python script, nothing clever:

FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "main.py"]

Each line becomes a layer. Docker caches layers, so if only your application code changes and the dependency list doesn't, the pip install step is reused. That's worth understanding early: order your Dockerfile so the things that change rarely come first. I once had builds taking four minutes because I copied the whole source tree before installing dependencies, invalidating the cache on every single edit. Reordering two lines brought it under twenty seconds.

Then: docker build -t myapp . and docker run myapp. That's the whole loop.

What nobody tells beginners about containers

Containers are often sold as sandboxes. They're not, not really.

Because every container shares the host kernel, a kernel vulnerability can potentially become an escape route. Isolation is enforced by Linux namespaces and cgroups — solid, well-tested mechanisms, but a different category of separation than a hypervisor gives you. For running your own application code, that's fine. For running untrusted code from strangers, it deserves more care.

Practical habits that matter more than paranoia:

  • Run as a non-root user inside the container. A one-line addition to your Dockerfile.
  • Pull images from sources you trust. A registry is not a security review.
  • Keep base images updated. An image built two years ago contains two-year-old packages.
  • Don't bake secrets into images. Environment variables and mounted files exist for that.

I learned the last one the hard way — an API key committed into a test image that I then pushed to a public repository. It was revoked within the hour, but the lesson stuck permanently.

Where Docker fits next to Kubernetes, Podman, and the rest

Once containers click, the next question is always "what about Kubernetes?"

Kubernetes orchestrates containers across many machines. It schedules them, restarts failed ones, and scales them. It expects containers as its input format, which is precisely why learning the basics first pays off. You cannot sensibly orchestrate something you can't run by hand.

Podman is a drop-in alternative that runs containers without a background daemon, which some teams prefer for security or systemd integration. containerd is the lower-level runtime that Docker itself uses underneath. None of these change the mental model — image, container, port, volume. Learn that once and the tools become interchangeable.

For a newcomer, the sequence is straightforward. Get one container running. Write one Dockerfile. Add a volume so data survives a restart. Then reach for Docker Compose when you need two services talking to each other. Skip that order and you'll be debugging YAML before you understand what it describes.

The first time you hand a colleague a single command that reproduces your entire working setup on their machine — and it just works — is the moment containerization stops being abstract. Everything after that is detail.

Nadia Whitaker

Nadia Whitaker

Nadia Whitaker is a recognized authority in cloud computing, DevOps, and distributed systems, with a career dedicated to designing resilient, scalable architectures. She combines deep technical knowledge with a collaborative spirit, helping teams navigate complex infrastructure challenges and adopt modern delivery practices. Her writing and speaking engagements reflect a genuine passion for making advanced engineering concepts accessible and practical.

See all articles →

Related articles