Cloud Native 37 min read

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.

ITPUB
ITPUB
ITPUB
Master Docker: From Container Basics to Advanced Image Management, Registry, Compose, and Networking

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-ssh

Private Docker Registry

Start a simple registry:

docker run -d -p 5000:5000 \
  --restart=always --name registry \
  -v /opt/myregistry:/var/lib/registry registry

Configure 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/busybox

Registry 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 \
  registry

Docker‑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: always

Start the stack:

docker-compose up -d

Access 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/sh

HAProxy 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/stats

Ensuring 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 nginx

Data 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-ssh

Pipework – 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.8

Zabbix 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:latest

Obtain 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.php

Additional 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

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DockerLinuxNetworkingDockerfileContainersDocker ComposeRegistry
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.