Learn 🧠 All Concepts (20) 🤖 What is an LLM? 📚 RAG Explained ⚡ AI Agents 💻 Run AI Locally 🇮🇳 AI in India 📖 Learn Tracks 🔧 DevOps Track ⚙️ AI Ops Track 🗺️ AI Engineer Roadmap
Tools 🔧 AI Tools Directory 🔓 Open Source AI ⭐ Top GitHub Repos ✦ Claude Skill Repos 🚀 Ready-to-Deploy Projects
Build 🏗️ Build Hub 🎯 Master Prompts 🧩 RAG Agents 🚀 App Megaprompts
Workflows ⚡ All Workflows (22) 🎥 Text to Video 🎞️ Image to Video 🔊 Text to Speech ♻️ Automation
Resources 🧪 Colab Notebooks ⚙️ n8n Workflows 📈 Algo Trading 💰 Passive Income
🗂️ Browse All Topics About AItheGuru
Learn Linux for Production Support Priya containerises everything
Linux for Production Support Ch 24 / 32 Intermediate
🐳

Priya containerises everything

Docker, Dockerfile, Docker Compose — running apps the modern way

⏱ 14 min 6 commands 5 takeaways
🐳
In this chapter
Priya
Backend engineer, moving to containers
The story

Priya had been running applications directly on Linux servers for 3 years. Start the app, configure systemd, manage dependencies. Every server was slightly different. What worked on staging sometimes failed on production because a library version was different.

Then she discovered Docker. Two weeks later she said: I will never go back.

WHAT DOCKER SOLVES

The problem: software runs differently on different machines because dependencies, library versions, and configurations differ. The solution: package the application AND its entire environment into a container that runs identically everywhere.

Without Docker: "Works on my machine" → hours debugging environment differences
With Docker:    Same container image runs on laptop, staging, production — identical every time

INSTALLING DOCKER

# Ubuntu/Debian:
sudo apt update
sudo apt install -y docker.io
sudo systemctl enable docker && sudo systemctl start docker
sudo usermod -aG docker $USER   # run docker without sudo (log out and back in)
# Verify:
docker --version
docker run hello-world          # test — downloads and runs a tiny container

CORE CONCEPTS

An image is a blueprint — like an ISO file. A container is a running instance of that image — like a VM running from an ISO. You can run many containers from the same image.

docker images                   # list downloaded images
docker ps                       # list running containers
docker ps -a                    # list all containers including stopped ones

RUNNING YOUR FIRST REAL CONTAINERS

# Run nginx web server:
docker run -d -p 80:80 --name webserver nginx
# -d = detached (background)
# -p 80:80 = map host port 80 to container port 80
# --name = give it a name
# Run PostgreSQL database:
docker run -d \
    -p 5432:5432 \
    --name mydb \
    -e POSTGRES_PASSWORD=secret \
    -e POSTGRES_DB=appdb \
    -v pgdata:/var/lib/postgresql/data \
    postgres:15
# -e = environment variable
# -v pgdata:/var/... = persistent volume (data survives container restart)
# Run Redis:
docker run -d -p 6379:6379 --name myredis redis:7

MANAGING CONTAINERS

docker stop webserver           # stop a container
docker start webserver          # start a stopped container
docker restart webserver        # restart
docker rm webserver             # delete container (must be stopped first)
docker rm -f webserver          # force delete even if running
docker logs webserver           # see container logs
docker logs -f webserver        # follow logs live (like tail -f)
docker exec -it webserver bash  # open a shell inside the running container

WRITING A DOCKERFILE

A Dockerfile is the recipe for building your own image:

# Dockerfile
FROM python:3.11-slim           # start from official Python image
WORKDIR /app                    # set working directory inside container
COPY requirements.txt .         # copy requirements first (caching optimisation)
RUN pip install -r requirements.txt
COPY . .                        # copy rest of your code
EXPOSE 8080                     # document which port the app uses
USER nobody                     # never run as root
CMD ["python", "app.py"]        # command to run when container starts
# Build it:
docker build -t myapp:v1.0 .
# Run it:
docker run -d -p 8080:8080 --name myapp myapp:v1.0

DOCKER COMPOSE — MULTIPLE CONTAINERS TOGETHER

Most apps need multiple services. Docker Compose starts them all with one command:

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports: ["8080:8080"]
    environment:
      - DB_HOST=db
      - DB_PASSWORD=secret
    depends_on: [db, redis]
    restart: always
  db:
    image: postgres:15
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=appdb
    volumes:
      - pgdata:/var/lib/postgresql/data
  redis:
    image: redis:7
    restart: always
volumes:
  pgdata:
# Commands:
docker compose up -d            # start everything in background
docker compose down             # stop everything
docker compose logs -f app      # follow app logs
docker compose ps               # see status of all services
docker compose restart app      # restart just one service

DEBUGGING CONTAINERS

# Container not starting? See why:
docker logs myapp
# Container running but app not working? Get inside:
docker exec -it myapp bash
# Now you are inside the container — check files, test connections, run commands
# See resource usage:
docker stats                    # live CPU/memory/network per container
# Inspect a container's full config:
docker inspect myapp | grep -A5 "IPAddress"
# What ports is a container using?
docker port myapp

CLEANING UP

docker system prune             # remove stopped containers, unused images, networks
docker system prune -a          # remove everything not currently running
docker volume prune             # remove unused volumes
# See disk usage:
docker system df

Priya containerised her first application in one afternoon. The next deployment to production was the same docker compose up -d she ran on her laptop. No environment differences. No surprise failures. The app ran identically in every environment.

Key takeaways

docker run -d -p 8080:8080 --name myapp image runs a container in background with port mapping

docker logs -f containername follows container logs live — same as tail -f for a regular process

docker exec -it containername bash opens a shell inside a running container for debugging

Docker Compose starts multiple containers together with one command — database, app, and cache all at once

docker system prune cleans up stopped containers and unused images — run this when disk fills up

Commands from this chapter
$ docker ps -a
List all containers including stopped — like Services.msc showing all services
$ docker run -d -p 80:80 --name web nginx
Run nginx container in background on port 80
$ docker logs -f myapp
Follow container logs live — like tail -f for containers
$ docker exec -it myapp bash
Open a shell inside running container for debugging
$ docker compose up -d
Start all services defined in docker-compose.yml in background
$ docker system prune -a
Remove all stopped containers and unused images to free disk