Docker Data Management, Networking, and Custom Image Creation
Data Persistence and Volume Management
Managing data within Docker containers is primarily achieved through data volumes and data volume containers, ensuring data persistence and sharing across container lifecycles.
Data Volumes
A data volume is a specially designated directory within a container that bypasses the standard filesystem. It facilitates mapping a host machine's directory directly into the container. Modifications made within the volume are instantly reflected and persist independently of the container's lifecycle, similar to mounting a directory in Linux.
docker pull ubuntu:22.04
Mount the host directory /srv/webapp to the container path /app/data. The host path must be absolute; if it does not exist, Docker will automatically generate it.
docker run -v /srv/webapp:/app/data --name web-node -it ubuntu:22.04 /bin/bash
Inside the container, write data to the mounted volume:
echo "persistence test" > /app/data/test.txt
exit
Verify the data on the host machine:
cat /srv/webapp/test.txt
Data Volume Containers
When sharing data among multiple containers, a data volume container serves as a centralized mount point. This type of container exists solely to provide volume references to other containers.
docker run -d --name shared-store -v /volume-a -v /volume-b ubuntu:22.04 sleep infinity
docker run -d --name client-one --volumes-from shared-store ubuntu:22.04 sleep infinity
docker run -d --name client-two --volumes-from shared-store ubuntu:22.04 sleep infinity
Write data from the primary volume container:
docker exec -it shared-store bash
echo 'shared data A' > /volume-a/info.txt
echo 'shared data B' > /volume-b/info.txt
Read the shared data from client containers:
docker exec -it client-one bash
cat /volume-a/info.txt
cat /volume-b/info.txt
Network Configuration
Port Mapping
Services running inside a container are isolated from external networks by default. Port mapping binds a host port to a container port, routing external traffic into the containerized service.
docker run -d --name web-random -P nginx # Randomly assigns a high port (e.g., 32768+)
docker run -d --name web-explicit -p 8080:80 nginx # Binds host 8080 to container 80
docker ps -a
Container Linking
Container IP addresses can change upon recreation. Container linking establishes a secure network tunnel using container names, allowing stable inter-container communication without relying on dynamic IPs.
docker run -d --name primary-db ubuntu:22.04 sleep infinity
docker run -it --name app-server --link primary-db:database ubuntu:22.04 /bin/bash
From the app-server container, the linked container can be reached via the alias:
ping database
Image Construction Methods
Custom Docker images can be generated through three distinct approaches: modifying existing containers, importing filesystem templates, or using automated Dockerfile builds.
Committing Modified Containers
Launch a base container, apply modifications, and commit the changed filesystem layer as a new image.
docker run -d --name base-ubuntu ubuntu:22.04 sleep infinity
docker exec base-ubuntu apt-get update
docker exec base-ubuntu apt-get install -y curl
Commit the changes using the container ID:
docker commit -m "Added curl utility" -a "devops" base-ubuntu ubuntu:curl
docker images
Run the newly created image with a port mapping:
docker run -d --name test-curl -p 8081:80 ubuntu:curl sleep infinity
docker ps -a
Importing Local Templates
OS templates, such as those from the OpenVZ project, can be imported directly to form an image.
wget http://openvz.org/Download/template/precreated/debian-7.0-x86-minimal.tar.gz
docker import debian-7.0-x86-minimal.tar.gz -- debian:7.0
docker run -it debian:7.0 /bin/bash
Dockerfile and Layered Architecture
Union File System (UnionFS)
Docker images rely on UnionFS, a layered, lightweight filesystem that aggregates multiple directories into a single virtual directory. Layers are cached and reused; modifying an instruction invalidates the cache for that layer and all subsequent layers. Layers are immutable—deleting a file in a higher layer merely masks it in the lower layer.
Common Dockerfile Instructions
FROM: Sets the base image (must be the first instruction).LABEL: Adds metadata such as maintainer info.RUN: Executes commands during build. Chain commands using&&to minimize layers.EXPOSE: Documents the network port the container listens on.ENV: Sets environment variables.COPY/ADD: Transfers files from host to image.ADDsupports URL fetching and automatic tar extraction, whereasCOPYis preferred for simple file duplication.VOLUME: Creates a mount point for external storage.USER: Sets the active user for subsequent instructions.WORKDIR: Sets the working directory.CMD/ENTRYPOINT: Defines the default executable upon container startup.ENTRYPOINTtakes precedence; if both are defined,CMDarguments are passed to theENTRYPOINTexecutable.
Command execution priority during container startup:
docker run --entrypoint="exec"ENTRYPOINTdefined in Dockerfile- Command appended to
docker run CMDdefined in Dockerfile
Dockerfile Case 1: Package Manager Installation
Create a working directory and define the build process for installing Apache via apt.
mkdir /opt/apache-docker
cd /opt/apache-docker
vim Dockerfile
Dockerfile content:
FROM ubuntu:22.04
LABEL maintainer="dev team"
RUN apt-get update && apt-get install -y apache2
EXPOSE 80
CMD ["apachectl", "-D", "FOREGROUND"]
Build and run the image:
docker build -t my-apache:latest .
docker run -d -p 9090:80 my-apache:latest
To customize the default web page, mount a local directory containing an index.html file:
mkdir /opt/apache-docker/html
echo 'Custom Apache Content' > /opt/apache-docker/html/index.html
docker run -d -p 9091:80 -v /opt/apache-docker/html/:/var/www/html/ my-apache:latest
Dockerfile Case 2: Source Code Compilation
For granular control, compile Nginx directly from the source tarball.
mkdir /opt/nginx-build
cd /opt/nginx-build
# Place nginx-1.25.0.tar.gz in this directory
vim Dockerfile
Dockerfile content:
FROM ubuntu:22.04
LABEL author="devops" usage="custom nginx"
ADD nginx-1.25.0.tar.gz /usr/local/src/
RUN apt-get update && apt-get install -y build-essential libpcre3-dev zlib1g-dev && \
useradd -M -s /sbin/nologin nginx && \
cd /usr/local/src/nginx-1.25.0 && \
./configure --prefix=/etc/nginx --user=nginx --group=nginx --with-http_stub_status_module && \
make && make install
EXPOSE 80
CMD ["/etc/nginx/sbin/nginx", "-g", "daemon off;"]
Build the image and launch the container with a mounted web root:
docker build -t nginx-src:1.0 .
mkdir /opt/nginx-build/html
echo 'Compiled Nginx Server' > /opt/nginx-build/html/index.html
docker run -d --name compiled-nginx -p 9092:80 -v /opt/nginx-build/html/:/etc/nginx/html/ nginx-src:1.0