Master Docker: From Container Basics to Advanced Image Management, Registry, Compose, and Networking
This comprehensive guide explains Linux containers, their differences from traditional virtualization, the evolution of Docker, core Docker commands, Dockerfile creation, image layering, private registries, docker‑compose orchestration, network modes, HAProxy load balancing, and best practices for secure and efficient container deployment.
What Is a Linux Container?
Linux containers isolate a set of processes from the host system using kernel features (cgroups, namespaces). All required files are packaged in an image, providing portability from development to production.
Containers vs. Virtual Machines
Traditional VMs run separate operating systems on a hypervisor. Containers share the host kernel and isolate applications at the process level, resulting in lightweight, fast deployment.
Brief History
FreeBSD jail (2000)
VServer (2001) – first Linux isolation project
LXC – foundation for modern containers
Docker – added tooling, image distribution and a rich ecosystem
Docker Basics
Docker implements container technology using kernel features. It provides image‑based deployment, versioned images, and easy distribution.
Key Docker Commands
# View Docker version
docker version
# List images
docker image list
# Pull an image
docker pull centos
# Run a container (detached, port 80 → 80)
docker run -d -p 80:80 nginx
# Inspect a container
docker container inspect container_id
# Stop a container
docker stop container_name
# Remove a container (force)
docker rm -f $(docker ps -a -q)Docker Image Lifecycle
Images are built in read‑only layers. When a container starts, a writable layer is added on top. Layers are shared between containers (copy‑on‑write).
Dockerfile Basics
# Example Dockerfile
FROM centos:6.8
RUN yum install -y openssh-server && yum clean all
RUN echo "root:123456" | chpasswd
RUN /etc/init.d/sshd start
CMD ["/usr/sbin/sshd","-D"]Common instructions: FROM, MAINTAINER, RUN, ADD, COPY, WORKDIR, VOLUME, EXPOSE, CMD, ENTRYPOINT, ENV.
Build and Run a Custom Image
# Build the image and tag it
docker image build -t centos6-ssh .
# Run the image with port mapping
docker run -d -p 2022:22 centos6-sshPrivate Docker Registry
Start a simple registry:
docker run -d -p 5000:5000 \
--restart=always --name registry \
-v /opt/myregistry:/var/lib/registry registryConfigure the daemon to trust the registry (e.g., /etc/docker/daemon.json) and push images:
# Tag the image for the private registry
docker tag busybox:latest 10.0.0.100:5000/clsn/busybox:1.0
# Push the image
docker push 10.0.0.100:5000/clsn/busyboxRegistry with Basic Authentication
# Install httpd-tools for htpasswd
yum install -y httpd-tools
# Create auth file
mkdir -p /opt/registry-var/auth
htpasswd -Bbn clsn 123456 > /opt/registry-var/auth/htpasswd
# Run registry with auth variables
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 \
registryDocker‑Compose Orchestration
Example docker-compose.yml for WordPress + MySQL:
version: '3'
services:
db:
image: mysql:5.7
volumes:
- /data/db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
restart: always
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
- /data/web_data:/var/www/html
restart: alwaysStart the stack:
docker-compose up -dAccess the site at http://host_ip:8000.
Docker Networking
bridge – default isolated network (virtual bridge).
host – container shares the host’s network namespace.
none – no network configuration.
container – shares another container’s network stack.
macvlan – assigns a MAC address from the physical network.
Example: create a macvlan network and run a container on it.
# Create macvlan network
docker network create --driver macvlan \
--subnet 10.1.0.0/24 --gateway 10.1.0.254 \
-o parent=eth0 macvlan_1
# Run a container using the macvlan network
docker run -it --network macvlan_1 --ip 10.1.0.222 busybox /bin/shHAProxy Load Balancing for Docker Containers
Install HAProxy and configure /etc/haproxy/haproxy.cfg to balance two WordPress containers. Use the HAProxy stats socket for runtime control:
# Disable a backend server
echo "disable server backend_www_example_com/web-node2" | socat stdio /var/lib/haproxy/stats
# Enable the server again
echo "enable server backend_www_example_com/web-node2" | socat stdio /var/lib/haproxy/statsEnsuring Containers Restart After Docker Daemon Restarts
Run containers with --restart=always.
Add "live-restore": true to /etc/docker/daemon.json so containers stay alive when the daemon restarts.
Best Practices for Container Images
Run a single process per container.
Keep images small and layered; avoid monolithic images.
Run processes as non‑root users.
Do not embed credentials or sensitive data in images.
Prefer explicit version tags over latest.
Use volumes for persistent data; never store data inside the container layer.
Monitoring Docker Containers
Key metrics: container ID, name, image, CPU usage, memory consumption, block I/O, network traffic. Tools: docker stats, Prometheus + Grafana, or custom exporters.
Docker Volumes
Create and use a named volume:
# Create a volume
docker volume create mydata
# Run a container with the volume mounted
docker run -d -p 80:80 -v mydata:/usr/share/nginx/html nginxData written to /usr/share/nginx/html inside the container persists in /var/lib/docker/volumes/mydata/_data on the host.
Building a Custom SSH Image (CentOS 6.8)
# Dockerfile
FROM centos:6.8
RUN yum install -y openssh-server && yum clean all
RUN echo "root:123456" | chpasswd
RUN /etc/init.d/sshd start
CMD ["/usr/sbin/sshd","-D"]Build and run:
# Build
docker image build -t centos6-ssh .
# Run with SSH port exposed
docker run -d -p 2022:22 centos6-sshPipework – Assigning Custom IPs to Containers
Install Pipework and a bridge on the host, then assign an IP address to a container:
# Install 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
# Create a Linux bridge (br0) and enable promiscuous mode
yum install -y bridge-utils
# (Configure /etc/sysconfig/network-scripts/ifcfg-br0 and ifcfg-eth0 accordingly)
ip link set eth0 promisc on
# Run a container and attach it to br0 with a static IP
pipework br0 $(docker run -d -p 6880:80 --name httpd_pw httpd) 10.0.0.220/[email protected]Test from another host: curl http://10.0.0.220.
Harbor – Enterprise‑Grade Registry
Download and install Harbor (v1.3.0) on /opt/harbor. Edit harbor.cfg to set the hostname and admin password, then run ./install.sh. After installation, access the UI at http://host_ip, create a project, and push images:
# Tag image for Harbor project "clsn"
docker tag centos:6.8 10.0.0.100/clsn/centos6.8:1.0
# Login to Harbor
docker login 10.0.0.100 # user: admin
# Push the image
docker push 10.0.0.100/clsn/centos6.8Zabbix Server Deployment with Docker
Example steps to run a Zabbix monitoring stack:
# MySQL for Zabbix data
docker run -d --name mysql-server \
-e MYSQL_DATABASE="zabbix" \
-e MYSQL_USER="zabbix" \
-e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \
mysql:5.7
# Zabbix Java gateway (optional)
docker run -d --name zabbix-java-gateway zabbix/zabbix-java-gateway:latest
# Zabbix server (MySQL backend)
docker run -d --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 \
zabbix/zabbix-server-mysql:latest
# Zabbix web interface (NGINX)
docker run -d --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 \
zabbix/zabbix-web-nginx-mysql:latestObtain an API token (example):
curl -s -X POST -H 'Content-Type:application/json' -d '{
"jsonrpc": "2.0",
"method": "user.login",
"params": {"user": "Admin", "password": "zabbix"},
"id": 1
}' http://host_ip/api_jsonrpc.phpAdditional Docker Network Types
none – container starts without any network interfaces.
container – shares another container’s network stack (e.g., --network container:mycontainer).
host – container uses the host’s network namespace directly (e.g., --network host).
References
Red Hat – What is a Linux container?
Red Hat – What is Docker?
Docker official documentation
Harbor documentation
Zabbix API guide
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.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
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.
