Docker has become one of the most popular tools for modern application development and deployment. Whether you are a PHP/Laravel developer, Node.js developer, React developer, Next.js developer, or DevOps beginner, understanding Docker can make your development and deployment workflow much easier.

In this Docker tutorial for beginners, we will learn:

  • What is Docker?
  • What is a Docker container?
  • What is a Docker image?
  • Docker image vs. container
  • Important Docker commands
  • Dockerfile
  • Docker volumes
  • Docker networking
  • Docker Compose
  • Docker Compose commands
  • Docker vs Virtual Machine
  • Docker and CI/CD
  • Real-world Docker workflow

Let's get started.

What is Docker?

Docker is a platform that allows developers to build, package, run, and deploy applications inside containers.

A Docker container packages an application together with the dependencies it needs to run.

For example, a web application might require:

  • Source code
  • PHP or Node.js
  • Libraries
  • Dependencies
  • Configuration
  • Database connectivity

Instead of configuring everything manually on every machine, Docker allows us to create a consistent environment.

    A simple way to understand Docker is:

Application
    +
Dependencies
    +
Runtime
    ↓
Docker Image
    ↓
Docker Container

This makes applications easier to develop, test, share, and deploy.

What is a Docker Container?

A Docker container is a lightweight and isolated environment in which an application can run.

The container contains the application and the dependencies required by that application.

For example:

Docker Container
├── Application
├── Runtime
├── Libraries
├── Dependencies
└── Configuration

Containers are commonly used to run:

  • Laravel applications
  • Node.js applications
  • React applications
  • Next.js applications
  • MySQL
  • MongoDB
  • Redis
  • Nginx
  • Apache
  • Microservices

Properties of Docker Containers

1. Portable

One of the biggest advantages of containers is portability.

A Docker container can be moved between environments that support Docker.

For example:

Developer Laptop
       ↓
Docker Container
       ↓
Testing Server
       ↓
Production Server

This helps reduce the common problem:

"It works on my machine."

2. Lightweight

Containers are generally lightweight compared with traditional virtual machines.

They share the host operating system's kernel instead of requiring a complete guest operating system for every application.

As a result, containers can usually start quickly and use fewer resources than traditional virtual machines.

3. Isolated

Containers provide an isolated environment for applications.

For example, you could run:

Container 1 → Laravel
Container 2 → Node.js
Container 3 → MySQL
Container 4 → Redis

Each service can have its own environment and dependencies.

What is a Docker Image?

A Docker image is a read-only template used to create containers.

An image contains everything needed to create a container, including application files, dependencies, configuration, and other required components.

The easiest way to remember the difference is:

Docker Image     = Blueprint
Docker Container = Running Instance

For example:

Docker Image
     ↓
 docker run
     ↓
Docker Container

One image can be used to create multiple containers.

              Docker Image
                   |
        ┌──────────┼──────────┐
        ↓          ↓          ↓
   Container 1  Container 2  Container 3

Docker Image vs Docker Container

Many beginners confuse Docker images and containers.

Here is a simple comparison:

Docker ImageDocker Container
Blueprint/templateRunning instance
Used to create containersCreated from an image
Read-only templateHas a writable container layer
Can be stored and sharedCan be started and stopped
Example: node:20Example: my-node-app

Remember:

IMAGE
  ↓
docker run
  ↓
CONTAINER

How to Install Docker

Docker can be installed using Docker Desktop on Windows and macOS.

On Linux, Docker Engine can be installed directly.

After installation, check whether Docker is working:

docker --version

You can also run:

docker info

If Docker is installed and running correctly, Docker will display information about the installation.

Important Docker Commands

Now let's look at some of the most commonly used Docker commands.

1. Pull an Image from Docker Hub

Docker Hub contains many publicly available Docker images.

To pull an image:

docker pull IMAGE_NAME

Example:

docker pull ubuntu

You can also pull specific versions or tags:

docker pull node:20

2. List Docker Images

To see all downloaded Docker images:

docker images

You can also use:

docker image ls

Example output conceptually looks like:

REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
node          20        xxxxxxxx       ...           ...
ubuntu        latest    xxxxxxxx       ...           ...

3. Create and Run a Container

Use:

docker run IMAGE_NAME

Example:

docker run ubuntu

The docker run command creates a new container from the specified image and starts it.

4. Run a Container in Interactive Mode

If you want to interact with the container terminal:

docker run -it IMAGE_NAME

Example:

docker run -it ubuntu

Here:

-i = Interactive
-t = Allocate a terminal

This is particularly useful when working with command-line environments.

5. Run a Container in Detached Mode

To run a container in the background:

docker run -d IMAGE_NAME

Example:

docker run -d nginx

The -d option means detached mode.

6. Give a Custom Name to a Container

Docker automatically generates a container name if you don't specify one.

You can provide your own name:

docker run --name CONTAINER_NAME -d IMAGE_NAME

Example:

docker run --name my-nginx -d nginx

Now you can refer to the container using:

my-nginx

instead of its container ID.

7. Show Running Containers

To see currently running containers:

docker ps

This is one of the most commonly used Docker commands.

8. Show All Containers

To see both running and stopped containers:

docker ps -a

This is useful when a container has stopped and you want to investigate it.

9. Start an Existing Container

To start an existing stopped container:

docker start CONTAINER_NAME

or:

docker start CONTAINER_ID

Example:

docker start my-nginx

10. Stop a Container

To stop a running container:

docker stop CONTAINER_NAME

or:

docker stop CONTAINER_ID

Example:

docker stop my-ngin

11. Restart a Container

To restart an existing container:

docker restart CONTAINER_NAME

Example:

docker restart my-nginx

12. Remove a Container

To remove a container:

docker rm CONTAINER_NAME

or:

docker rm CONTAINER_ID

If the container is still running, stop it first:

docker stop my-nginx

Then:

docker rm my-nginx

13. Remove a Docker Image

To remove an image:

docker rmi IMAGE_NAME

Example:

docker rmi ubuntu

You may need to remove containers that depend on an image before Docker allows the image to be deleted.

14. Port Binding in Docker

Applications inside containers can listen on their own ports.

To make a container port available through the host machine, we use port mapping.

Syntax:

docker run -p HOST_PORT:CONTAINER_PORT IMAGE_NAME

Example:

docker run -p 8080:3033 my-app

This means:

Host Machine
localhost:8080
       ↓
Docker Container
port 3033

So when you visit:

http://localhost:8080

the request can be forwarded to port 3033 inside the container.

15. View Container Logs

To view logs:

docker logs CONTAINER_ID

Example:

docker logs my-app

To continuously watch the logs:

docker logs -f my-app

The -f option follows the log output.

16. Execute Commands Inside a Container

If you want to enter a running container using Bash:

docker exec -it CONTAINER_ID /bin/bash

Example:

docker exec -it my-container /bin/bash

Some lightweight images don't include Bash.

In that case, use:

docker exec -it CONTAINER_ID /bin/sh

Example:

docker exec -it my-container /bin/sh

Docker Networking

Docker networking allows containers to communicate with each other and with external networks.

To see available networks:

docker network ls

Create a Docker Network

You can create your own network:

docker network create NETWORK_NAME

Example:

docker network create my-network

Remove a Docker Network

To remove a network:

docker network rm NETWORK_NAME

Example:

docker network rm my-network

Docker Volumes

Containers are not designed to be the primary place for storing persistent application data.

For persistent data, Docker provides volumes.

For example, databases such as MySQL and MongoDB commonly use volumes to make sure their data remains available even if the container is recreated.

Container
    ↓
 Volume
    ↓
Persistent Data

Volumes are commonly used for:

  • Database data

  • Uploaded files

  • Application data

  • Persistent storage

Types of Docker Volumes

1. Named Volume

A named volume has a specific name.

docker run -v VOLUME_NAME:CONTAINER_PATH IMAGE_NAME

Example:

docker run -v mysql_data:/var/lib/mysql mysql

Here:

mysql_data
     ↓
/var/lib/mysql

2. Anonymous Volume

An anonymous volume doesn't have a custom name.

docker run -v CONTAINER_PATH IMAGE_NAME

Example:

docker run -v /var/lib/mysql mysql

Docker automatically creates a volume for the specified container path.

3. Bind Mount

A bind mount maps a directory from the host machine to a directory inside the container.

Syntax:

docker run -v HOST_DIRECTORY:CONTAINER_DIRECTORY IMAGE_NAME

Example:

docker run -v ./data:/app/data my-app

This maps:

Host
./data
  ↓
Container
/app/data

Bind mounts are especially useful during development.

List Docker Volumes

To see available volumes:

docker volume ls

Remove Unused Docker Volumes

To remove unused volumes:

docker volume prune

Warning: Be careful with this command. Make sure important data is not stored in an unused volume before removing it.

What is a Dockerfile?

A Dockerfile contains instructions that Docker uses to build an image.

It defines things such as:

  • Base image
  • Working directory
  • Application files
  • Dependencies
  • Commands
  • Exposed ports
  • Startup command

Example:

FROM node:20

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

Common Dockerfile Instructions

InstructionPurpose
FROMDefines the base image
WORKDIRSets the working directory
COPYCopies files into the image
ADDAdds files/directories
RUNExecutes commands while building
EXPOSEDocuments the application port
CMDDefault command when the container starts
ENTRYPOINTDefines the main executable

Build a Docker Image

If your Dockerfile is in the current directory:

docker build -t my-app .

Here:

docker build
     ↓
-t my-app
     ↓
Image Name
     ↓
.
     ↓
Current Directory

After building the image, you can run it:

docker run -p 3000:3000 my-app

What is Docker Compose?

Docker Compose is a tool used to define and run multi-container applications.

Imagine an application containing:

Frontend
Backend
Database
Redis

Running every service manually can become difficult.

Docker Compose allows us to define these services inside a YAML file.

Common Compose files include:

compose.yml

or:

docker-compose.yml

Example Docker Compose File

For example:

services:

  frontend:
    image: nginx
    ports:
      - "8080:80"

  backend:
    image: node:20

  database:
    image: mysql:8

Here we have three services:

Frontend
Backend
Database

Docker Compose can manage them together.

Docker Compose Commands

Start Services

docker compose up

Start Services in Detached Mode

docker compose up -d

Use a Specific YAML File

docker compose -f filename.yml up -d

Example:

docker compose -f docker-compose.yml up -d

Stop and Remove Compose Services

docker compose down

For a specific YAML file:

docker compose -f filename.yml down

Example:

docker compose -f docker-compose.yml down

Docker Compose Networking

Docker Compose automatically creates a network for the services defined in a Compose application.

For example:

       Docker Compose Network
                |
       ┌────────┼────────┐
       ↓        ↓        ↓
   Frontend   Backend   Database

Services can communicate with each other using their service names.

For example, if the database service is named:

database:
  image: mysql:8

the backend can generally use:

database

as the database hostname within the Compose network.

This means you normally don't need to manually create a network for a basic Docker Compose application.

Docker vs Virtual Machine

Docker containers and virtual machines are different technologies.

Docker ContainerVirtual Machine
LightweightHeavier
Starts quicklyUsually slower
Shares host OS kernelIncludes a complete guest OS
Uses fewer resourcesUses more resources
Smaller deployment sizeLarger deployment size

A simplified architecture looks like this:

Virtual Machine

Hardware
   ↓
Host OS
   ↓
Hypervisor
   ↓
Guest OS
   ↓
Application

Docker

Hardware
   ↓
Host OS
   ↓
Docker Engine
   ↓
Container
   ↓
Application

Docker Desktop

Docker Desktop provides a convenient way to use Docker on Windows and macOS.

When running Linux containers on Windows or macOS, Docker Desktop uses a Linux-based virtualized environment because Linux containers rely on the Linux kernel.

Docker + CI/CD

Docker is commonly used together with CI/CD pipelines.

CI/CD stands for:

CI = Continuous Integration
CD = Continuous Delivery / Continuous Deployment

What is Continuous Integration?

Continuous Integration means developers frequently integrate their code into a shared repository.

Automated processes can then build and test the application.

Code Push
    ↓
Build
    ↓
Test
    ↓
Code Validation

Popular CI/CD platforms include:

  • GitHub Actions

  • GitLab CI/CD

  • Jenkins

  • Bitbucket Pipelines

  • Azure DevOps

What is Continuous Delivery?

Continuous Delivery means that successfully tested code is automatically prepared and kept ready for deployment.

Code
 ↓
Build
 ↓
Test
 ↓
Package
 ↓
Ready for Deployment

What is Continuous Deployment?

Continuous Deployment takes automation one step further.

Successfully tested changes can automatically be deployed to production.

Developer
    ↓
Git Push
    ↓
CI/CD Pipeline
    ↓
Build
    ↓
Test
    ↓
Docker Image
    ↓
Deploy
    ↓
Production

Docker and CI/CD Workflow

A common Docker-based CI/CD workflow looks like this:

Developer
    │
    │ git push
    ↓
GitHub / GitLab
    │
    ↓
CI/CD Pipeline
    │
    ├── Install Dependencies
    ├── Run Tests
    ├── Build Docker Image
    └── Push Docker Image
              │
              ↓
        Docker Registry
              │
              ↓
       Production Server
              │
              ↓
       Docker Container

This approach helps keep development, testing, and production environments consistent.

Real-World Docker Application

A modern web application can contain multiple services.

For example:

                 Docker Compose
                       │
        ┌──────────────┼──────────────┐
        ↓              ↓              ↓
     Frontend        Backend        Database
     Next.js         Laravel          MySQL
        │              │              │
        └──────────────┼──────────────┘
                       │
                  Docker Network
                       │
                    Volumes
                       │
                 Persistent Data

For example:

  • Frontend: Next.js
  • Backend: Laravel
  • Database: MySQL
  • Cache: Redis
  • Web Server: Nginx

Each service can run in its own container.

Docker Command Cheat Sheet

Images

docker pull IMAGE
docker images
docker image ls
docker rmi IMAGE

Containers

docker run IMAGE
docker run -it IMAGE
docker run -d IMAGE
docker run --name NAME -d IMAGE
docker ps
docker ps -a
docker start CONTAINER
docker stop CONTAINER
docker restart CONTAINER
docker rm CONTAINER

Ports

docker run -p HOST_PORT:CONTAINER_PORT IMAGE

Example:

docker run -p 8080:3000 my-app

Logs and Exec

docker logs CONTAINER
docker logs -f CONTAINER
docker exec -it CONTAINER /bin/bash
docker exec -it CONTAINER /bin/sh

Networks

docker network ls
docker network create NETWORK_NAME
docker network rm NETWORK_NAME

Volumes

docker volume ls
docker volume prune

Build

docker build -t IMAGE_NAME .

Docker Compose

docker compose up
docker compose up -d
docker compose down
docker compose -f docker-compose.yml up -d
docker compose -f docker-compose.yml down

Docker Learning Roadmap

If you are a beginner, learn Docker in this order:

1. Docker Basics
       ↓
2. Docker Images
       ↓
3. Docker Containers
       ↓
4. Docker Commands
       ↓
5. Dockerfile
       ↓
6. Port Mapping
       ↓
7. Docker Volumes
       ↓
8. Docker Networking
       ↓
9. Docker Compose
       ↓
10. Docker Registry
       ↓
11. Docker + CI/CD
       ↓
12. Docker Deployment

Important Docker Concepts to Remember

Docker
  │
  ├── Image
  │      └── Blueprint
  │
  ├── Container
  │      └── Running instance of an image
  │
  ├── Dockerfile
  │      └── Instructions to build an image
  │
  ├── Volume
  │      └── Persistent storage
  │
  ├── Network
  │      └── Container communication
  │
  └── Docker Compose
         └── Manage multiple services