← Back to list

Hands-On Docker: Build, Push, and Run Your First Containerized App

Stop reading about Docker. Start doing it. This step-by-step walkthrough takes you from zero to a live containerized Node.js app — with…

Gunjan Kapoor · 2026-05-22 19:57 · 27 claps · 4.7 min read paywalled
#docker #dockerfiles #dockerhub #containers #devops
Open on Medium ↗
Wiki topics: 🌐 · Web Development ☁️ · DevOps & Cloud 📚 · Books & Reading

Hands-On Docker: Build, Push, and Run Your First Containerized App

Stop reading about Docker. Start doing it. This step-by-step walkthrough takes you from zero to a live containerized Node.js app — with your image published on Docker Hub and running anywhere.

Docker DevOps Containers

Prerequisites

Before diving in, make sure you have the following installed on your machine:

  • Docker Desktop — available for macOS, Windows, and Linux
  • Git — to clone the sample repository
  • A free account on hub.docker.com — you’ll need this to push your image

Once Docker Desktop is installed and running, confirm everything is working:

docker --version

You should see a version string like Docker version 24.x.x. If you do, you're ready to go.

Step 1 — Get the Sample Application

We’ll use Docker’s official getting-started app as our test subject. It’s a simple Node.js to-do application — just enough to demonstrate the full Docker workflow without getting lost in application code.

Clone the repository and navigate into it:

git clone https://github.com/docker/getting-started-app.git
cd getting-started-app/

Take a moment to look around. You’ll see a src/ directory with the app code, a package.json, and a few config files. There's no Dockerfile yet — that's your job.

Step 2 — Write Your Dockerfile

The Dockerfile is the blueprint for your container image. It's a plain-text file that tells Docker exactly how to assemble your application and everything it needs to run.

Create an empty file in the project root:

touch Dockerfile

Open it in your editor of choice and paste in the following:

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
EXPOSE 3000

Let’s break down what each line does:

Instruction What it does FROM node:18-alpine Starts from an official Node.js 18 base image built on Alpine Linux — lightweight at under 50MB WORKDIR /app Sets /app as the working directory inside the container for all subsequent commands COPY . . Copies everything from your current directory into /app inside the image RUN yarn install --production Installs only production dependencies during the image build CMD ["node", "src/index.js"] The command that runs when a container starts from this image EXPOSE 3000 Documents that the app listens on port 3000 (does not publish the port itself)

Why Alpine? The node:18-alpine base image is a deliberately minimal Linux distribution. It includes only what's needed to run a Node.js application — no desktop utilities, no extra packages. The result is a smaller, faster, and more secure image compared to a full Ubuntu or Debian base.

Step 3 — Build the Docker Image

With your Dockerfile in place, build the image using the docker build command. The -t flag tags the image with a human-readable name.

docker build -t day02-todo .

The . at the end tells Docker to use the current directory as the build context — the set of files available during the build. You'll see Docker pull the base image (first run only), then execute each instruction layer by layer.

Once complete, verify the image exists locally:

docker images

You should see day02-todo listed with its size and creation timestamp. Your image is now a self-contained, portable binary sitting on your machine.

Step 4 — Push the Image to Docker Hub

A local image is useful, but the real power comes from sharing it — pushing it to a remote registry so any environment can pull and run the exact same image.

First, log in to Docker Hub:

docker login

Enter your Docker Hub username and password when prompted.

Tag your image for the remote repository. Docker needs the image name to include your username and repository name before it can be pushed:

docker tag day02-todo:latest your-username/your-repo-name:v1.0

Verify the tagged image appears in your local image list:

docker images

Push to the registry:

docker push your-username/your-repo-name:v1.0

Docker uploads each layer individually. Layers that already exist in the registry are skipped — this is what makes subsequent pushes fast. Once complete, log in to hub.docker.com and you’ll see your image listed under your repositories.

Step 5 — Pull and Run the Container

Now simulate what happens in a real deployment. On any machine — your staging server, a colleague’s laptop, a cloud VM — you can pull and run this image with two commands:

Pull the image from the registry:

docker pull your-username/your-repo-name:v1.0

Start the container:

docker run -dp 3000:3000 your-username/your-repo-name:v1.0

The flags here matter:

  • -d — runs the container in detached mode (in the background, freeing your terminal)
  • -p 3000:3000 — maps port 3000 on your host machine to port 3000 inside the container

Open your browser and navigate to http://localhost:3000. You should see the to-do application running.

That’s the full loop: code → image → registry → running container. The same image you built on your machine is now running on demand, anywhere.

Step 6 — Inspect and Debug Your Container

Once your container is running, Docker gives you several tools to look inside and understand what’s happening.

Execute a shell session inside the running container:

docker exec -it container-name sh
# or using the container ID
docker exec -it container-id sh

The -it flags allocate an interactive terminal (-i keeps stdin open, -t allocates a pseudo-TTY). Once inside, you can inspect the file system, check environment variables, or run commands as if you were SSH'd into a server.

Type exit to leave the container without stopping it.

View the container’s logs:

docker logs container-name
# or
docker logs container-id

This streams the stdout and stderr output from the running process — exactly what you’d see if you ran node src/index.js directly. Add -f to follow logs in real time:

docker logs -f container-name

The Full Workflow at a Glance

Your Code + Dockerfile
         │
         ▼  docker build -t day02-todo .
    Local Image (day02-todo)
         │
         ▼  docker tag + docker push
    Docker Hub Registry
         │
         ▼  docker pull
    Any Environment (dev / staging / prod)
         │
         ▼  docker run -dp 3000:3000
    Running Container → localhost:3000

What You’ve Accomplished

In the span of a few commands, you’ve completed the entire Docker lifecycle:

  • Written a Dockerfile that packages a Node.js app with its runtime and dependencies
  • Built a layered, immutable image from that blueprint
  • Published that image to a public registry
  • Pulled and run the image as a live container
  • Inspected a running container’s file system and logs

This is the foundation that every Docker-based deployment — from a single microservice to a Kubernetes cluster running hundreds of containers — is built on.

The next step from here is Docker Compose for multi-container applications, and then Kubernetes when you need orchestration at scale. But those are stories for another day.

Quick Reference

Command What it does docker build -t name . Build an image from the current directory docker images List all locally stored images docker run -dp 3000:3000 name Run a container, detached, with port mapping docker tag image user/repo:tag Tag an image for a remote registry docker push user/repo:tag Push an image to Docker Hub docker pull user/repo:tag Pull an image from Docker Hub docker exec -it name sh Open a shell inside a running container docker logs name View stdout/stderr logs from a container

Build once. Push once. Run anywhere.


메타데이터
post_id
5c8a1357151e
slug
hands-on-docker-build-push-and-run-your-first-containerized-app-5c8a1357151e
url
https://medium.com/@gunjankapoor9999/hands-on-docker-build-push-and-run-your-first-containerized-app-5c8a1357151e
canonical_url
https://medium.com/@gunjankapoor9999/hands-on-docker-build-push-and-run-your-first-containerized-app-5c8a1357151e
author_url
https://medium.com/@gunjankapoor9999
status
ok
fetched_at
2026-06-09 15:37:30