Comprehensive Docker Tutorial: Installation, Commands, Image Management, Networking, Dockerfile, Compose, Registry, and Advanced Practices
This extensive guide covers Docker fundamentals, container concepts, installation steps, basic and advanced commands, image lifecycle, volume handling, Dockerfile creation, networking options, Docker Compose orchestration, private registries, Harbor deployment, best‑practice recommendations, and monitoring techniques, providing a complete reference for container‑based development and operations.
1 Container Introduction
Linux containers isolate a set of processes from the rest of the system, running from a specific image that provides all required files, ensuring portability and consistency from development through testing to production.
1.1 What is a Linux Container 1.2 Are containers just virtualization? 1.3 Brief history of container technology
1.1 What is a Linux Container
Linux containers are isolated processes that run from a separate image, containing all application dependencies, making them portable across environments.
When developing an application on a laptop with a specific configuration, containers ensure the same environment can be reproduced on other developers' machines, testing, and production without recreating the server setup.
1.2 Are containers just virtualization?
Virtualization allows multiple operating systems to run on a single host, while containers share the same kernel and isolate application processes.
Containers provide a lightweight alternative to full virtual machines, enabling dense deployment of applications on limited resources.
1.3 Container Development History
The concept originated in 2000 as FreeBSD jail, evolved through VServer in 2001, and later formed the basis of modern Linux containers.
2 What is Docker?
Docker refers to the open‑source container technology, the community project, and the company Docker Inc. that supports it.
Docker provides containerization technology that enables creation and use of Linux containers.
Docker treats containers as lightweight, modular virtual machines, offering flexibility for creation, deployment, and migration across environments.
2.1 How Docker Works
Docker uses Linux kernel features such as cgroups and namespaces to isolate processes, providing independent execution of multiple applications.
2.2 Is Docker the Same as Traditional Linux Containers?
Initially built on LXC, Docker has diverged to provide additional tooling for building, transferring, and versioning images.
2.3 Docker's Goal
Docker's primary goal is "Build, Ship and Run any App, Anywhere".
3 Installing Docker
Environment description:
# Need two machines for installation
[root@docker01 ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@docker01 ~]# uname -r
3.10.0-327.el7.x86_64
[root@docker01 ~]# hostname -I
10.0.0.100 172.16.1.100
[root@docker02 ~]# hostname -I
10.0.0.101 172.16.1.101Perform the following on both nodes:
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
yum install docker-ce -yModify the Docker service to listen on a remote port:
# Edit startup file to listen on remote port
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.100:2375
systemctl daemon-reload
systemctl enable docker.service
systemctl restart docker.service
# Verify startup
ps -ef | grep dockerdTest from the second host:
[root@docker02 ~]# docker -H 10.0.0.100 info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.12.0-ce
Storage Driver: devicemapper
...3.1 Basic Docker Commands
Check Docker version:
# docker version
Client:
Version: 17.12.0-ce
API version: 1.35
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 27 20:10:14 2017
OS/Arch: linux/amd64
Server:
Engine:
Version: 17.12.0-ce
API version: 1.35 (minimum version 1.12)
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 27 20:12:46 2017
OS/Arch: linux/amd64
Experimental: falseConfigure image registry mirrors:
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}3.2 Starting the First Container
# docker run -d -p 80:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e7bb522d92ff: Pull complete
6edc05228666: Pull complete
cd866a17e81f: Pull complete
Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
Status: Downloaded newer image for nginx:latest
8d8f81da12b5c10af6ba1a5d07f4abc041cb95b01f3d632c3d638922800b0b4d
# After container starts, test via browserParameter explanation table:
Parameter
Description
run
Create and run a container
-d
Run in background
-p
Port mapping
nginx
Image name
3.3 Docker Image Lifecycle
4 Docker Image Operations
4.1 Search Official Repository Images
# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 3992 [OK]
ansible/centos7-ansible Ansible on Centos7 1054.2 Pull an Image
# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
af4b0a2388c6: Downloading 34.65MB/73.67MB4.3 Export an Image
# docker image save centos > docker-centos.tar.gz4.4 Delete an Image
# docker image rm centos:latest
# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3f8a4339aadd 5 weeks ago 108MB4.5 Import an Image
# docker image load -i docker-centos.tar.gz
e15afa4858b6: Loading layer 215.8MB/215.8MB
Loaded image: centos:latest4.6 Inspect Image Details
# docker image inspect centos5 Daily Container Management
5.1 Start/Stop Containers
# docker run nginx
# docker create centos:latest /bin/bash
# docker start <container_name>
# docker run -d -p 8888:80 nginx:latest
# docker container ls
# docker ps -a5.2 Enter a Container
# docker run -it -p 80:80 nginx
# docker exec -it <container> /bin/bash
# docker attach <container_id>5.3 Delete All Containers
# docker rm -f `docker ps -a -q`5.4 Port Mapping on Startup
# docker run -d -p 8888:80 nginx:latestParameter
Description
-p hostPort:containerPort
Port mapping, e.g., -p 8080:80
-p ip:hostPort:containerPort
Specify listening address
-p ip::containerPort
Random host port
-p hostPort:containerPort:udp
Specify protocol
-p 81:80 -p 443:443
Multiple mappings
6 Docker Volume Management
6.1 Create Volume on Mount
# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latestWrite data on host and verify:
# echo "http://www.nmtui.com" > /data/index.html
# curl 10.0.0.1006.2 Create Volume Then Mount
# docker volume create
f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
# docker volume ls
DRIVER VOLUME NAME
local f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b835216.3 Save Container as Image
# docker pull centos:6.8
# docker run -it -p 1022:22 centos:6.8 /bin/bash
# yum install openssh-server -y
# echo "root:123456" | chpasswd
# /etc/init.d/sshd start
# docker commit brave_mcclintock centos6-ssh
# docker run -d -p 1122:22 centos6-ssh:latest /usr/sbin/sshd -D7 Dockerfile Automated Image Build
Example Dockerfile:
FROM centos:6.8
RUN yum install openssh-server -y
RUN echo "root:123456" | chpasswd
RUN /etc/init.d/sshd start
CMD ["/usr/sbin/sshd","-D"]Build and run:
# docker image build -t centos6.8-ssh .
# docker run -d -p 2022:22 centos6.8-ssh-b8 Image Layering in Docker
Docker builds new images by stacking layers on top of a base image; each installed package adds a new read‑only layer, while the topmost layer is writable.
8.1 Why Images Are Layered
Layering enables sharing of common base layers across many images, reducing disk usage and memory footprint.
8.2 Writable Container Layer
When a container starts, a writable layer is added on top of the read‑only image layers.
8.3 Details of Container Layer Operations
File Operation
Description
Add File
New file is added to the writable layer.
Read File
Docker searches layers from top to bottom, copies the file to the writable layer, then reads it.
Modify File
File is copied to the writable layer before modification (copy‑on‑write).
Delete File
Deletion is recorded in the writable layer without removing the original file from lower layers.
9 Running Zabbix Server with Docker
9.1 Container Inter‑Connection
# docker run -d -p 80:80 nginx
# docker run -it --link quirky_brown:web01 centos-ssh /bin/bash
# ping web019.2 Start Zabbix Containers
# MySQL container
docker run --name mysql-server -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" -d mysql:5.7 --character-set-server=utf8 --collation-server=utf8_bin
# Java gateway
docker run --name zabbix-java-gateway -d zabbix/zabbix-java-gateway:latest
# Zabbix server (MySQL backend)
docker run --name zabbix-server-mysql -e DB_SERVER_HOST="mysql-server" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" -e ZBX_JAVAGATEWAY="zabbix-java-gateway" --link mysql-server:mysql --link zabbix-java-gateway:zabbix-java-gateway -p 10051:10051 -d zabbix/zabbix-server-mysql:latest
# Zabbix web frontend
docker run --name zabbix-web-nginx-mysql -e DB_SERVER_HOST="mysql-server" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" --link mysql-server:mysql --link zabbix-server-mysql:zabbix-server -p 80:80 -d zabbix/zabbix-web-nginx-mysql:latest9.3 Zabbix API Example
# Get token
curl -s -X POST -H 'Content-Type:application/json' -d '{
"jsonrpc": "2.0",
"method": "user.login",
"params": {"user": "Admin", "password": "zabbix"},
"id": 1
}' http://10.0.0.100/api_jsonrpc.php10 Docker Registry
10.1 Create a Simple Registry
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registryConfigure Docker daemon to allow insecure registry:
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.100:5000"]
}Tag and push an image:
# docker tag busybox:latest 10.0.0.100:5000/clsn/busybox:1.0
# docker push 10.0.0.100:5000/clsn/busybox10.2 Registry with Basic Authentication
# yum install httpd-tools -y
mkdir -p /opt/registry-var/auth/
htpasswd -Bbn clsn 123456 > /opt/registry-var/auth/htpasswd
# Run registry with auth
docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registryLogin and push:
# docker login 10.0.0.100:5000
Username: clsn
Password: 123456
Login Succeeded
# docker push 10.0.0.100:5000/clsn/busybox11 Docker‑Compose Orchestration
11.1 Install Docker‑Compose
# yum install -y python2-pip
pip install docker-compose11.2 Compose a WordPress Stack
version: '3'
services:
db:
image: mysql:5.7
volumes:
- /data/db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- /data/web_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpressStart the stack:
# docker-compose up -d11.3 HAProxy as a Load Balancer for Multiple WordPress Instances
# yum install haproxy -y
# Edit /etc/haproxy/haproxy.cfg (example excerpt)
frontend frontend_www_example_com
bind 10.0.0.100:8000
default_backend backend_www_example_com
backend backend_www_example_com
balance roundrobin
server web-node1 10.0.0.100:32768 check
server web-node2 10.0.0.100:32769 checkStart HAProxy:
# systemctl start haproxy
# systemctl enable haproxy11.4 Control HAProxy via socat
# yum install socat.x86_64 -y
# echo "disable server backend_www_example_com/web-node2" | socat stdio /var/lib/haproxy/stats12 Restart Docker Service Without Stopping Containers
Option 1 – set containers to always restart: # docker run --restart=always ... Option 2 – enable live‑restore in daemon.json:
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"graph": "/opt/mydocker",
"insecure-registries": ["10.0.0.100:5000"],
"live-restore": true
}13 Docker Networking Types
Type
Description
None
No network configuration for the container (‑‑net=none)
Container
Share another container's network namespace (‑‑net=container:ID)
Host
Share the host's network namespace (‑‑net=host)
Bridge
Docker's default NAT network model
13.1 Bridge (default)
Each container gets its own network namespace and is attached to a virtual bridge on the host.
13.2 No Network
# docker run -it --network none busybox /bin/sh
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...13.3 Share Another Container's Network
# docker run -it --network container:mywordpress_db_1 busybox /bin/sh
# ip a
105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth013.4 Host Network
# docker run -it --network host busybox /bin/sh13.5 List Networks
# docker network list
NETWORK ID NAME DRIVER SCOPE
b15e8a720d3b bridge bridge local
345d65b4c2a0 host host local
bc5e2a32bb55 mywordpress_default bridge local
ebf76eea91bb none null local13.6 Assign Independent IP with pipework
# wget https://github.com/jpetazzo/pipework/archive/master.zip
unzip master.zip
cp pipework-master/pipework /usr/local/bin/
chmod +x /usr/local/bin/pipework
# Configure bridge br0 and assign IP 10.0.0.100
# Run container and assign IP 10.0.0.220/24
pipework br0 $(docker run -d -p 6880:80 --name httpd_pw httpd) 10.0.0.220/[email protected]13.7 macvlan for Cross‑Host Communication
# docker network create --driver macvlan --subnet 10.1.0.0/24 --gateway 10.1.0.254 -o parent=eth0 macvlan_1
# Set interface to promiscuous mode
ip link set eth0 promisc on
# Run container on macvlan network
docker run -it --network macvlan_1 --ip=10.1.0.222 busybox /bin/sh14 Harbor – Enterprise Docker Registry
Start/stop Harbor with Docker‑Compose:
# cd /opt/harbor
# ./install.shConfigure hostname and admin password in harbor.cfg:
hostname = 10.0.0.100
harbor_admin_password = Harbor12345Push an image to Harbor:
# docker tag centos:6.8 10.0.0.100/clsn/centos6.8:1.0
# docker login 10.0.0.100
Username: admin
Password: ******
# docker push 10.0.0.100/clsn/centos6.814.1 Best Practices for Using Containers
Do not split application releases across multiple containers.
Avoid creating large images.
Run only one process per container.
Never store credentials inside images; avoid IP‑based dependencies.
Run processes as non‑root users.
Avoid using the latest tag.
Do not commit running containers to create images.
Avoid single‑layer images.
Never store persistent data inside containers.
14.2 Monitoring Docker Containers
Key metrics include container count, IDs, names, images, commands, ports, CPU usage, memory consumption, block I/O, and network traffic.
References
[1] https://www.redhat.com/zh/topics/containers/whats-a-linux-container [2] https://www.redhat.com/zh/topics/containers/what-is-docker [3] http://blog.51cto.com/dihaifeng/1713512 [4] https://www.cnblogs.com/Bourbon-tian/p/6867796.html [5] https://www.cnblogs.com/CloudMan6/p/6806193.html
Author: 悲绿少年 Source: https://www.cnblogs.com/clsn/p/8410309.html
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architects' Tech Alliance
Sharing project experiences, insights into cutting-edge architectures, focusing on cloud computing, microservices, big data, hyper-convergence, storage, data protection, artificial intelligence, industry practices and solutions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
