Skip to content

DevOps Cluster

Docker to Kubernetes: A Beginner's Path

Published April 11, 2026 · 11 min read

There is a specific order in which the container stack is easiest to learn. Start with one Dockerfile. Get the app running in a container. Add a second service with Docker Compose. Understand why Compose does not scale past a laptop. Translate the Compose file to a Kubernetes manifest. Run it on a single-node cluster. Add real observability. Everything after that — ingress, Helm, operators, service meshes — is variation on that base.

Skipping steps is where beginners get stuck. Going straight from a README tutorial to a production Kubernetes deployment means you are debugging ten abstractions at once and you do not know which one is lying to you. This guide walks through the path in order, with the tools that help at each step.

Why containers at all

A container packages an application with its runtime dependencies into a single image that runs the same way on a developer laptop, a CI runner, and a production server. Before containers, "works on my machine" was a running joke in every engineering org because the OS, the language runtime version, the system libraries, and the service configuration all varied between environments. Containers collapse that surface area to the container image and the host kernel.

The official Docker documentation is still the best starting reference for how the technology works. For the ecosystem of tools that grew around containers — orchestrators, service meshes, observability — the CNCF Cloud Native Landscape is an overwhelming but comprehensive map.

Step 1: The Dockerfile

A Dockerfile is a recipe for building a container image. It starts from a base image (say, node:20-alpine), copies your source code in, installs dependencies, sets an entrypoint, and exposes a port. Four lines can be enough. Ten is more common. Thirty is a sign you are doing something wrong.

The rules of a good Dockerfile are by now well-known and mostly ignored in practice.

  • Pin the base image. node:20.11.1-alpine3.19, not node:latest. Your builds should be reproducible in six months.
  • Cache layers intelligently. Copy package.json and run npm install before copying the rest of the source. Then a source-code change does not invalidate the dependency layer.
  • Use multi-stage builds. Build in one image, copy the artifact into a slim runtime image. Your production image should not contain compilers, test frameworks, or dev dependencies.
  • Run as non-root. Add a user in the image and USER to it. Containers are not jails; running as root inside a container and escaping is a real class of vulnerability.
  • Set HEALTHCHECK. Let the orchestrator know when the container is actually ready.

Use Dockerfile Generator to scaffold a sensible starting Dockerfile for common stacks (Node, Python, Go, Java, PHP). The generated file handles the base case — multi-stage, cached dependencies, exposed ports — so you can focus on the application-specific tweaks.

Step 2: Multi-service with Compose

Real applications are rarely one container. A typical web app is an application server, a database, a cache, maybe a queue. Running each manually with docker run quickly becomes unmaintainable. Docker Compose is a YAML file that declares all of them together.

A Compose file defines services (containers), networks (how they talk to each other), and volumes (where persistent data lives). When you run docker compose up, Docker starts everything, wires them into a private network, and attaches the volumes.

The Compose model is perfect for a single machine. It handles development environments, small-scale production, and local testing of multi-service setups. It does not handle multiple machines, failure recovery, rolling updates, or any of the things orchestrators exist for.

Generate or normalize a Compose file with Docker Compose Generator. If you already have a docker run command from a tutorial and want to convert it into a reusable Compose file, Docker Run to Compose does the translation for you. Since Compose files are YAML, pass the output through YAML Validator to catch indentation mistakes before you try to run them.

Step 3: The first Kubernetes manifest

Kubernetes is an orchestrator. It runs containers across many machines, reschedules them when nodes die, handles rolling updates, routes traffic, and mounts persistent storage. It has a reputation for complexity and the reputation is deserved — not because Kubernetes itself is hard, but because the ecosystem around it is vast.

The base unit in Kubernetes is the Pod, which is one or more co-located containers. Pods are wrapped in higher-level objects: Deployment (a desired number of pod replicas), Service (a stable network endpoint), ConfigMap (non-secret configuration), Secret (sensitive configuration), Ingress (external HTTP routing), PersistentVolumeClaim (storage).

The minimum a new Kubernetes user needs to write is:

  • A Deployment that runs your container.
  • A Service that gives the Deployment a stable DNS name inside the cluster.
  • An Ingress that routes external traffic to the Service.
  • A ConfigMap or Secret for environment variables.

Every one of those is a YAML file. The official Kubernetes docs have clean examples for each. The manifests are verbose but the structure is mechanical — every object has apiVersion, kind, metadata, and spec.

Validate manifests before applying them with YAML Validator. For the inevitable environment variables, Env File Parser helps convert a .env file into the shape you need for a Kubernetes ConfigMap or Secret.

Step 4: What you need to add for production

A Deployment plus Service plus Ingress gets your app running. Production needs a handful of things beyond that, and most outages come from skipping them.

  • Resource requests and limits. Every container should declare CPU and memory requests (what it needs to start) and limits (what it cannot exceed). Without these, the cluster cannot schedule intelligently and one runaway process can starve everything else.
  • Liveness and readiness probes. Liveness tells Kubernetes "restart me if I am broken." Readiness tells it "do not send me traffic until I am ready." Confusing the two is how you ship apps that rolling-update into 502s.
  • PodDisruptionBudget. Tell the cluster how many pods can be down during voluntary disruptions (node drains, upgrades). Without this, an upgrade can take all your pods down simultaneously.
  • HorizontalPodAutoscaler. Scale the number of replicas based on CPU or custom metrics. Essential for anything with variable load.
  • NetworkPolicy. Default Kubernetes lets any pod talk to any other pod. In production, restrict pod-to-pod traffic with NetworkPolicies.

Common mistakes on the path

Installing a full cluster before running a container

Start with a single Docker container on your laptop. A full production Kubernetes cluster is ten concepts to learn simultaneously when you only need three to understand what a container is.

Treating Compose as production

Compose is fantastic for development. It is not for production traffic beyond a single machine. If you find yourself wishing Compose had rolling updates, it is time to move on.

Running latest tags

Images tagged latest are a time bomb. Today's latest is not tomorrow's latest. Pin image tags to specific versions in both Compose and Kubernetes.

Secrets in environment variables, in git

Secrets end up in docker-compose.yml, which ends up in git. Use a secrets manager, not a text file in your repo.

Ignoring image size

A 2 GB image is slow to push, slow to pull, and slow to start. Slim base images, multi-stage builds, and .dockerignore are not optional for serious projects.

Adjacent tools worth bookmarking

Tools DevOps engineers reach for repeatedly: JSON Formatter for inspecting container logs that emit structured JSON, YAML to JSON for feeding Compose or manifest files into tools that only accept JSON, Base64 Encoder/Decoder because Kubernetes Secrets store values base64-encoded, and Hash Generator for verifying image digests.

Related pillar guide

This cluster is part of the developer and DevOps track. For a broader survey of browser-based tools across the stack, see The Complete Guide to Free Online Tools in 2026.

FAQ

Do I need Kubernetes for my small web app?

Almost certainly not. A single container behind a managed hosting platform is often simpler and cheaper. Kubernetes pays off once you need multi-service orchestration across many machines.

Can I use Docker Compose in production?

On a single host, yes, and many small production systems do. You lose high availability and zero-downtime updates, which may or may not matter depending on your users.

What is the smallest production-usable Kubernetes setup?

A managed single-node or small-node cluster from a cloud provider, with ingress, cert-manager for TLS, and Prometheus for metrics. Anything less and you are hand-rolling pieces a managed service would give you.

Why is my container image so big?

Usually because the build image (with compilers and dev dependencies) and the runtime image are the same. Multi-stage builds copy only the artifact into a minimal runtime image and typically cut size by 80–95 percent.

Helm or plain YAML?

Plain YAML for a few services. Helm once you need templating, environment overrides, or to consume third-party charts. There is no prize for using Helm on day one.

Closing thought

Containers are not magic. They are a structured way to package software, and the tools around them — Compose, Kubernetes, service meshes — are layers that each solve one real problem. Learn them in order, use a generator when the syntax is tedious, and do not deploy anything to production that you could not draw on a whiteboard.