What is a Docker?
Docker
is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications.
What is a Containers?
Containers
are executable units of software in which application code is packaged, along with its libraries and dependencies, in common ways so that it can be run anywhere, whether it be on desktop, traditional IT, or the cloud. Actually, Container is not modern technology, containers first appeared decades ago with versions like FreeBSD Jails and AIX Workload Partitions. Docker enhanced the native Linux containerization capabilities with technologies, so that most modern developers remember 2013 as the start of modern container era with the introduction of Docker.
Viturlarization vs Container
One way to better understand a container is to understand how it differs from a traditional virtual machine. In traditional virtualization
, a hypervisor is leveraged to virtualize physical hardware, each VM then contains a guest OS, a virtual copy of the hardware that the OS requires to run, along with an application and its associated libraries and dependencies. Instead of virtualizing the underlying hardware, containers
virtualize the operating system (typically Linux) so each individual container contains only the application and its libraries and dependencies. The absence of the guest OS is why containers are so lightweight and, thus, fast and portable.
Benified of Containers
Lightweight
: Containers share the machine OS kernel, eliminating the need for a full OS instance per application and making container files small and easy on resources. Their smaller size, especially compared to virtual machines, means they can spin up quickly and better support cloud-native applications that scale horizontally.Portable and platform independent
: Containers carry all their dependencies with them, meaning that software can be written once and then run without needing to be re-configured across laptops, cloud, and on-premises computing environments.Supports modern development and architecture
: Due to a combination of their deployment portability/consistency across platforms and their small size, containers are an ideal fit for modern development and application patterns, such as DevOps, serverless, and microservice -- that are built are regular code deployments in small increments.Improves utilization
: Like VMs before them, containers ebable developers and operators to improve CPU and memory utilization of physical machines. Where containers go even further is that because they also enable microservice architectures, application components can be deployed and scaled more granularly, an attractive alternative to having to scale up an entire monolithic application because a single component is struggling with load.Docker uses a client-server architecture. The Docker client
talks to the Docker daemon
, which does the heavy lifting of building, running, and distributing your Docker containers. The picture show the architecture of Docker below.
The Docker daemon(dockerd) is a long-runnning daemon process on a server, which listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes.
The Docker client(docker) is the primary way that many Docker users interact with Docker. Docker client can communicate with Docker daemon uses Docker API. For example, when you use commands such as docker run
, the client sends these commands to dockerd using API request, and get the response from dockerd.
Docker Desktop is an easy-to-install application for MacOS or Windows environment, includes Docker Engine, Docker client, Docker Compose, Docker Content Trust, Kubernetes, and Credential Helper.
A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. When you use the docker pull
or docker run
commands, the required images are pulled from your configured registry. When you use the docker push
command, your image is pushed to your configured registry.
When you use Docker, you are creating and using images, containers, networks, volumes, plugins, and other objects.
images
: An image is a read-only template with instructions for creating a Docker container. An image is based on another image, with some additional customization. You might create your own images or you might only use those created by others and published.
Containers
: A container is a runnable instance of an image. You can create, start, stop, move or delete a container using Docker API or CLI. By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container's network, storage, or other underlying subsystems are from other containers or from the host machine.
The fully guidance can check here
# Update the `apt` package index and install packages to allow `apt` to use a repository over HTTPS
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
# Add Docker's offical GPG key
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker's repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# To install a specific version of Docker Engine
sudo apt-cache madison docker-ce
sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
sudo docker run hello-world
sudo systemctl start docker.service
sudo systemctl stop docker.service
sudo systemctl restart docker.service
# Update the `apt` package index and install packages to allow `apt` to use a repository over HTTPS
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
# Add Docker's offical GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker's repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# To install a specific version of Docker Engine
sudo apt-cache madison docker-ce
sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
sudo docker run hello-world
sudo systemctl start docker.service
sudo systemctl stop docker.service
sudo systemctl restart docker.service
# Install the yum-utils package
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum clean all && yum makecache
sudo yum install docker-ce docker-ce-cli containerd.io
# To install a specific version of Docker Engine
sudo yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
sudo systemctl start docker
sudo docker run hello-world
sudo systemctl start docker.service
sudo systemctl stop docker.service
sudo systemctl restart docker.service
# Install the yum-utils package
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo yum clean all && yum makecache
sudo yum install docker-ce docker-ce-cli containerd.io
# To install a specific version of Docker Engine
sudo yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
sudo systemctl start docker
sudo docker run hello-world
sudo systemctl start docker.service
sudo systemctl stop docker.service
sudo systemctl restart docker.service
The default location of the configuration file on Linux is /etc/docker/daemon.json
. The --config-file
flag can be used to specify a non-default location.
"Main key in daemon.json
on Linux"
{
"bip": "Specify network bridge IP",
"bridge": "Attach containers to a network bridge",
"containerd": "/run/containerd/containerd.sock",
"data-root": "Root directory of persistent Docker state (default "/var/lib/docker")",
"debug": "true or false, Enable debug mode"
"default-address-pools": [
{
"base": "172.30.0.0/16",
"size": 24
},
{
"base": "172.31.0.0/16",
"size": 24
}
],
"default-cgroupns-mode": "Default mode for containers cgroup namespace ("host" | "private") (default "host")",
"default-gateway": "Container default gateway IPv4 address, an IPv4 address",
"default-gateway-v6": "Container default gateway IPv6 address, an IPv6 address",
"default-runtime": "runc",
"default-shm-size": "64M",
"default-ulimits": {
"nofile": {
"Hard": 64000,
"Name": "nofile",
"Soft": 64000
}
},
"dns": [DNS server to use, "172.30.0.1", "172.30.0.2"],
"dns-opts": [DNS options to use],
"dns-search": [DNS search domains to use],
"group": "Group for the unix socket (default "docker")",
"hosts": [Daemon socket(s) to connect to, "1.1.1.1", "2.2.2.2"],
"icc": "Enable inter-container communication (default true)"
"init": "Run an init in the container to forward signals and reap processes",
"init-path": "/usr/libexec/docker-init",
"insecure-registries": [Enable insecure registry communication, "", ""],
"ip": "Default IP when binding container ports (default 0.0.0.0)",
"ip-forward": "Enable net.ipv4.ip_forward (default true)",
"iptables": "Enable addition of iptables rules (default true)",
"ip6tables": "Enable addition of ip6tables rules (default false)",
"ipv6": "Enable IPv6 networking",
"labels": [Set key=value labels to the daemon],
"log-driver": "json-file",
"log-level": "Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")",
"log-opts": {
"cache-disabled": "false",
"cache-max-file": "5",
"cache-max-size": "20m",
"cache-compress": "true",
"env": "os,customer",
"labels": "somelabel",
"max-file": "5",
"max-size": "10m"
},
"max-concurrent-downloads": "Set the max concurrent downloads for each pull (default 3)",
"max-concurrent-uploads": "Set the max concurrent uploads for each push (default 5)",
"max-download-attempts": "Set the max download attempts for each pull (default 5)",
"mtu": "Set the containers network MTU",
"oom-score-adjust": "Set the oom_score_adj for the daemon (default -500)",
"pidfile": "Path to use for daemon PID file (default "/var/run/docker.pid")",
"registry-mirrors": [Preferred Docker registry mirror, "https://xxxxxxxx.mirror.aliyuncs.com", "https://xxxxxxx.dkr.ecr.us-east-1.amazonaws.com"],
"seccomp-profile": "",
"selinux-enabled": false,
"shutdown-timeout": 15,
"storage-driver": "Storage driver to use, support: aufs, devicemapper, btrfs, zfs, overlay, overlay2, and fuse-overlayfs",
"storage-opts": ["Storage driver options"],
"tls": true
}
The default location of the configuration file on Windows is %programdata%\docker\config\daemon.json
. The --config-file
flag can be used to specify a non-default location.
"Main key in daemon.json
on Windows"
{
"allow-nondistributable-artifacts": [],
"authorization-plugins": [],
"bridge": "Attach containers to a network bridge",
"containerd": "\\\\.\\pipe\\containerd-containerd",
"data-root": "Root directory of persistent Docker state (default "/var/lib/docker")",
"debug": "true or false, Enable debug mode",
"dns": [DNS server to use, "172.30.0.1", "172.30.0.2"],
"dns-opts": [DNS options to use],
"dns-search": [DNS search domains to use],
"group": "Group for the unix socket (default "docker")",
"hosts": [Daemon socket(s) to connect to, "1.1.1.1", "2.2.2.2"],
"insecure-registries": [Enable insecure registry communication, "", ""],
"labels": [Set key=value labels to the daemon],
"log-driver": "",
"log-level": "Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")",
"max-concurrent-downloads": "Set the max concurrent downloads for each pull (default 3)",
"max-concurrent-uploads": "Set the max concurrent uploads for each push (default 5)",
"max-download-attempts": "Set the max download attempts for each pull (default 5)",
"mtu": "Set the containers network MTU",
"pidfile": "Path to use for daemon PID file (default "/var/run/docker.pid")",
"registry-mirrors": [Preferred Docker registry mirror, "https://xxxxxxxx.mirror.aliyuncs.com", "https://xxxxxxx.dkr.ecr.us-east-1.amazonaws.com"],
"shutdown-timeout": 15,
"storage-driver": "Storage driver to use, support: aufs, devicemapper, btrfs, zfs, overlay, overlay2, and fuse-overlayfs",
"storage-opts": ["Storage driver options"]
}
There are two real-word project as the practice in Docker.
This example demonstrates how to build your own blog web site with wordpress
in Docker.
docker network ls
docker network create --subnet 172.21.0.0/16 --ip-range 172.21.240.0/20 personal-blog
docker network ls
docker run --name wordpress-mysql -t \
-e DB_SERVER_HOST="wd-mysql-server" \
-e MYSQL_DATABASE="wordpress" \
-e MYSQL_USER="wordpress" \
-e MYSQL_PASSWORD="wordpress_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--network=personal-blog \
--restart unless-stopped \
-d mysql:8.0 \
--character-set-server=utf8 \
--collation-server=utf8_bin \
--default-authentication-plugin=mysql_native_password
docker run --name "cerek-wordpress" -t \
-e WORDPRESS_DB_HOST="wordpress-mysql" \
-e WORDPRESS_DB_USER='wordpress' \
-e WORDPRESS_DB_PASSWORD='wordpress_pwd' \
-e WORDPRESS_DB_NAME='wordpress' \
--network personal-blog \
-p 80:80 \
-d wordpress
This example demonstrates how to run Zabbix server
with MySQL database support, Zabbix web interface based on the Nginx web server and Zabbix Java gateway.
docker network ls
docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 zabbix-net
docker network ls
docker run --name mysql-server -t \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
--network=zabbix-net \
--restart unless-stopped \
-d mysql:8.0 \
--character-set-server=utf8 --collation-server=utf8_bin \
--default-authentication-plugin=mysql_native_password
docker run --name zabbix-java-gateway -t \
--network=zabbix-net \
--restart unless-stopped \
-d zabbix/zabbix-java-gateway:alpine-5.4-latest
docker run --name zabbix-server-mysql -t \
-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" \
--network=zabbix-net \
-p 10051:10051 \
--restart unless-stopped \
-d zabbix/zabbix-server-mysql:alpine-5.4-latest
docker run --name zabbix-web-nginx-mysql -t \
-e ZBX_SERVER_HOST="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" \
--network=zabbix-net \
-p 80:8080 \
--restart unless-stopped \
-d zabbix/zabbix-web-nginx-mysql:alpine-5.4-latest
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
743b5c7c32ac zabbix/zabbix-web-nginx-mysql:alpine-5.4-latest "docker-entrypoint.sh" 13 minutes ago Up 13 minutes 8443/tcp, 0.0.0.0:80->8080/tcp zabbix-web-nginx-mysql
24fd3751c5fc zabbix/zabbix-server-mysql:alpine-5.4-latest "/sbin/tini -- /usr/…" 13 minutes ago Up 13 minutes 0.0.0.0:10051->10051/tcp zabbix-server-mysql
2173072776d4 zabbix/zabbix-java-gateway:alpine-5.4-latest "docker-entrypoint.s…" 13 minutes ago Up 13 minutes 10052/tcp zabbix-java-gateway
ff968c8c8de7 mysql:8.0 "docker-entrypoint.s…" 18 minutes ago Up 18 minutes 3306/tcp, 33060/tcp mysql-server