Cloud Native 35 min read

Master Docker: Core Concepts, Installation, Image Building, and Multi‑Stage Optimization

This guide walks you through Docker fundamentals, installation on Linux and Windows, basic container commands, image management, custom Dockerfile creation, multi‑stage builds for smaller images, and how to export and import images for production use.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Master Docker: Core Concepts, Installation, Image Building, and Multi‑Stage Optimization

Docker Related Concepts

Understanding Docker starts with the evolution of virtualization: physical machines, virtual machines, and now containerization. Containers are lightweight, process‑level isolated environments that start in seconds and consume far less storage than VMs. Docker is an open‑source container engine that creates containers from images, which are essentially read‑only filesystem snapshots.

Docker works closely with Kubernetes (k8s); both use the containerd runtime, so images built with Docker run seamlessly in k8s clusters.

Docker Installation

Ubuntu

Install Docker with the official one‑line script: curl -sSL https://get.daocloud.io/docker | sh Add your user to the docker group to avoid root‑only usage: sudo gpasswd -a <your_username> docker Restart the Docker service: sudo service docker restart If you encounter conflicts with Podman, remove Podman first:

yum erase podman buildah

Windows 10

Docker Desktop for Windows requires Hyper‑V. Enable Hyper‑V with the following batch script (run as administrator):

pushd "%~dp0"

dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt
for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"

del hyper-v.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V-All /LimitAccess /ALL

Hello World Example

Run a simple command inside an Ubuntu container: docker run ubuntu:20.04 /bin/echo "Hello world" The first run pulls the image from Docker Hub; subsequent runs are instantaneous. Docker also provides an official hello-world image:

docker run hello-world

Using Docker Images

Docker Hub can be slow, so configure a local registry mirror by creating /etc/docker/daemon.json:

{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "https://docker.mirrors.ustc.edu.cn",
    "http://hub-mirror.c.163.com",
    "https://cr.console.aliyun.com/"
  ]
}

Restart Docker to apply the changes: systemctl restart docker List local images:

$ docker images
REPOSITORY   TAG       IMAGE ID   CREATED      SIZE
ubuntu       20.04     f643c72b... 5 weeks ago  72.9MB
hello-world  latest    bf756fb1... 12 months ago 13.3kB

Search for images:

$ docker search python
NAME      DESCRIPTION                     STARS   OFFICIAL
python    Python is an interpreted...     5757    [OK]
...

Pull a specific image version:

$ docker pull python:3.8
3.8: Pulling from library/python
... (download progress) ...
Status: Downloaded newer image for python:3.8

Running Containers

Start an interactive Python container: docker run -it python:3.8 Mount a host directory into a container ( -v host_path:container_path) and run a script:

docker run -v ~/docker_test:/docker_test python:3.8 python /docker_test/hello.py

Expose container ports to the host with -p host_port:container_port. For a server listening on 0.0.0.0:5000 inside the container, map it to host port 5001:

docker run -v ~/docker_test:/docker_test -it -p 5001:5000 python:3.8 python /docker_test/hello.py

List running containers and their details:

$ docker ps
CONTAINER ID   IMAGE          COMMAND               CREATED          STATUS          PORTS                     NAMES
ec4c86b8a163   python:3.8     "python /docker_test…"   5 seconds ago   Up 4 seconds    0.0.0.0:5000->5000/tcp    eager_wilson

Stop a container with docker kill CONTAINER_ID.

Creating Custom Docker Images

Key Dockerfile instructions:

FROM : base image.

WORKDIR : set working directory.

COPY / ADD : copy files from the build context.

RUN : execute shell commands during build (each creates a layer).

CMD and ENTRYPOINT : define the default command; ENTRYPOINT is preferred when you want to allow additional arguments from docker run.

ENV : set environment variables.

Example 1 – Text‑display image

# cat.py
import sys
with open(sys.argv[1], "r") as fp:
    print(fp.read())

Dockerfile:

FROM python:3.8
WORKDIR /files
COPY cat.py /cat.py
ENTRYPOINT ["python", "/cat.py"]

Build and run:

docker build -t cat:1.0 .
docker run -it -v ~/docker_test/cat/files:/files cat:1.0 test.txt

Example 2 – Tornado web server

# ws.py (simplified)
import tornado.ioloop, tornado.web, tornado.options
from tornado.options import define, options
define("port", default=8000, type=int)
class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello world")
if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application([(r"/", IndexHandler)])
    app.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

Dockerfile (using CMD):

FROM python:3.8
WORKDIR /ws
COPY ws.py /ws/ws.py
RUN pip install tornado
CMD python ws.py

Running with docker run -it -p 8000:8000 ws:1.0 starts the server. If you replace CMD with ENTRYPOINT (JSON form), arguments supplied after docker run are passed to the script, allowing you to override the port. Example 3 – APScheduler service

# sch.py
import sys, shutil
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger

def scan_files():
    shutil.copytree(sys[1], sys[2])

scheduler = BlockingScheduler()
scheduler.add_job(scan_files, trigger=CronTrigger(minute="*"), misfire_grace_time=30)

Dockerfile:

FROM python:3.8
WORKDIR /
COPY sch.py /sch.py
RUN pip install apscheduler
ENTRYPOINT ["python", "sch.py"]

Run with two volume mounts for source and destination directories:

docker run -d -v ~/docker_test/sch/src:/src -v ~/docker_test/sch/dest:/dest sch:1.0 /src /dest

Multi‑Stage Builds to Reduce Image Size

Large images (e.g., the official python image ~884 MB) can be trimmed by separating build‑time dependencies from the final runtime image. Stage 1 – Build image with Python, pip, and required packages (e.g., numpy ).

FROM python:3.8-ubuntu-pip
RUN pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy

Stage 2 – Minimal runtime image, copying only the installed packages.

FROM python:3.8-ubuntu
COPY --from=0 /usr/local/lib/python3.8/dist-packages/ /usr/local/lib/python3.8/dist-packages/

Build with docker build -t project:1.0 . . The resulting image is roughly 750 MB smaller than a monolithic build.

Exporting and Importing Images

Save an image to a tar archive:

docker save -o hello.tar hello:1.0

Transfer the .tar file to the target host and load it:

docker load -i hello.tar

The image is now available for deployment on the production machine.

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.

PythonKubernetesContainersImage BuildingMulti‑Stage Build
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

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.