引言
在现代软件开发与部署领域,Docker 凭借其轻量、高效和跨平台的特性,已成为容器化技术的行业标准。Docker 的出现极大地简化了应用程序的开发、测试和部署流程,使得开发者能够在不同环境中确保一致的运行表现。本文将从 Docker 的基本概念入手,逐步深入到安装配置、核心命令、镜像管理、容器操作、网络配置以及容器编排等内容,涵盖 Docker 的方方面面。教程内容将以 Linux 系统为主,同时兼顾 Windows 和 macOS 平台的安装与使用场景,确保读者能够在不同环境中轻松上手。
第一章:Docker 核心概念
1.1 什么是 Docker?
Docker 是一个开源的容器化平台,用于将应用程序及其所有依赖(包括代码、运行时、库和配置文件)封装到一个独立的运行环境——容器中。容器是一个轻量级的虚拟化单元,运行在宿主机(运行 Docker 的计算机)上,与宿主机的操作系统内核共享资源。相比传统的虚拟机(VM),Docker 容器具有以下优势:
- 轻量级:容器不包含完整的操作系统,仅封装应用程序及其依赖,占用资源极少,通常只有几十 MB。
- 快速启动:容器启动时间通常在秒级,而虚拟机可能需要数分钟。
- 一致性:容器确保应用程序在开发、测试和生产环境中的运行一致性,避免了“在我机器上能跑”的问题。
- 可移植性:Docker 容器可以在任何支持 Docker 的环境中运行,极大简化了跨平台部署。
与虚拟机的最大区别在于,Docker 容器共享宿主机的内核,而虚拟机需要为每个实例加载完整的操作系统内核。这使得 Docker 容器在资源利用率和启动速度上远超虚拟机。
1.2 镜像与容器的关系
Docker 的两个核心概念是 镜像(Image) 和 容器(Container):
- 镜像:镜像是容器的模板,类似于软件的安装包。它是一个只读的文件,包含了应用程序、依赖库、配置文件以及运行所需的元数据。
- 容器:容器是基于镜像创建的可运行实例,类似于安装后的软件。每个容器是独立的运行环境,可以启动、停止或删除。
为了直观理解镜像与容器的关系,我们可以用一个现实世界的比喻:
- 镜像类似于制作糕点的模具,定义了糕点的形状和结构。
- 容器则是使用模具制作出的具体糕点。同一模具可以制作多个糕点,同一镜像也可以创建多个容器。
镜像可以通过 Dockerfile 构建,也可以通过 Docker Hub 等仓库获取。容器则是镜像的实例化,运行时可以动态修改内容(如写入文件),但这些修改不会影响原始镜像。
1.3 Docker 仓库与 Docker Hub
Docker 仓库是存储和分享镜像的平台,类似于 GitHub 之于代码。Docker Hub 是 Docker 官方提供的公共仓库,托管了数十万计的镜像,供用户免费下载和使用。用户也可以将自制的镜像上传到 Docker Hub,与全球开发者共享。
Docker Hub 上的镜像名称通常由以下部分组成:
- Registry(仓库地址):默认是
docker.io
,表示 Docker Hub 官方仓库,通常可省略。 - Namespace(命名空间):用于区分镜像的作者或组织。例如,
library
是 Docker 官方维护的命名空间,官方镜像可省略此部分。 - 镜像名:镜像的具体名称,如
nginx
或mongo
。 - 标签(Tag):表示镜像的版本号,如
latest
(最新版本)或特定版本号(如1.28.0
)。
例如,docker.io/library/nginx:latest
表示从 Docker Hub 的官方命名空间下载最新版本的 Nginx 镜像,简写为 nginx:latest
。非官方镜像需要指定命名空间,如 n8n/n8n:latest
。
1.4 Docker 的核心优势
Docker 的核心优势在于其标准化、可重复性和模块化设计:
- 标准化:Docker 镜像提供了一种标准化的打包格式,确保应用程序及其依赖在任何环境中一致运行。
- 可重复性:通过 Dockerfile 和 Docker Compose,开发者可以重复构建和部署相同的环境。
- 模块化:Docker 支持将复杂应用拆分为多个独立容器,方便扩展和维护。
第二章:Docker 安装与配置
Docker 基于 Linux 容器化技术(LXC),因此在 Linux 系统上运行最为高效。在 Windows 和 macOS 上,Docker 通过虚拟化技术(如 WSL 或 Hypervisor)模拟 Linux 环境。本章将详细介绍在不同操作系统上安装 Docker 的步骤,并提供网络优化的配置方法。
2.1 在 Linux 上安装 Docker
Linux 是 Docker 的原生运行环境,安装过程简单高效。以 Ubuntu 系统为例,安装步骤如下:
-
获取官方安装脚本:
访问 get.docker.com,获取最新安装命令。通常执行以下命令:curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh
-
验证安装:
安装完成后,运行以下命令检查 Docker 版本:docker --version
如果返回类似
Docker version 20.10.17, build 100c701
的信息,说明安装成功。 -
为非 root 用户配置权限:
默认情况下,Docker 命令需要 root 权限。如果以非 root 用户运行,需要在命令前加sudo
或将用户加入 Docker 用户组:sudo usermod -aG docker $USER
注销并重新登录后,普通用户即可直接运行 Docker 命令。
-
配置镜像加速(中国用户):
由于网络限制,Docker Hub 的下载速度可能较慢。可以通过配置镜像站加速:sudo mkdir -p /etc/docker sudo nano /etc/docker/daemon.json
添加以下内容:
{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev" ] }
保存后重启 Docker 服务:
sudo systemctl restart docker
2.2 在 Windows 上安装 Docker
Windows 系统需要启用 WSL(Windows Subsystem for Linux)来运行 Docker Desktop。以下是详细步骤:
-
启用虚拟化支持:
- 在任务栏搜索“启用或关闭 Windows 功能”。
- 勾选“虚拟机平台”和“适用于 Linux 的 Windows 子系统(WSL)”。
- 点击“确定”并重启电脑。
-
安装 WSL:
打开命令提示符(以管理员身份运行),执行:wsl --set-default-version 2 wsl --update
如果在中国网络环境中,建议添加
--web-download
参数:wsl --update --web-download
-
安装 Docker Desktop:
- 访问 Docker Desktop 下载页面,根据 CPU 架构(如 AMD64)下载安装包。
- 运行安装程序,按照提示完成安装。如果需要自定义安装目录,可通过命令行指定:
DockerDesktopInstaller.exe install --install-dir=C:\CustomPath
-
配置镜像加速:
打开 Docker Desktop,进入“Settings” > “Docker Engine”,添加以下配置:{ "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev" ] }
点击“Apply & Restart”。
-
验证安装:
启动 Docker Desktop,打开 PowerShell 或命令提示符,运行:docker --version
返回版本号即表示安装成功。
2.3 在 macOS 上安装 Docker
macOS 安装 Docker Desktop 非常简单:
-
下载安装包:
访问 Docker Desktop 下载页面,根据芯片类型(Intel 或 Apple Silicon)下载.dmg
文件。 -
安装:
双击.dmg
文件,按照提示拖动 Docker 图标到 Applications 文件夹。 -
配置镜像加速:
打开 Docker Desktop,进入“Preferences” > “Docker Engine”,添加镜像站配置(如上),然后点击“Apply & Restart”。 -
验证安装:
打开终端,运行:docker --version
返回版本号即表示安装成功。
第三章:Docker 核心命令详解
Docker 的核心功能通过命令行实现,命令行操作具有跨平台一致性,适合所有操作系统。本章将详细介绍 Docker 的常用命令及其实际应用场景。
3.1 镜像管理命令
docker pull
从 Docker 仓库下载镜像。例如:
docker pull nginx:latest
- 如果省略
latest
,Docker 默认下载最新版本。 - 非官方镜像需指定命名空间,例如:
docker pull n8n/n8n:latest
docker images
列出本地所有已下载的镜像:
docker images
输出包括镜像名称、标签、ID、大小和创建时间。
docker rmi
删除本地镜像:
docker rmi nginx:latest
或使用镜像 ID 删除:
docker rmi <image_id>
-f
参数可强制删除被容器引用的镜像。
docker tag
为镜像创建新标签,方便重命名或推送:
docker tag my-image:latest myusername/my-image:v1.0
3.2 容器操作命令
docker run
基于镜像创建并运行容器,是 Docker 的核心命令。例如:
docker run -d -p 80:80 nginx
常用参数:
-d
:以分离模式(后台)运行容器。-p <host_port>:<container_port>
:端口映射,将宿主机的端口映射到容器端口。-v <host_path>:<container_path>
:挂载卷,将宿主机目录映射到容器目录。-e <key>=<value>
:设置环境变量,如-e MONGO_INITDB_ROOT_USERNAME=admin
。--name <name>
:为容器指定自定义名称。--restart <policy>
:设置重启策略,如always
或unless-stopped
。
docker ps
查看运行中的容器:
docker ps
-a
:查看所有容器(包括已停止的):docker ps -a
docker stop
和 docker start
- 停止容器:
docker stop <container_id_or_name>
- 启动已停止的容器:
docker start <container_id_or_name>
docker rm
删除容器:
docker rm -f <container_id_or_name>
-f
:强制删除运行中的容器。
docker exec
在运行中的容器内执行命令。例如,进入容器获取交互式终端:
docker exec -it <container_id_or_name> bash
或执行特定命令:
docker exec <container_id_or_name> ps -ef
docker logs
查看容器日志:
docker logs <container_id_or_name>
-f
:实时滚动查看日志。
3.3 挂载卷与数据持久化
Docker 容器是临时的,删除后内部数据会丢失。挂载卷可以将容器内目录与宿主机目录绑定,实现数据持久化。挂载卷有两种方式:
-
绑定挂载:
docker run -d -p 80:80 -v /host/path:/usr/share/nginx/html nginx
宿主机目录
/host/path
会覆盖容器内目录/usr/share/nginx/html
。修改任一方目录的内容会同步到另一方。 -
命名卷挂载:
创建命名卷:docker volume create nginx-html
使用命名卷:
docker run -d -p 80:80 -v nginx-html:/usr/share/nginx/html nginx
命名卷会在首次使用时初始化容器内目录的内容到宿主机,并持久化保存数据。
管理卷的命令:
- 列出所有卷:
docker volume ls
- 查看卷详情:
docker volume inspect <volume_name>
- 删除卷:
docker volume rm <volume_name>
- 清理未使用的卷:
docker volume prune -a
3.4 环境变量与自定义配置
通过 -e
参数向容器传递环境变量。例如,启动 MongoDB 容器并设置用户名和密码:
docker run -d -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=password mongo
可在 Docker Hub 的镜像文档中查找支持的环境变量。
3.5 重启策略
通过 --restart
参数配置容器的重启策略:
--restart=always
:容器因任何原因停止(包括崩溃或宿主机断电)都会自动重启。--restart=unless-stopped
:仅在非手动停止的情况下重启,适合生产环境。--restart=on-failure:5
:当容器因错误退出时重试最多 5 次。
第四章:Docker 网络配置
Docker 提供了多种内置网络模式,包括桥接模式(Bridge)、主机模式(Host)、无网络模式(None)等以满足不同场景的需求。本章详细介绍常用网络模式及其配置方法。
4.1 Bridge 模式(默认)
桥接模式是 Docker 的默认网络模式,所有容器分配在 172.17.0.0/16
子网内,容器之间可通过内部 IP 访问,但与宿主机网络隔离。可以通过创建自定义子网增强管理:
docker network create my-network
docker run -d --network my-network --name mongodb mongo
docker run -d --network my-network -p 8081:8081 --name mongo-express mongo-express
在同一子网内,容器可通过容器名称(如 mongodb
)相互访问,利用 Docker 内置的 DNS 机制解析名称到 IP。
Bridge 模式原理
- 网络隔离:每个容器拥有独立的网络栈,包含自己的 IP 地址、端口和路由表。
- Docker 桥接网桥:Docker 在宿主机上创建一个虚拟网桥(通常命名为
docker0
),所有容器通过该网桥与宿主机和其他容器通信。 - DNS 解析:Docker 内置 DNS 服务器,允许同一网络中的容器通过容器名称相互访问,无需硬编码 IP 地址。
4.2 Host 模式
容器直接使用宿主机的网络栈,无需端口映射。例如:
docker run -d --network host nginx
访问宿主机的 IP 和端口即可访问容器内的服务。Host 模式适合需要高性能网络或解决复杂网络问题的场景。
Host 模式原理
- 无网络隔离:容器直接使用宿主机的网络命名空间,相当于运行在宿主机上的普通进程。
- 高性能:避免了网络地址转换(NAT)的开销,适合高性能需求的场景。
- 端口冲突风险:由于容器直接使用宿主机端口,需确保端口不冲突。
4.3 None 模式
无网络模式(None)将容器置于完全隔离的网络环境中,不分配任何网络接口,容器无法访问外部网络或被外部访问。
docker run -d --network none my-image
4.4 网络管理命令
- 列出网络:
docker network ls
- 查看网络详情:
docker network inspect <network_name>
- 删除自定义网络:
docker network rm <network_name>
第五章:Dockerfile 与镜像构建
Dockerfile 是一个文本文件(无后缀名),用于定义镜像的构建过程,相当于制作模具的图纸。通过 Dockerfile,开发者可以精确控制镜像的内容、依赖和运行行为。
5.1 Dockerfile 指令详解
以下是 Dockerfile 的常用指令及其作用:
- FROM:指定基础镜像,作为构建的起点。通常建议使用轻量级基础镜像如
python:3.13-slim
或alpine
以减少镜像大小。 - WORKDIR:设置容器内的工作目录,后续指令(如
COPY
、RUN
)在此目录执行。 - COPY:将本地文件或目录复制到镜像中,格式为
COPY <src> <dest>
。 - ADD:类似
COPY
,但支持解压 tar 文件或从 URL 下载文件。 - RUN:在构建过程中执行命令,生成新的镜像层。例如,
RUN pip install -r requirements.txt
。 - EXPOSE:声明镜像提供的服务端口,仅为文档提示,实际端口映射依赖
docker run -p
。 - CMD:指定容器启动时的默认命令,推荐使用数组格式(如
["python", "main.py"]
),以便正确处理信号。 - ENTRYPOINT:类似
CMD
,但优先级更高,不易被覆盖,适合定义容器主进程。 - ENV:设置环境变量,如
ENV PATH=/app:$PATH
。 - VOLUME:定义挂载点,用于数据持久化。
- USER:指定运行容器的用户,避免以 root 权限运行。
以下是一个 Python FastAPI 应用的 Dockerfile 示例:
FROM python:3.13-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "main.py"]
5.2 构建镜像
docker build -t myusername/docker-test:latest .
docker build -t docker-test .
-t
:指定镜像名称和标签。.
:表示在当前目录构建。
5.3 推送镜像到 Docker Hub
- 登录 Docker Hub:
输入用户名和密码,必要时完成验证码验证。docker login
- 推送镜像:
docker push myusername/fastapi-app:latest
第六章:Docker Compose 容器编排
Docker Compose 是一个轻量级的容器编排工具,通过 YAML 文件定义和管理多容器应用的配置,简化了复杂应用的部署和管理。Compose 特别适合开发、测试和单机生产环境,能够将多个 docker run
命令整合为一个配置文件,自动处理容器间的网络和依赖关系。
6.1 Docker Compose YAML 文件结构
Docker Compose 使用 YAML 文件(通常命名为 docker-compose.yml
)定义服务、网络和卷。一个典型的 Compose 文件包含以下顶级元素:
- version:指定 Compose 文件格式版本,如
3.8
。 - services:定义容器服务,每个服务对应一个容器。
- networks:定义自定义网络(可选,Compose 默认创建桥接网络)。
- volumes:定义持久化卷(可选)。
以下是一个 MongoDB 和 Mongo Express 的 Docker Compose 示例:
version: '3.8'
services:
mongodb:
image: mongo:latest
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express:latest
ports:
- "8081:8081"
environment:
- ME_CONFIG_MONGODB_SERVER=mongodb
- ME_CONFIG_MONGODB_ADMINUSERNAME=admin
- ME_CONFIG_MONGODB_ADMINPASSWORD=password
depends_on:
- mongodb
restart: unless-stopped
volumes:
mongo-data:
networks:
default:
name: app-network
在 AI 时代,撰写 Docker Compose 文件已不再是必须的。我们只需将所需的 Docker 命令告诉AI,然后让它生成一个等价的 Docker Compose 文件,轻松实现容器编排与管理,高效又便捷。
6.2 常用命令
- 启动所有容器:
docker compose up -d
-d
表示后台运行。 - 停止并删除容器:
停止并移除所有容器、网络和默认卷。docker compose down
- 仅停止容器:
docker compose stop
- 重新启动容器:
docker compose start
- 指定非标准文件名:
docker compose -f custom-compose.yml up
- 查看日志:
docker compose logs -f
- 检查运行状态:
docker compose ps
6.3 Docker Compose 的优势
- 简化配置:将复杂的
docker run
命令整合为单一 YAML 文件,降低手动配置的错误率。 - 依赖管理:通过
depends_on
指定容器启动顺序,确保依赖服务(如数据库)先启动。 - 自动网络:Compose 为每个项目创建一个默认桥接网络,容器通过服务名称通信。
- 可扩展性:支持环境变量、卷、网络和重启策略,适合复杂应用。
- 跨平台一致性:YAML 文件可在不同环境中复用,确保开发和生产环境一致。
第七章:Docker 技术原理
Docker 容器本质上是运行在宿主机上的特殊进程,但通过 Linux 内核的特性实现了资源隔离、限制和高效存储。与传统的虚拟机相比,Docker 不需要为每个容器加载完整的操作系统,而是共享宿主机的内核,从而显著降低了资源开销。以下是 Docker 依赖的三大核心技术:
-
Cgroups(Control Groups):
- 限制和隔离容器的资源使用(如 CPU、内存、带宽)。
- 确保一个容器的资源消耗不会影响宿主机或其他容器。
-
Namespaces:
- 隔离容器的资源视图,包括进程、用户、网络和文件系统。
- 使容器表现为独立的操作系统,看不到宿主机的资源。
-
UnionFS:
- 实现镜像的分层存储,优化存储空间和构建效率。
这些技术共同使 Docker 容器轻量、高效且隔离性强。
容器与虚拟机的对比
特性 | Docker 容器 | 虚拟机 |
---|---|---|
内核 | 共享宿主机内核 | 每个虚拟机包含完整内核 |
启动时间 | 秒级 | 分钟级 |
资源占用 | 轻量(MB 级) | 较重(GB 级) |
隔离性 | 进程级隔离(Namespaces) | 硬件级隔离(Hypervisor) |
性能 | 接近原生性能 | 存在虚拟化开销 |
适用场景 | 微服务、快速部署 | 运行不同操作系统 |
第八章:高级功能与优化
8.1 优化镜像大小
- 使用轻量级基础镜像(如
alpine
或slim
)。 - 合并 RUN 命令,减少镜像层数:
RUN apt-get update && apt-get install -y package && rm -rf /var/lib/apt/lists/*
- 使用多阶段构建:
FROM python:3.13-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt FROM python:3.13-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . CMD ["python", "main.py"]
8.2 安全最佳实践
- 避免以 root 用户运行容器:
docker run --user 1000:1000 ...
- 定期更新镜像,修复安全漏洞。
- 使用
.dockerignore
文件排除不必要的文件。
8.3 性能优化
- 限制容器资源:
docker run --memory="512m" --cpus="0.5" ...
- 使用合适的网络模式(如 Host 模式)减少网络开销。
- 定期清理无用容器和镜像:
docker system prune -a
第九章:实战案例
案例 1:部署 Nginx 静态网站
- 创建 HTML 文件:
mkdir nginx-html echo "<h1>Welcome to Docker</h1>" > nginx-html/index.html
- 运行容器:
docker run -d -p 80:80 -v $(pwd)/nginx-html:/usr/share/nginx/html nginx
- 访问
http://localhost:80
,查看网页。
案例 2:MongoDB 与 Mongo Express
使用上述 Docker Compose 文件启动 MongoDB 和 Mongo Express,访问 http://<server-ip>:8081
进行数据库管理。
案例 3:部署 Python FastAPI 应用
- 创建 FastAPI 应用:
# main.py from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"}
- 创建
requirements.txt
:fastapi==0.68.0 uvicorn==0.15.0
- 使用上述 Dockerfile 构建镜像并运行:
docker build -t my-fastapi-app . docker run -d -p 8000:8000 my-fastapi-app
- 访问
http://localhost:8000
,查看输出。
第十章:常见问题与故障排查
-
Permission Denied 错误:
- 确保用户有 Docker 权限:
sudo usermod -aG docker $USER
。 - 检查文件系统权限,必要时使用
chmod
或chown
。
- 确保用户有 Docker 权限:
-
网络连接问题:
- 检查镜像站配置是否正确。
- 确保防火墙允许相关端口:
sudo ufw allow 80
。
-
容器无法启动:
- 查看日志:
docker logs <container_id>
。 - 检查资源限制:
docker inspect <container_id>
。
- 查看日志:
-
镜像拉取失败:
- 尝试切换镜像站或使用 VPN。
- 确保网络连接稳定。
结语
通过本教程,您已经全面掌握了 Docker 的核心概念、安装方法、常用命令以及高级功能。Docker 的轻量、高效和可移植性使其成为现代开发和部署的首选技术。从简单的静态网站到复杂的多容器应用,Docker 提供了灵活的解决方案,满足各种场景的需求。希望您通过本教程的实战案例,能够在实际项目中熟练应用 Docker,构建高效、可靠的应用程序部署方案。