A Comprehensive Summary of Docker Concepts and
Configurations
1 Introduction
This document summarizes the theoretical concepts and practical configurations of Docker,
as discussed in a detailed conversation. It covers Docker containers, their comparison with
virtual machines (VMs), Docker images, Dockerfiles, and integration with Kubernetes.
Additionally, it includes configuration details for a sample Flask application and a Reac-
t/Node.js project, along with Docker Compose settings.
2 Docker Containers: Theoretical Overview
2.1 What is a Docker Container?
A Docker container is a lightweight, portable unit that packages an application and its
dependencies (code, libraries, runtime) to run consistently across different environments.
Unlike carrying an entire toy box, a container is like a small bag with just the needed
toys, making it efficient and easy to move.
2.2 Docker vs. Virtual Machines (VMs)
• Docker Containers: Share the host operating system’s kernel, making them
lightweight and fast. They only include the application and its dependencies.
• Virtual Machines: Run a full operating system, including a separate kernel,
making them heavier and slower. Each VM requires significant resources (CPU,
RAM, storage).
• Key Differences:
– Containers are more resource-efficient and start in seconds.
– VMs provide stronger isolation by running a full OS.
– Containers are ideal for microservices and scalable applications, while VMs
are better for applications requiring full OS isolation (e.g., banking systems).
2.3 Docker Images and Dockerfiles
• Docker Image: A read-only template containing the application, dependencies,
and runtime environment. Multiple containers can be instantiated from a single
image.
1
• Dockerfile: A script with instructions to build a Docker image. It specifies the
base image, files to copy, dependencies to install, and commands to run.
3 Practical Configuration: Flask Application with Docker
3.1 Project Setup
To demonstrate Docker usage, a simple Flask web application was created. The steps
include creating the application, defining dependencies, and containerizing it.
3.1.1 Step 1: Create the Flask Application
Create a project directory and a Python script (app.py):
1 from flask import Flask
2 app = Flask ( __name__ )
3
4 @app . route ( ’/ ’)
5 def home () :
6 return " Hello , Docker World ! "
7
8 if __name__ == ’ __main__ ’:
9 app . run ( host = ’ 0.0.0.0 ’ , port =5000)
3.1.2 Step 2: Define Dependencies
Create a requirements.txt file to list dependencies:
1 flask
3.1.3 Step 3: Create a Dockerfile
The Dockerfile defines how to build the Docker image:
1 FROM python :3.9
2 WORKDIR / app
3 COPY . / app
4 RUN pip install -r requirements . txt
5 EXPOSE 5000
6 CMD [" python " , " app . py "]
• FROM python:3.9: Uses Python 3.9 as the base image.
• WORKDIR /app: Sets the working directory inside the container.
• COPY . /app: Copies all project files to the /app directory.
• RUN pip install: Installs dependencies from requirements.txt.
• EXPOSE 5000: Exposes port 5000 for the Flask app.
• CMD ["python", "app.py"]: Specifies the command to run the app.
2
3.1.4 Step 4: Build and Run the Docker Image
Build the image and run the container:
1 docker build -t my - flask - app .
2 docker run -p 5000:5000 my - flask - app
Access the app at http://localhost:5000, which displays "Hello, Docker World!".
3.1.5 Step 5: Sharing the Docker Image
To share the image across systems:
• Export the image:
1 docker save -o my - flask - app . tar my - flask - app
• Transfer the .tar file to another machine and import it:
1 docker load -i my - flask - app . tar
• Run the container on the new machine:
1 docker run -p 5000:5000 my - flask - app
3.2 Portability Across Operating Systems
Docker containers are portable across Linux, Windows, and macOS, as they rely on the
Docker engine. On Windows, Docker Desktop uses WSL 2 to run Linux containers,
ensuring compatibility.
4 Docker Compose for Multi-Container Applications
4.1 Overview
Docker Compose is a tool for defining and running multi-container applications using a
YAML file. It simplifies managing multiple containers, such as a frontend and backend.
4.2 Example: React and Node.js Application
A sample project with a React frontend and Node.js backend was discussed. The Docker
Compose configuration orchestrates both services.
4.2.1 Directory Structure
• frontend/: Contains the React application.
• backend/: Contains the Node.js backend with a JSON database.
• docker-compose.yml: Defines the services.
3
4.2.2 Dockerfile for Frontend
1 FROM node :18
2 WORKDIR / app
3 COPY package . json .
4 RUN npm install
5 COPY . .
6 RUN npm run build
7 CMD [" npx " , " serve " , " - s " , " build " , " - l " , "80"]
• COPY package.json .: Copies package.json separately to leverage Docker’s layer
caching, avoiding unnecessary npm install if only code changes.
• RUN npm run build: Builds the React app for production.
• CMD ["npx", "serve", "-s", "build", "-l", "80"]: Serves the built app on
port 80.
4.2.3 Dockerfile for Backend
1 FROM node :18
2 WORKDIR / app
3 COPY package . json .
4 RUN npm install
5 COPY . .
6 EXPOSE 3000
7 CMD [" npm " , " start "]
• Similar structure to the frontend, with EXPOSE 3000 for the backend API.
4.2.4 Docker Compose Configuration
The docker-compose.yml file orchestrates the services:
1 version : ’3 ’
2 services :
3 frontend :
4 build :
5 context : ./ frontend
6 ports :
7 - "8080:80"
8 - "8081:80"
9 depends_on :
10 - backend
11 networks :
12 - my - network
13 backend :
14 build :
15 - context : ./ backend
16 ports :
17 - "3000:3000"
18 networks :
19 - my - network
4
20 networks :
21 my - network :
22 driver : bridge
• services: Defines frontend and backend services.
• build.context: Specifies the directory containing each service’s Dockerfile.
• ports: Maps host ports (e.g., 8080, 8081) to container ports (80).
• dependso n : Ensuresthebackendstartsbef orethef rontend.networks : Createsabridgenetworkf orcomm
4.3 Development Mode with Docker Compose
For development with live code updates, add volumes and override the command:
1 version : ’3 ’
2 services :
3 frontend :
4 build :
5 context : ./ frontend
6 ports :
7 - "8080:80"
8 - "8081:80"
9 depends_on :
10 - backend
11 networks :
12 - my - network
13 volumes :
14 - ./ frontend :/ app
15 command : npm start
16 backend :
17 build :
18 context : ./ backend
19 ports :
20 - "3000:3000"
21 networks :
22 - my - network
23 volumes :
24 - ./ backend / db . json :/ app / db . json
25 networks :
26 my - network :
27 driver : bridge
• volumes: Syncs local code (./frontend:/app) for live updates.
• command: npm start: Runs the React development server with live reloading.
4.4 Interactive Settings in Docker Compose
• stdino pen : true : Keepsstandardinputopenf orinteractiveinput, evenwithoutanattachedtermina
Allocatesapseudo−terminalf orterminal−likebehavior, usef ulf orrunninginteractiveshells.
5
• Without these, containers can still run, but manual interaction (e.g., via docker-compose
run) may not work as expected.
4.5 Detached Mode
Running docker-compose up -d starts containers in detached mode, meaning they run
in the background, freeing the terminal for other tasks. Logs can be viewed with
docker-compose logs.
5 Layer Caching in Docker
Docker uses layer caching to optimize builds:
• Each Dockerfile instruction creates a layer.
• Separating COPY package.json . and RUN npm install from COPY . . ensures
that npm install is only re-run if package.json changes, speeding up rebuilds.
6 Conclusion
Docker provides a lightweight, portable, and efficient way to package and run applications.
Containers share the host OS kernel, making them faster and more resource-efficient than
VMs, which run full operating systems. Dockerfiles define how to build images, and
Docker Compose simplifies multi-container management. Configurations for a Flask app
and a React/Node.js project demonstrate practical usage, with optimizations like layer
caching and development mode settings.