_____                   _             ___     _________  __
 |_   _|__ _ __ _ __ ___ (_)_ __   __ _| \ \   / / ____\ \/ /
   | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | |\ \ / /|  _|  \  /
   | |  __/ |  | | | | | | | | | | (_| | | \ V / | |___ /  \
   |_|\___|_|  |_| |_| |_|_|_| |_|\__,_|_|  \_/  |_____/_/\_\
advanced15 min

Docker Basic Commands: Introduction to Containers

What is Docker?

Docker is an open-source platform that allows you to package, distribute, and run applications in isolated environments called containers. Developed by Solomon Hykes in 2013, it quickly became one of the standard tools in the software world. With Docker, the "it works on my machine" problem disappears because the application is packaged with all its dependencies and runs the same way in every environment.

Unlike virtual machines, containers do not carry their own operating system kernel. Instead, they share the host machine's kernel and contain only the files and libraries necessary for the application to run. This enables containers to start in seconds, consume very few resources, and allow hundreds of containers to run in parallel on the same machine.

Containers vs Virtual Machines

Containers and virtual machines (VMs) are different virtualization approaches:

  • Virtual Machines: Each VM hosts its own OS kernel, libraries, and applications. Runs on a hypervisor. Takes minutes to start and uses gigabytes of memory.
  • Containers: Share the host machine's kernel, contain only the application and its dependencies. Run on a container runtime. Start in seconds and consume resources at the megabyte level.

Containers stand out for their lightness and speed, while VMs are preferred in scenarios requiring full isolation. In modern architectures, containers are mostly used because they align perfectly with the microservice approach.

Docker Installation

# Check if Docker is installed
$ docker --version

# Verify Docker service is running
$ docker info

# First test — Hello World container
$ docker run hello-world

Docker Image Operations

A Docker image is a read-only template containing all the files, libraries, and configuration needed for a container to run. Containers are created from these images.

docker images — List Local Images

# List local images
$ docker images

# Filter a specific image
$ docker images nginx

# Show image sizes
$ docker images --format "table {{.Repository}}	{{.Tag}}	{{.Size}}"

docker pull — Download Images

# Pull an image from Docker Hub
$ docker pull nginx

# Pull a specific version
$ docker pull node:18-alpine

# Pull from a specific registry
$ docker pull ghcr.io/user/app:latest

docker rmi — Remove Images

# Remove an image
$ docker rmi nginx

# Force remove
$ docker rmi -f old-image

# Clean all unused images
$ docker image prune -a

Container Operations

docker run — Create and Run a Container

docker run creates a new container from an image and starts it. It is Docker's most fundamental and frequently used command.

# Run a simple container
$ docker run nginx

# Run in the background (-d: detached)
$ docker run -d nginx

# Run with a name
$ docker run -d --name my-web-server nginx

# Port mapping (-p host:container)
$ docker run -d -p 8080:80 --name web nginx
# Accessible at http://localhost:8080 in browser

# Interactive mode (-it: interactive terminal)
$ docker run -it ubuntu bash

# Auto-remove (container deleted when stopped)
$ docker run --rm -it alpine sh

# Set environment variable
$ docker run -d -e MYSQL_ROOT_PASSWORD=pass123 mysql:8

# Multiple options combined
$ docker run -d   --name database   -p 3306:3306   -e MYSQL_ROOT_PASSWORD=strong_password   -e MYSQL_DATABASE=myapp   -v mysql-data:/var/lib/mysql   mysql:8

docker ps — List Running Containers

# List running containers
$ docker ps

# List all containers (including stopped)
$ docker ps -a

# List only container IDs
$ docker ps -q

# Custom format listing
$ docker ps --format "table {{.Names}}	{{.Status}}	{{.Ports}}"

Container Lifecycle Commands

# Stop a container
$ docker stop my-web-server

# Start a container
$ docker start my-web-server

# Restart a container
$ docker restart my-web-server

# Connect to a running container
$ docker exec -it my-web-server bash

# View container logs
$ docker logs my-web-server

# Follow logs in real-time
$ docker logs -f my-web-server

# Inspect container details
$ docker inspect my-web-server

# Remove a container (must be stopped first)
$ docker stop my-web-server
$ docker rm my-web-server

# Force remove (even while running)
$ docker rm -f my-web-server

# Clean all stopped containers
$ docker container prune

Building Images with Dockerfile

A Dockerfile is a text file used to create your own custom Docker images. Each line creates a layer and defines how the image should be built.

# Dockerfile for a simple Node.js application
# Filename: Dockerfile

# Base image
FROM node:18-alpine

# Working directory
WORKDIR /app

# Copy dependency files
COPY package*.json ./

# Install dependencies
RUN npm install --production

# Copy application files
COPY . .

# Port the application listens on
EXPOSE 3000

# Application start command
CMD ["node", "server.js"]

docker build — Build an Image

# Build an image from Dockerfile in current directory
$ docker build -t myapp:v1 .

# Specify a different Dockerfile
$ docker build -f Dockerfile.prod -t myapp:prod .

# Build with build arguments
$ docker build --build-arg NODE_ENV=production -t myapp:prod .

# Run the built image
$ docker run -d -p 3000:3000 myapp:v1

Docker Volumes (Persistent Data)

Containers are ephemeral by default; when a container is deleted, the data inside it is also lost. Volumes enable data to be stored persistently, independent of the container lifecycle.

# Create a named volume
$ docker volume create data-store

# List volumes
$ docker volume ls

# Run a container with a volume
$ docker run -d   --name database   -v data-store:/var/lib/mysql   mysql:8

# Bind mount a host directory
$ docker run -d   --name web   -v $(pwd)/site:/usr/share/nginx/html   -p 8080:80   nginx

# Inspect volume details
$ docker volume inspect data-store

# Clean unused volumes
$ docker volume prune

Docker Networking Basics

# List networks
$ docker network ls

# Create a custom network
$ docker network create app-network

# Connect a container to a specific network
$ docker run -d --name web --network app-network nginx
$ docker run -d --name api --network app-network node:18

# Containers on the same network can find each other by name
# From web container to api: curl http://api:3000

# Inspect network details
$ docker network inspect app-network

Introduction to Docker Compose

Docker Compose allows you to define and manage multiple containers with a single YAML file. It is ideal for multi-container applications.

# docker-compose.yml example
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./site:/usr/share/nginx/html
    depends_on:
      - api

  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=database
      - DB_PASSWORD=pass123
    depends_on:
      - database

  database:
    image: mysql:8
    environment:
      - MYSQL_ROOT_PASSWORD=pass123
      - MYSQL_DATABASE=myapp
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:

Docker Compose Commands

# Start all services
$ docker compose up -d

# View logs
$ docker compose logs -f

# Stop services
$ docker compose down

# Stop services and remove volumes
$ docker compose down -v

# Restart a specific service
$ docker compose restart api

# View service status
$ docker compose ps

Useful Docker Commands

# View system-wide disk usage
$ docker system df

# Clean all unused resources
$ docker system prune -a

# Copy file from container
$ docker cp my-web-server:/etc/nginx/nginx.conf ./nginx.conf

# Copy file to container
$ docker cp ./index.html my-web-server:/usr/share/nginx/html/

# Monitor container resource usage
$ docker stats

Summary

Docker is an indispensable tool for modern software development and deployment processes. Thanks to container technology, you can run your applications in isolated, portable, and reproducible environments. Creating containers with docker run, building custom images with docker build, managing persistent data with volumes, and orchestrating multi-container applications with Docker Compose — once you learn these fundamental concepts, you can begin leveraging the vast possibilities the container world offers. Your Docker knowledge will be your greatest advantage in advanced topics such as microservice architecture, CI/CD pipelines, and cloud deployments.