Docker 全面详解:从入门到实战的完整指南
Docker 全面详解:从入门到实战的完整指南
摘要: Docker 是目前最流行的容器化平台,彻底改变了软件的开发、打包和部署方式。本文将从 Docker 的核心概念讲起,系统介绍镜像、容器、网络、数据卷、Dockerfile、Docker Compose 等关键内容,并提供常用指令的完整参考。无论你是初次接触 Docker,还是希望系统梳理知识体系,本文都能帮到你。
来源: Docker 官方文档
一、Docker 是什么?
Docker 是一个开源的容器化平台,用于开发、打包和运行应用程序。它的核心理念是:将应用及其所有依赖(代码、运行时、系统工具、库、配置)打包到一个标准化的单元 —— 容器(Container) 中。
为什么需要 Docker?
在没有 Docker 之前,开发者经常面临这样的问题:
- "在我的机器上能跑" —— 开发环境、测试环境、生产环境的依赖版本不一致
- 环境配置复杂 —— 安装数据库、消息队列、缓存等中间件耗时耗力
- 虚拟机太重 —— 传统 VM 需要完整的操作系统,资源占用大、启动慢
Docker 通过容器技术解决了这些问题:
- 一致性 —— 同一个容器镜像在任何地方运行结果完全一致
- 轻量 —— 容器共享宿主机的操作系统内核,不需要完整的 OS,启动只需几秒钟
- 隔离 —— 每个容器运行在独立的命名空间中,互不干扰
- 可移植 —— 容器可以运行在笔记本、物理机、虚拟机、云平台上
Docker 与虚拟机的区别
| 特性 | Docker 容器 | 虚拟机(VM) |
|---|---|---|
| 内核 | 共享宿主机内核 | 每个 VM 有独立的完整 OS |
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 极低(MB 级) | 较高(GB 级) |
| 隔离性 | 进程级隔离(较强) | 硬件级隔离(最强) |
| 典型数量 | 单机可运行数十到数百个 | 单机通常运行几个到十几个 |
二、Docker 核心概念
理解 Docker 之前,必须先搞清楚几个核心概念。
2.1 镜像(Image)
镜像是一个只读的模板,包含了创建容器所需的所有内容:文件系统、代码、运行时、库、环境变量、配置文件等。
可以把镜像理解为"类的定义"或"安装光盘"。
2.2 容器(Container)
容器是镜像的运行实例。一个镜像可以创建多个容器,每个容器彼此独立。
类比:镜像是"类",容器是"对象实例"。
2.3 Dockerfile
Dockerfile 是一个文本文件,包含了构建镜像的所有指令。每一行指令都会创建镜像的一层(Layer),Docker 会缓存这些层,只在变化时重新构建。
2.4 仓库(Registry)
仓库是存放和分发镜像的地方。最著名的是 Docker Hub(hub.docker.com),你也可以搭建私有仓库(如 Harbor)。
2.5 Docker 架构
Docker 采用 客户端-服务端(C/S)架构:
- Docker 客户端(docker) —— 用户通过 CLI 输入命令
- Docker 守护进程(dockerd) —— 处理实际工作(构建、运行、分发容器)
- REST API —— 客户端和守护进程之间的通信接口
用户命令 → docker CLI → REST API → dockerd → 执行操作
三、安装 Docker
3.1 Linux(Ubuntu/Debian)
# 一键安装脚本(官方推荐用于开发环境)
curl -fsSL https://get.docker.com | sh
# 安装完成后,将当前用户加入 docker 组(避免每次用 sudo)
sudo usermod -aG docker $USER
# 重新登录或执行
newgrp docker
# 验证安装
docker --version
docker run hello-world
3.2 Windows
安装 Docker Desktop for Windows:
- 需要 WSL 2 后端(见上一篇 WSL 相关文章)
- 下载地址:https://www.docker.com/products/docker-desktop/
- 安装后 Docker 命令行即可使用
3.3 macOS
安装 Docker Desktop for Mac:
- 下载地址同上
- 安装后在终端中直接使用
docker命令
四、Docker 常用指令
这是本文的重点部分。Docker 的指令非常多,下面按功能分类,列出最常用、最实用的命令。
4.1 镜像管理
# 搜索镜像
docker search nginx
# 拉取镜像(从 Docker Hub)
docker pull nginx
docker pull nginx:latest # 指定标签
docker pull ubuntu:22.04 # 指定版本
# 查看本地镜像
docker images
docker images -a # 包含中间层镜像
docker images --format "{{.Repository}}: {{.Tag}}"
# 删除镜像
docker rmi nginx
docker rmi nginx:latest
docker rmi -f <image_id> # 强制删除
# 查看镜像详情
docker inspect nginx
# 查看镜像构建历史(分层信息)
docker history nginx
# 给镜像打标签
docker tag nginx:latest myregistry.com/nginx:v1
# 推送镜像到仓库
docker push myregistry.com/nginx:v1
# 导出镜像为 tar 文件
docker save nginx -o nginx.tar
# 从 tar 文件加载镜像
docker load -i nginx.tar
# 构建镜像(从 Dockerfile)
docker build -t myapp:v1 .
docker build -t myapp:v1 -f Dockerfile.prod .
4.2 容器管理
# 创建并运行容器
docker run nginx # 前台运行
docker run -d nginx # 后台运行(detached)
docker run -d --name myweb nginx # 指定容器名称
docker run -d -p 8080:80 nginx # 端口映射(宿主机8080 → 容器80)
docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx # 挂载数据卷
docker run -it ubuntu /bin/bash # 交互式运行(如进入 shell)
docker run -d -e MYSQL_ROOT_PASSWORD=123 mysql # 设置环境变量
docker run -d --restart always nginx # 自动重启(开机自启)
docker run -d --network mynet nginx # 指定网络
# 查看运行中的容器
docker ps
docker ps -a # 查看所有容器(含已停止的)
docker ps -q # 只显示容器 ID
# 停止容器
docker stop <container_name_or_id>
docker stop $(docker ps -q) # 停止所有运行中的容器
# 启动已停止的容器
docker start <container_name_or_id>
# 重启容器
docker restart <container_name_or_id>
# 删除容器
docker rm <container_name_or_id>
docker rm -f <container_name_or_id> # 强制删除(运行中的)
docker rm $(docker ps -aq) # 删除所有容器
# 查看容器日志
docker logs <container_name_or_id>
docker logs -f <container_name_or_id> # 实时跟踪日志
docker logs --tail 100 <container> # 只看最后 100 行
# 进入运行中的容器
docker exec -it <container_name_or_id> /bin/bash
docker exec -it <container_name_or_id> /bin/sh
docker exec -it <container_name_or_id> python3
# 查看容器资源占用
docker stats
docker stats <container_name_or_id>
# 查看容器详情
docker inspect <container_name_or_id>
# 复制文件
docker cp /host/path <container>:/container/path
docker cp <container>:/container/path /host/path
# 暂停/恢复容器
docker pause <container_name_or_id>
docker unpause <container_name_or_id>
4.3 端口映射详解
-p 参数是 docker run 最常用的参数之一:
# 宿主机端口:容器端口
docker run -d -p 8080:80 nginx
# 指定绑定 IP
docker run -d -p 127.0.0.1:8080:80 nginx
# 映射多个端口
docker run -d -p 8080:80 -p 4443:443 nginx
# 随机分配宿主机端口
docker run -d -P nginx
4.4 数据卷(Volume)
数据卷用于持久化容器数据。容器删除后,数据卷中的数据不会丢失。
# 创建数据卷
docker volume create mydata
# 查看所有数据卷
docker volume ls
# 查看数据卷详情
docker inspect mydata
# 使用数据卷运行容器
docker run -d -v mydata:/var/lib/mysql mysql
# 挂载宿主机目录(bind mount)
docker run -d -v /host/path:/container/path nginx
# 删除数据卷
docker volume rm mydata
# 删除未使用的数据卷
docker volume prune
# 只读挂载
docker run -d -v /host/path:/container/path:ro nginx
4.5 网络管理
Docker 提供了多种网络模式,用于容器之间的通信。
# 查看网络
docker network ls
# 创建自定义网络
docker network create mynet
docker network create --driver bridge mynet
# 在指定网络中运行容器
docker run -d --network mynet --name web nginx
docker run -d --network mynet --name db mysql
# 连接已有容器到网络
docker network connect mynet <container>
# 断开网络连接
docker network disconnect mynet <container>
# 查看网络详情
docker inspect mynet
# 删除网络
docker network rm mynet
docker network prune
# 删除未使用的网络
网络驱动类型:
| 驱动 | 说明 |
|---|---|
| bridge | 默认,容器间通过内部网桥通信 |
| host | 容器直接使用宿主机网络,无隔离 |
| none | 容器无网络 |
| overlay | 跨主机容器通信(Swarm 模式) |
| macvlan | 给容器分配独立 MAC 地址 |
4.6 Dockerfile 编写
Dockerfile 是构建镜像的蓝图。下面是一个典型示例:
# 基础镜像
FROM python:3.12-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8000
# 设置环境变量
ENV PYTHONUNBUFFERED=1
# 启动命令
CMD ["python", "main.py"]
常用 Dockerfile 指令说明:
| 指令 | 说明 |
|---|---|
| FROM | 指定基础镜像 |
| WORKDIR | 设置工作目录 |
| COPY | 从宿主机复制文件到镜像 |
| ADD | 类似 COPY,但支持 URL 和解压 |
| RUN | 在构建时执行命令 |
| CMD | 容器启动时默认执行的命令 |
| ENTRYPOINT | 容器启动时的入口命令(可与 CMD 配合) |
| EXPOSE | 声明容器监听的端口 |
| ENV | 设置环境变量 |
| ARG | 构建时可用的变量 |
| VOLUME | 声明数据卷挂载点 |
| USER | 设置运行用户 |
| HEALTHCHECK | 健康检查命令 |
4.7 Docker Compose
Docker Compose 用于管理多容器应用。通过一个 docker-compose.yml 文件定义所有服务。
安装:
# Docker Desktop 已包含 docker compose
# Linux 单独安装:
sudo apt install docker-compose-plugin
docker-compose.yml 示例:
version: "3.8"
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
depends_on:
- db
volumes:
- .:/app
networks:
- appnet
db:
image: postgres:16
environment:
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=myapp
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- appnet
volumes:
pgdata:
networks:
appnet:
driver: bridge
Compose 常用命令:
# 启动所有服务(后台)
docker compose up -d
# 启动并查看日志
docker compose up
# 停止所有服务
docker compose down
# 停止并删除数据卷
docker compose down -v
# 查看服务状态
docker compose ps
# 查看日志
docker compose logs
docker compose logs -f web
# 进入某个服务容器
docker compose exec web /bin/bash
# 重建并启动
docker compose up -d --build
# 只启动指定服务
docker compose up -d db
# 重启指定服务
docker compose restart web
五、实战示例
5.1 部署 Nginx 静态网站
# 拉取镜像并运行
docker run -d --name mysite -p 80:80 -v /var/www/html:/usr/share/nginx/html nginx
# 在网站目录放一个 index.html
echo "<h1>Hello from Docker Nginx!</h1>" > /var/www/html/index.html
# 浏览器访问 http://localhost 即可看到页面
5.2 部署 MySQL 数据库
# 运行 MySQL 容器
docker run -d --name mydb \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=secret123 \
-e MYSQL_DATABASE=myapp \
-v mysql_data:/var/lib/mysql \
mysql:8.0
# 进入 MySQL 命令行
docker exec -it mydb mysql -u root -p
5.3 构建并运行自己的应用
创建项目目录:
myapp/
├── Dockerfile
├── main.py
└── requirements.txt
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
构建并运行:
# 构建镜像
docker build -t myapp:v1 .
# 运行容器
docker run -d --name myapp -p 8000:8000 myapp:v1
# 访问 http://localhost:8000
5.4 一键部署完整项目(Compose)
# 在项目目录执行
docker compose up -d
# 查看运行状态
docker compose ps
# 停止并清理
docker compose down
六、注意事项与最佳实践
6.1 镜像优化
- 使用更小的基础镜像(如
alpine、slim版本) - 合并 RUN 指令减少层数:
RUN apt update && apt install -y xxx && rm -rf /var/lib/apt/lists/* - 使用
.dockerignore文件排除不必要的文件(如.git、node_modules、__pycache__) - 使用多阶段构建(Multi-stage build)减小最终镜像体积
多阶段构建示例:
# 构建阶段
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o /app/myapp
# 运行阶段(仅包含编译后的二进制文件)
FROM alpine:latest
COPY --from=builder /app/myapp /app/myapp
CMD ["/app/myapp"]
6.2 安全性
- 不要在镜像中硬编码密码或密钥,使用环境变量或 secrets
- 尽量以非 root 用户运行容器(Dockerfile 中用
USER指令) - 定期更新基础镜像以获取安全补丁
- 使用
docker scan扫描镜像漏洞 - 生产环境不要使用
--privileged标志
6.3 资源限制
# 限制 CPU 和内存
docker run -d --cpus=2 --memory=512m nginx
# 在 Compose 中限制
# docker-compose.yml
services:
web:
deploy:
resources:
limits:
cpus: "2"
memory: 512M
6.4 日志管理
容器日志如果不管理,可能占满磁盘:
# 限制容器日志大小(daemon.json 全局配置)
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
6.5 清理无用资源
Docker 长期使用会积累大量无用资源,定期清理:
# 清理所有未使用的资源(已停止容器、未使用网络、悬空镜像)
docker system prune
# 清理所有未使用的资源(包括未使用的镜像和卷)
docker system prune -a --volumes
# 分别清理
docker container prune # 清理已停止容器
docker image prune # 清理悬空镜像
docker image prune -a # 清理所有未使用镜像
docker volume prune # 清理未使用数据卷
docker network prune # 清理未使用网络
# 查看磁盘占用
docker system df
6.6 常见问题
问题:权限被拒绝(Permission denied)
# 将用户加入 docker 组
sudo usermod -aG docker $USER
newgrp docker
问题:容器启动后立即退出
Docker 容器的主进程退出后,容器就会停止。确保容器有持续运行的前台进程。
问题:端口冲突
# 查看哪个进程占用了端口
sudo lsof -i :80
sudo ss -tlnp | grep 80
结语
Docker 已经彻底改变了软件的开发和部署方式。从简单的 docker run 开始,你可以逐步深入到 Dockerfile 构建、Compose 编排、集群管理(Docker Swarm 或 Kubernetes)。
对于开发者来说,掌握 Docker 几乎已经成为必备技能。不管是本地开发环境搭建、CI/CD 流水线、还是生产环境部署,Docker 都能提供一致、可靠、高效的解决方案。
建议的学习路径:
- 学会
docker run、docker ps、docker exec等基础命令 - 学会编写 Dockerfile 构建自己的镜像
- 学会使用 Docker Compose 管理多容器应用
- 了解数据卷和网络的使用
- 进阶学习 Docker Swarm 或 Kubernetes
参考链接:
- Docker 官方文档:https://docs.docker.com/
- Docker Hub:https://hub.docker.com/
- Docker 入门教程:https://docs.docker.com/get-started/
- Docker Compose 文档:https://docs.docker.com/compose/

浙公网安备 33010602011771号