Docker Deep Dive: Beginner To Advanced

9 min
Docker Deep Dive: Beginner To Advanced
Docker Deep Dive: Beginner To Advanced

If you’ve ever said:

  • “Why does this app work on your machine and not mine?”
  • “How do I test this microservice without setting up an environment?”
  • “Why does my local build pass but CI fails?”

Then my friend, it’s time to welcome Docker into your life. Think of it as your app’s personal travel agent - it packages everything your app needs and ensures it works the same way everywhere.

Let’s go through practical examples, gotchas, and setups you can try right now on your machine.

Performance optimization goes hand-in-hand with containerization. You can also explore these 5 techniques to reduce page load time..

What is Docker, really?

Docker is a platform to build, ship, and run apps in an isolated, consistent environment — across machines, clouds, and even timezones.

It’s like a neatly packed tiffin box. Everything your app needs — libraries, settings, OS flavor — bundled and ready to go.

Containers

A container is an isolated environment that runs an application.

Why they’re awesome:

  • lightweight
  • uses OS(kernel) of host
  • start quickly
  • need less hardware resources
  • can be stopped & restarted
  • just a process

Docker Image

A Docker image is like a read-only snapshot of your app.

It includes:

  • application files
  • third party libraries
  • environment variables
  • cut down OS
Application Code + Dependencies + Config + Base OS = Image

You build containers from images.

Note: To do hands-on, make sure you have installed Docker Desktop.

Dockerfile

This is your image’s blueprint. Let’s say you want to run a basic NodeJS app:

Example 1: Dockerizing a Node App

// app.js

console.log('Hello from docker container!')
# Dockerfile

# Use the latest version of NodeJS
FROM node:24-slim

# Set the working directory
WORKDIR /app

# Copy files
COPY . .

# Start the app
CMD ["node", "app.js"]

Then to build the docker image and run the docker container, execute the following commands in your terminal:

# Syntax: docker build -t <image-name> <build-context>
docker build -t hello-node .
docker run hello-node

See “Hello from docker container!” in your terminal. It’s working. Yay!

Tips

  • Use COPY ["file", "destination"] for JSON-safe copy.
  • Ignore unnecessary files using .dockerignore:
# .dockerignore

node_modules
.git
Dockerfile*
*.log

Example 2: Dockerizing a React App

Let’s turn a React app into a container:

# Dockerfile

# Use the latest version of NodeJS
FROM node:24-slim

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the files
COPY . .

# Expose the port
EXPOSE 3000

# Run the app
CMD ["npm", "start"]

Let’s again build the docker image and run the docker container:

docker build -t react-app .
docker run react-app

Note: ‘slim’ is smaller than full Node images.

RUN vs CMD

Click to read more
CommandPurposeRuns duringExample
RUNExecutes at build time to build the image (e.g., install packages).Docker image buildRUN npm install
CMDSpecifies the default command when a container starts.When container is runCMD ["node", "app.js"]

Note: Only one CMD is allowed per Dockerfile; last one overrides previous.

Setting environment variables

This is how we can add environment variables in our Dockerfile.

ENV PUBLIC_URL=https://gauravadhikari.com

Port Mapping

By now you can build your docker image and run the docker container, but you can not access the react app in your system. That’s because the react app is running on an isolated environment and its ports aren’t exposed to your system.

This is where port publishing comes in.

You can map ports using the -p flag:

# Syntax: -p <host_port>:<container_port>
docker run -d -p 3000:3000 react-app

Now, try to open localhost:3000 tada.., you can access your react app!

Tagging Images

You can tag images to organize them with names and versions:

# Tag image during build
# Syntax: -t <image-name>:<tag> <build-context>

docker build -t my-app:1.0 .

# Tag an existing image with another tag
docker tag my-app:1 my-app:latest

Manage, Inspect, Debug & Explore

Here are some essential commands to help you manage your Docker environment:

List Docker Images

docker images

Check Running Containers

docker ps

List All Containers (Including Stopped)

docker ps -a

Run Container in Background

docker run -d react-app

Access Container Shell

docker exec -it <container_id> bash

View Container Logs

docker logs <container_id>

Watch Logs in Real-time

docker logs -f <container_id>

Stop a Container

docker stop <container_id>

Start a Container

docker start <container_id>

Restart a Container

docker restart <container_id>

Remove a Container

docker rm <container_id>

Clean Up Unused Images

docker image prune
docker image rm hello-node

Clean Up Stopped Containers

docker container prune

I hope you enjoyed running the above commands in your terminal, now let’s learn another important topic in Docker, that is Volumes.

Docker Volumes

When a container shuts down or gets deleted, everything inside it usually disappears - so in order to persist important data like databases, log files etc we need Docker Volumes.

To create a docker volume:

docker volume create app-data

To create / use a volume while running container:

docker run -v app-data:/app/data react-app

To view / inspect volume:

docker volume inspect app-data

This ensures your data survives even if the container is removed. For example - databases, logs, uploads.

Copying Files Between Host and Containers

While we are here, let’s quickly learn how to copy files to and from a docker container.

DirectionCommandExample
Container → Hostdocker cp SOURCE DESTINATIONdocker cp my_container:/app/logs.txt .
Host → Containerdocker cp SOURCE DESTINATIONdocker cp secret.txt my_container:/app

Docker Hub

Docker Hub is like the App Store or Play Store, but for Docker containers. You can download ready-made images from Docker Hub — like Node, Nginx, MongoDB etc, you can upload your own images to the Docker Hub so that others can use them.

Publish to Docker Hub

docker login
docker tag react-app username/react-app:1
docker push username/react-app:1

Share Locally

# Create tar of the image
docker image save -o react.tar react-app

# Use it like this now
docker image load -i react.tar

Multi-stage Builds

Multi-stage builds in Docker let you use multiple FROM statements in a single Dockerfile to build your app in stages.

Why ?

  • Smaller Final Image — The final image uses nginx:alpine, not node, which means you’re not shipping node_modules, source code, or the Node.js runtime — just the static files.

  • Better Security — Fewer packages = fewer vulnerabilities. You’re only exposing what’s absolutely needed to serve the app.

  • Faster Deployments — Smaller images are faster to pull, push, and deploy.

  • Cleaner Separation — One stage handles building (node), another handles serving (nginx), keeping concerns neatly separated.

# Stage 1: Build
FROM node:24-slim AS build
WORKDIR /app
COPY . .
RUN npm install && npm run build

# Stage 2: Serve
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

TL;DR Cheat Sheet

ActionCommand
Build imagedocker build -t <name> .
Run containerdocker run <name>
Run with port mappingdocker run -p 3000:3000 <name>
Run and auto-removedocker run --rm -it <name>
Enter running containerdocker exec -it <container_id> sh
See logsdocker logs -f <container_id>
List containersdocker ps -a
List imagesdocker images
Stop/start containerdocker stop <id> / docker start <id>
Remove container/imagedocker rm <id> / docker rmi <image>
Remove stopped containersdocker container prune
Pull imagedocker pull <image>
Persist data (volume)docker run -v <vol_name>:/app/data <img>
Save/load image filedocker image save -o file.tar <img> / docker image load -i file.tar
Push to Docker Hubdocker push <username>/<image>

Frequently Asked Questions

What is Docker and why is it essential for modern application development?

Docker is a platform for building, shipping, and running applications in an isolated, consistent environment. It packages your app with all its dependencies (libraries, settings, OS flavor) into a 'container,' ensuring it works identically across different machines, clouds, and environments. This eliminates common issues like 'it works on my machine' and simplifies testing and deployment.

What is the key difference between a Docker Image and a Docker Container?

A Docker Image is a read-only blueprint or snapshot of your application, including its code, dependencies, configuration, and a cut-down OS. It's what you build. A Docker Container, on the other hand, is a runnable instance of an image. It's an isolated, lightweight process that runs your application, utilizing the host OS kernel and starting quickly.

How do I create a Docker image for my application using a Dockerfile?

A Dockerfile is a text file containing instructions for building a Docker image. You define the base image (e.g., FROM node:24-slim), set the working directory, copy your application files, install dependencies (using RUN commands), and specify the command to run your application (using CMD). You then build the image with docker build -t <image-name> .

How can I run my Dockerized application and access it from my browser?

After building your image (e.g., my-app), you can run it using docker run my-app. To access web applications (like a React app), you need to map ports between the container and your host machine using the -p flag. For example, docker run -p 3000:3000 my-app maps the container's port 3000 to your host's port 3000, allowing you to access it via localhost:3000.

What are the essential Docker commands for managing images and containers?

Key commands include: docker build (to create images), docker run (to start containers), docker ps (to list running containers), docker ps -a (to list all containers), docker images (to list images), docker stop <id> (to stop a container), docker rm <id> (to remove a container), docker rmi <image> (to remove an image), docker logs <id> (to view container logs), and docker exec -it <id> bash (to access a container's shell).

How do Docker Volumes help in persisting data for containers?

Docker Volumes are used to store important data (like databases or log files) outside of the container's writable layer. This ensures that your data survives even if the container is stopped, removed, or replaced. You can create a volume with docker volume create <name> and then mount it to a container using the -v flag: docker run -v <volume_name>:<container_path> <image>.

What are multi-stage builds in Docker and what are their benefits?

Multi-stage builds allow you to use multiple FROM statements in a single Dockerfile, where each FROM statement starts a new build stage. This is beneficial because you can use an intermediate stage to build your application (e.g., compile code, install dependencies) and then copy only the necessary artifacts to a much smaller final image. This results in smaller final image sizes, improved security (fewer packages), and faster deployments.

How can I share my Docker images with other developers or deploy them?

You can share images by pushing them to Docker Hub (a public registry) after logging in and tagging your image: docker login, docker tag <local_image> <username>/<repo_name>:<tag>, docker push <username>/<repo_name>:<tag>. Alternatively, you can save an image as a .tar file locally with docker image save -o image.tar <image_name> and share that file, which can then be loaded by others using docker image load -i image.tar.

What is the functional difference between RUN and CMD commands in a Dockerfile?

RUN commands execute at build time and are used to build the image itself (e.g., installing packages, compiling code). Each RUN command creates a new layer in the image. CMD specifies the default command that will be executed when a container is started from the image. Only one CMD instruction is allowed per Dockerfile; if multiple are present, only the last one takes effect.

Where can I find a quick reference for common Docker commands?

The article includes a 'TL;DR Cheat Sheet' section that provides a concise list of essential Docker commands for actions like building and running images, managing containers, persisting data, and sharing images. This serves as a handy reference for quick lookups.

Final Words

Docker might seem like a lot at first, but once you get it, it feels like magic. No more “it works on my machine” drama.

So go ahead — experiment, break things, fix them, and deploy like it’s no big deal. Your future self will thank you for learning Docker today!