Docker Hub and Docker Compose
A public (or private) cloud registry of Docker images.
Used for searching and sharing ready-made images.
Address: https://hub.docker.com
When selecting an image, look for:
Each image has:
On Docker Hub we can find an image with Python:
docker.io/library/python:3.12-slim
Breakdown:
| Part | Meaning |
|---|---|
| docker.io | registry (Docker Hub) |
| library | namespace (official images) |
| python | image name |
| 3.12-slim | tag (version + variant) |
On the Python image page we can find e.g.:
3.123.12-slim3.12-alpine3.12-bookwormlatest| Tag | Meaning |
|---|---|
| 3.12 | full version |
| slim | smaller version (fewer packages) |
| alpine | very small image (Alpine Linux) |
| bookworm | Debian version |
| latest | latest stable version |
On the image's GitHub page we can find the Dockerfile.
Typical Dockerfile:
FROM debian:bookworm-slim
ENV PYTHON_VERSION 3.12.2
RUN apt-get update && apt-get install -y \
build-essential \
libssl-dev
CMD ["python3"]
FROM → base imageRUN → what is installedENV → environment variablesCMD → default commandThis tells us:
A tool for configuring multi-container applications.
Web applications typically consist of multiple services:
HTML
|
+----------+
| Frontend |
+----------+
| REST
+----------+ NFS +----------+
| Backend |-------| Storage |
+----------+ +----------+
| postgres
+----------+
| Database |
+----------+
A typical web application consists of multiple components. Each component has different requirements.
E.g.
Docker Compose allows you to:
Uses a YAML file:
docker-compose.yml
services:
service_name:
image: image_name
ports:
- "host_port:container_port"
volumes:
- volume_name:/path/in/container
environment:
VARIABLE: value
depends_on:
- other_service
volumes:
volume_name:
Start the application:
docker compose up -d
Stop it:
docker compose down
image – Docker imageports – port mappingenvironment – environment variablesvolumes – persistent storagenetworks – networkscmd: how to startOn Linux, typically:
/var/lib/docker/volumes/
Custom networks between containers.
projectname_default
Within it:
WordPress requires:
docker rundocker network create wordpress_net
docker volume create db_data
docker volume create wordpress_data
docker run -d \
--name wordpress_db \
--restart always \
--network wordpress_net \
-v db_data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=example \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppassword \
mysql:8.0
docker run -d \
--name wordpress_app \
--restart always \
--network wordpress_net \
-p 8080:80 \
-v wordpress_data:/var/www/html \
-e WORDPRESS_DB_HOST=wordpress_db:3306 \
-e WORDPRESS_DB_USER=wpuser \
-e WORDPRESS_DB_PASSWORD=wppassword \
-e WORDPRESS_DB_NAME=wordpress \
wordpress:latest
services:
db:
image: mysql:8.0
container_name: wordpress_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppassword
volumes:
- db_data:/var/lib/mysql
wordpress:
image: wordpress:latest
container_name: wordpress_app
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppassword
WORDPRESS_DB_NAME: wordpress
depends_on:
- db
volumes:
- wordpress_data:/var/www/html
volumes:
db_data:
wordpress_data:
depends_on only waits for the container to start, not for when the database is ready.
Solution – healthcheck condition:
services:
db:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
depends_on:
db:
condition: service_healthy
WordPress will only start once MySQL successfully responds to the ping.
Docker's native tool for orchestrating containers in a cluster of multiple servers.
Allows:
Internet
+----------------+ +---------+ +---------+
| Leader Manager | | Manager | | Manager |
+----------------+ +---------+ +---------+
+--------+ +--------+ +--------+
| Worker | | Worker | | Worker |
+--------+ +--------+ +--------+
+-----+ +-----+
| NAS | | SAN |
+-----+ +-----+