Docker入门

Docker 实战笔记

视频来源:40分钟的Docker实战攻略,一期视频精通Docker


一、Docker 简介

1.1 什么是 Docker?

Docker 是目前最成熟高效的软件部署技术,通过容器化技术给应用程序封装独立的运行环境,每个运行环境就是一个容器

运行容器的计算机被称为 宿主机(Host)

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────────────────────┐
│ 宿主机 (Host) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Docker 引擎 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 容器 A │ │ 容器 B │ │ 容器 C │ │ │
│ │ │ (Nginx) │ │ (MySQL) │ │ (Redis) │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ 共享操作系统内核 │
└─────────────────────────────────────────────────────────┘

1.2 Docker vs 虚拟机

特性 Docker 容器 虚拟机 (VM)
系统内核 共享宿主机内核 每个 VM 独立内核
启动速度 秒级 分钟级
资源占用 轻量(MB级) 重量级(GB级)
性能 接近原生 有虚拟化开销
隔离性 进程级隔离 系统级隔离
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Docker 架构:                    虚拟机架构:
┌─────────────┐ ┌─────────────┐
│ 容器 A │ │ VM A │
│ 容器 B │ │ ┌───────┐ │
│ 容器 C │ │ │ 应用A │ │
├─────────────┤ │ ├───────┤ │
│ Docker引擎 │ │ │ 系统A │ │
├─────────────┤ │ └───────┘ │
│ 宿主机OS │ └─────────────┘
├─────────────┤ ┌─────────────┐
│ 宿主机硬件 │ │ VM B │
└─────────────┘ │ ┌───────┐ │
│ │ 应用B │ │
│ ├───────┤ │
│ │ 系统B │ │
│ └───────┘ │
└─────────────┘
┌─────────────┐
│ Hypervisor │
├─────────────┤
│ 宿主机OS │
└─────────────┘

二、Docker 核心概念

2.1 镜像(Image)

镜像是容器的模板,可以理解为:

  • 📦 软件安装包 → 容器就是安装出来的软件
  • 🍰 模具 → 容器就是用模具做出来的糕点
  • 🧬 类(Class) → 容器就是对象(Object)
1
2
3
4
5
6
7
8
9
10
镜像层次结构:
┌─────────────────┐
│ 应用层 │ ← 你的应用程序代码
├─────────────────┤
│ 运行时层 │ ← Python/Node/Java
├─────────────────┤
│ 系统工具层 │ ← 依赖库、工具
├─────────────────┤
│ 基础镜像层 │ ← Alpine/Ubuntu/CentOS
└─────────────────┘

2.2 容器(Container)

容器是镜像的运行实例,是一个独立的运行环境。

1
2
3
4
5
6
7
8
9
10
同一个镜像 → 多个容器:

nginx:latest 镜像

┌────┼────┐
↓ ↓ ↓
┌─────┐┌─────┐┌─────┐
│Web-1││Web-2││Web-3│
│:80 ││:81 ││:82 │
└─────┘└─────┘└─────┘

2.3 镜像仓库(Registry)

Docker 仓库是用来存放和分享镜像的地方。

  • 官方仓库: Docker Hub
  • 国内镜像站: 阿里云、网易云、中科大等
1
2
3
4
5
6
7
8
9
10
Docker Hub 工作流程:

开发者A Docker Hub 开发者B
│ │ │
│ 推送镜像 │ │
│ ──────────────> │ │
│ │ │
│ │ 拉取镜像 │
│ │ <────────────── │
│ │ │

三、Docker 安装

3.1 Linux 安装(Ubuntu/Debian)

1
2
3
4
5
6
7
8
# 第一步:下载安装脚本
curl -fsSL https://get.docker.com -o install-docker.sh

# 第二步:执行安装
sudo sh install-docker.sh

# 验证安装
docker --version

3.2 配置国内镜像源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 编辑配置文件
sudo vi /etc/docker/daemon.json

# 添加以下内容
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}

# 重启 Docker
sudo service docker restart

3.3 Windows/Mac 安装

  1. 下载 Docker Desktop
  2. 安装并启动
  3. 设置 → Docker Engine → 添加镜像源配置

四、Docker 常用命令

4.1 镜像命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest
docker pull nginx:alpine # 轻量版

# 查看本地镜像
docker images

# 删除镜像
docker rmi nginx:latest

# 查看镜像详情
docker inspect nginx

4.2 容器生命周期命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# ========== 创建并运行容器 ==========
# 基础启动(前台模式,Ctrl+C退出)
docker run nginx

# 后台运行 + 端口映射 + 命名
docker run -d --name web -p 80:80 nginx:alpine

# 带环境变量(如MySQL密码)
docker run -e MYSQL_ROOT_PASSWORD=123456 mysql

# 常用参数说明:
# -d: 后台运行(守护模式)
# -p: 端口映射(主机端口:容器端口)
# -v: 挂载数据卷(/host/path:/container/path)
# --name: 指定容器名称
# --restart=always: 崩溃后自动重启
# -e: 设置环境变量


# ========== 停止/删除容器 ==========
# 优雅停止(允许完成当前请求)
docker stop web

# 强制终止(立即kill)
docker kill web

# 删除已停止的容器
docker rm web

# 强制删除运行中的容器
docker rm -f web


# ========== 暂停与恢复 ==========
# 暂停容器(冻结进程)
docker pause web

# 恢复运行
docker unpause web

4.3 容器操作与监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 列出运行中的容器
docker ps

# 查看所有容器(包括已停止的)
docker ps -a

# 只显示容器ID(用于脚本)
docker ps -q

# 查看容器日志(调试必备)
docker logs -f --tail 100 web

# 查看容器内进程树
docker top web

# 查看容器详细配置(JSON格式)
docker inspect web

# 查看容器资源使用情况
docker stats

# 进入容器内部(调试用)
docker exec -it web /bin/sh
docker exec -it web /bin/bash

4.4 实用运维命令

1
2
3
4
5
6
7
8
9
10
11
# 一键清理停止的容器和悬空镜像
docker system prune -f

# 查看 Docker 磁盘使用情况
docker system df

# 从容器拷贝文件到主机
docker cp web:/usr/share/nginx/html/index.html ./

# 从主机拷贝文件到容器
docker cp ./index.html web:/usr/share/nginx/html/

五、Docker 网络

5.1 网络类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌─────────────────────────────────────────────────────────┐
│ 宿主机 │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Docker 网络 │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ bridge │ │ host │ │ │
│ │ │ (默认) │ │ (主机) │ │ │
│ │ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │
│ │ ┌────┴────┐ ┌────┴────┐ │ │
│ │ │容器A │ │容器B │ │ │
│ │ │172.17.0│ │宿主机IP │ │ │
│ │ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
网络类型 说明
bridge 默认模式,容器通过 Docker 网桥通信
host 容器使用宿主机网络栈
none 容器没有网络接口
自定义bridge 用户创建的桥接网络,支持DNS服务发现

5.2 端口映射

1
2
3
4
5
6
7
8
9
10
# 端口映射格式: -p 宿主机端口:容器端口

# 例1: 将容器的80端口映射到宿主机的8080端口
docker run -d -p 8080:80 nginx

# 例2: 随机分配宿主机端口
docker run -d -p 80 nginx

# 例3: 指定IP绑定
docker run -d -p 127.0.0.1:8080:80 nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
端口映射示意图:

外部用户

↓ http://宿主机IP:8080
┌─────────────┐
│ 宿主机 │
│ 端口:8080 │
└──────┬──────┘
│ Docker 转发

┌─────────────┐
│ 容器 │
│ 端口:80 │
│ (Nginx) │
└─────────────┘

5.3 自定义网络(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
# 创建自定义网络
docker network create my-app-network

# 查看网络列表
docker network ls

# 运行容器并指定网络
docker run -d --name web --network my-app-network -p 80:80 nginx
docker run -d --name db --network my-app-network mysql

# 在自定义网络中,容器可以通过名称互相访问
docker exec -it web ping db # 可以ping通!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
自定义网络优势:

默认 bridge 网络: 自定义 bridge 网络:
┌─────────┐ ┌─────────┐
│ 容器A │ │ 容器A │
│ IP: 172 │ │ 名称:web │◄────┐
└────┬────┘ └────┬────┘ │
│ │ │ 通过名称访问
│ 只能通过IP │ │ web → db
↓ ↓ │
┌─────────┐ ┌─────────┐ │
│ 容器B │ │ 容器B │◄────┘
│ IP: 173 │ │ 名称:db │
└─────────┘ └─────────┘

六、Docker 数据持久化

6.1 数据卷(Volume)

容器是临时的,数据需要持久化保存!

1
2
3
4
5
6
7
8
9
10
数据卷原理:

┌─────────────┐ ┌─────────────┐
│ 容器 │ │ 宿主机 │
│ ┌───────┐ │ 挂载 │ ┌───────┐ │
│ │/data │◄─┼─────────────┼──┤/host/ │ │
│ │(临时) │ │ │ │data │ │
│ └───────┘ │ │ │(持久) │ │
└─────────────┘ │ └───────┘ │
└─────────────┘

6.2 挂载方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ========== 方式1: 挂载主机目录(适合开发环境)==========
docker run -v /host/path:/container/path nginx

# 例: 挂载网站代码
docker run -d -p 80:80 -v /home/user/website:/usr/share/nginx/html nginx


# ========== 方式2: 使用命名卷(推荐生产环境)==========
# 创建命名卷
docker volume create mydata

# 使用命名卷
docker run -v mydata:/data mysql

# 查看所有卷
docker volume ls


# ========== 方式3: 匿名挂载 ==========
docker run -v /container/path nginx

6.3 MySQL 数据持久化实战

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建本地目录
mkdir -p /home/mysql/conf /home/mysql/data

# 运行 MySQL 并挂载数据卷
docker run -d \
-p 3306:3306 \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql01 \
mysql:5.7

# 即使删除容器,数据仍然保留在 /home/mysql/data

七、Dockerfile 构建镜像

7.1 Dockerfile 指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# ========== 基础指令 ==========
# 指定基础镜像
FROM ubuntu:22.04

# 维护者信息
LABEL maintainer="yourname@example.com"

# 设置工作目录
WORKDIR /app

# ========== 构建指令 ==========
# 执行命令(构建时执行)
RUN apt-get update && apt-get install -y python3

# 复制文件到镜像
COPY . /app

# 添加远程文件/压缩包
ADD https://example.com/file.tar.gz /app/

# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000

# ========== 运行指令 ==========
# 暴露端口
EXPOSE 3000

# 挂载数据卷
VOLUME ["/data"]

# 容器启动时执行的命令
CMD ["python3", "app.py"]

# 或设置入口点
ENTRYPOINT ["python3"]
CMD ["app.py"]

7.2 Dockerfile 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
# Python Flask 应用 Dockerfile
FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 5000

CMD ["python", "app.py"]
1
2
3
4
5
6
7
8
9
10
11
12
13
# Node.js 应用 Dockerfile
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "server.js"]

7.3 构建镜像

1
2
3
4
5
6
7
8
# 构建镜像(注意最后的点表示当前目录)
docker build -t myapp:v1 .

# 指定 Dockerfile 路径
docker build -t myapp:v1 -f /path/to/Dockerfile .

# 查看构建历史
docker history myapp:v1

八、Docker Compose 多容器管理

8.1 什么是 Docker Compose?

Docker Compose 用于定义和运行多容器应用,通过一个 YAML 文件配置所有服务。

1
2
3
4
5
6
7
8
9
10
Docker Compose 架构:

docker-compose.yml

┌─────────┼─────────┐
↓ ↓ ↓
┌───────┐ ┌───────┐ ┌───────┐
│ Web │ │ DB │ │ Cache │
│(Nginx)│ │(MySQL)│ │(Redis)│
└───────┘ └───────┘ └───────┘

8.2 docker-compose.yml 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
version: '3.8'

services:
# Web 服务
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
networks:
- my-network

# API 服务
api:
build: ./api
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
depends_on:
- db
networks:
- my-network

# 数据库服务
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- db_data:/var/lib/mysql
networks:
- my-network

# 缓存服务
redis:
image: redis:alpine
networks:
- my-network

# 数据卷定义
volumes:
db_data:

# 网络定义
networks:
my-network:
driver: bridge

8.3 Docker Compose 命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 启动所有服务(后台运行)
docker-compose up -d

# 停止所有服务
docker-compose stop

# 停止并删除容器
docker-compose down

# 停止并删除容器+数据卷
docker-compose down -v

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs -f

# 重启服务
docker-compose restart

# 重新构建镜像
docker-compose build

# 拉取最新镜像
docker-compose pull

九、实战案例

9.1 部署 Nginx 静态网站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 创建目录
mkdir -p ~/docker/nginx/html
cd ~/docker/nginx

# 2. 创建首页
echo "<h1>Hello Docker!</h1>" > html/index.html

# 3. 运行容器
docker run -d \
--name my-nginx \
-p 8080:80 \
-v $(pwd)/html:/usr/share/nginx/html \
nginx:alpine

# 4. 访问 http://localhost:8080

9.2 部署 WordPress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# docker-compose.yml
version: '3.8'

services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress

wordpress:
image: wordpress:latest
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
- wp_data:/var/www/html
depends_on:
- db

volumes:
db_data:
wp_data:
1
2
3
4
# 启动 WordPress
docker-compose up -d

# 访问 http://localhost:8000

十、常见问题排查

10.1 容器启动失败

1
2
3
4
5
6
7
8
# 查看失败容器的日志
docker logs <container_id>

# 检查端口冲突
netstat -tuln | grep 80

# 查看容器详细配置
docker inspect <container_id>

10.2 网络连接问题

1
2
3
4
5
6
7
8
# 测试容器间连通性
docker exec -it web ping database

# 检查 DNS 配置
docker run --dns 8.8.8.8 alpine

# 查看网络详情
docker network inspect my-app-network

10.3 权限问题

1
2
3
4
# Linux 下需要 sudo 或添加用户到 docker 组
sudo usermod -aG docker $USER

# 重新登录后生效

十一、学习路线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Docker 学习路线:

入门阶段 进阶阶段 高级阶段
──────── ──────── ────────
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 理解核心概念 │ │ Dockerfile │ │ Docker │
│ 镜像/容器/仓库│ → │ 构建镜像 │ → │ Swarm │
├─────────────┤ ├─────────────┤ ├─────────────┤
│ 安装 Docker │ │ Docker │ │ Kubernetes │
├─────────────┤ │ Compose │ ├─────────────┤
│ 基础命令 │ ├─────────────┤ │ CI/CD 集成 │
│ pull/run/ps │ │ 网络配置 │ ├─────────────┤
├─────────────┤ │ 数据卷管理 │ │ 镜像安全扫描│
│ 端口映射 │ ├─────────────┤ └─────────────┘
│ 环境变量 │ │ 多容器编排 │
└─────────────┘ └─────────────┘

十二、常用命令速查表

命令 说明
docker pull <image> 拉取镜像
docker images 查看本地镜像
docker rmi <image> 删除镜像
docker run <image> 运行容器
docker ps 查看运行中的容器
docker ps -a 查看所有容器
docker stop <container> 停止容器
docker start <container> 启动容器
docker rm <container> 删除容器
docker logs <container> 查看日志
docker exec -it <container> /bin/sh 进入容器
docker build -t <name> . 构建镜像
docker-compose up -d 启动所有服务
docker-compose down 停止并删除服务

参考资料


💡 提示: 本笔记基于 B站视频《40分钟的Docker实战攻略,一期视频精通Docker》整理,建议配合视频学习效果更佳!