01 认识 Docker
在敲第一条命令之前,先花几分钟搞清楚:容器到底是什么、它解决了什么问题。理解了这一节,后面所有命令都会变得很自然。
1. 部署的痛点:「在我电脑上能跑啊」
想象一个经典场景:你在自己电脑上写了一个 Python 项目,跑得好好的,交给同事或者部署到服务器上就报错:
- 服务器的 Python 是 3.8,你本地是 3.12
- 服务器上没装某个系统依赖库
- 配置文件路径不一样、环境变量没设
- 同一台服务器上另一个项目要用不同版本的 MySQL
根本原因是:程序 = 代码 + 运行环境,而我们通常只交付了代码,环境全靠手工搭建,一台机器一个样。
2. Docker 的解决思路:连环境一起打包
Docker 的做法很直接:把代码、运行时、系统库、配置统统打包成一个标准化的「箱子」,在哪台机器上都以完全相同的方式运行。
这个箱子有两种形态:
| 概念 | 类比 | 说明 |
|---|---|---|
| 镜像(Image) | 安装包 / 模板 | 只读的打包文件,包含程序和完整运行环境 |
| 容器(Container) | 运行中的程序 | 镜像跑起来之后的实例,可以启动、停止、删除 |
一个镜像可以启动多个容器,就像一个安装包可以装出多个程序实例。
3. 容器和虚拟机的区别
有人会问:这不就是虚拟机吗?不是。
- 虚拟机:虚拟出完整的硬件,里面跑一个完整的操作系统,启动要分钟级,占用几个 GB 内存
- 容器:直接共享宿主机的 Linux 内核,只隔离进程、网络、文件系统,启动是秒级,占用 MB 级内存
虚拟机:App → 客户机操作系统 → 虚拟硬件 → 宿主机操作系统 → 硬件
容 器:App → 容器引擎(Docker) → 宿主机操作系统 → 硬件
所以容器轻量、启动快、密度高——一台普通服务器跑几十个容器很正常。
4. Docker 的核心概念一览
先混个眼熟,后面每一个都会实际用到:
| 概念 | 说明 |
|---|---|
| 镜像(Image) | 只读模板,如 nginx:1.25、python:3.12 |
| 容器(Container) | 镜像的运行实例 |
| 仓库(Registry) | 存放镜像的服务器,官方的叫 Docker Hub |
| Dockerfile | 一个文本文件,描述「怎么构建镜像」 |
| 数据卷(Volume) | 把数据存到容器外面,容器删了数据还在 |
| 网络(Network) | 让多个容器之间能互相访问 |
它们的关系可以用一句话串起来:
用 Dockerfile 构建出 镜像,推送到 仓库;在服务器上拉取镜像并启动为 容器,数据挂到 数据卷,容器之间通过 网络 通信。
5. Docker 的典型使用场景
- 部署应用:把项目打包成镜像,服务器上一条命令启动,这是本教程的主线
- 统一开发环境:本地要用 MySQL 8 + Redis 7?各起一个容器,用完就删,不污染系统
- CI/CD:构建、测试都在干净的容器里进行,结果可复现
- 快速试用软件:想试试某个数据库、某个工具,
docker run一下,不用装到系统里
6. 一个直观的例子
不用安装 Nginx,一条命令就能在本机跑起一个 Web 服务器(下一章装好 Docker 后你就可以亲手试):
docker run -d -p 8080:80 nginx:1.25
这条命令做了什么:
- 本地没有
nginx:1.25镜像,就自动从仓库下载 - 用这个镜像启动一个容器,在后台运行(
-d) - 把宿主机的 8080 端口映射到容器的 80 端口(
-p 8080:80)
然后浏览器打开 http://localhost:8080 就能看到 Nginx 欢迎页。用完删掉容器,系统干干净净,就像什么都没发生过。
小结
- Docker 解决的是环境不一致的问题:把程序和环境一起打包
- 镜像是模板,容器是运行实例,一个镜像可以起多个容器
- 容器不是虚拟机,它更轻、更快
- 记住核心类比:镜像 = 安装包,容器 = 运行中的程序
下一章我们把 Docker 装起来:02-安装Docker