01 Docker基础入门
你刚写好一个AI Agent服务,在你的Mac上跑得很好。丢给同事,他的Windows上跑不起来——Python版本不对、缺了系统依赖、环境变量没配。"在我电脑上能跑啊"这句话,Docker就是来解决它的。
把应用和它需要的一切打包成一个镜像,不管在谁的电脑上、什么操作系统,都能一模一样地跑起来。
一、Docker是什么
Docker是一个开源的应用容器化平台,核心能力是:把应用和运行环境打包在一起,实现一次构建、到处运行。
传统的部署方式是:在服务器上装Python、装依赖、配环境、传代码、祈祷不出问题。Docker的方式是:把代码、Python运行时、依赖库、配置文件全部塞进一个"容器"里,这个容器在任何装了Docker的机器上都能跑。
1.1 容器和虚拟机的区别
很多人把容器和虚拟机搞混,其实它们完全不同。
| 对比项 | 虚拟机 | 容器 |
|---|---|---|
| 隔离级别 | 完整的操作系统内核 | 进程级隔离 |
| 启动速度 | 分钟级 | 秒级 |
| 资源占用 | 大(每个VM独立内核) | 小(共享宿主机内核) |
| 镜像大小 | GB级 | MB级 |
| 适合场景 | 需要完整OS隔离 | 应用级别的隔离和部署 |
简单说:虚拟机是一栋独立的房子,容器是一个集装箱。集装箱轻便、标准、可以快速搬来搬去。
1.2 Docker的核心价值
Docker解决三个核心问题:
- 环境一致性——开发、测试、生产环境完全一样,告别"在我电脑上能跑"
- 快速部署——镜像打包一次,秒级启动,不需要在每台机器上重新安装依赖
- 资源高效——容器共享操作系统内核,比虚拟机轻量得多,一台服务器能跑更多应用
二、Docker架构
Docker采用客户端-服务端架构。
┌──────────────────┐
│ Docker Client │ ← 你敲的 docker 命令
│ (docker CLI) │
└────────┬─────────┘
│ REST API
▼
┌──────────────────┐
│ Docker Daemon │ ← 后台服务,干脏活累活
│ (dockerd) │
└────────┬─────────┘
│
┌────┴────┐
▼ ▼
镜像 容器
(Images) (Containers)- Docker Client:就是你在终端里敲的
docker命令,它把你的指令发送给Docker Daemon - Docker Daemon:后台守护进程,负责构建镜像、运行容器、管理网络和存储
- Docker Registry:存储和分发镜像的服务,Docker Hub是最常用的公共仓库
Client和Daemon可以在同一台机器上,也可以通过网络连接远程的Daemon。
三、容器
容器是镜像的运行实例。一个镜像可以启动多个容器,每个容器之间相互隔离。
容器有四个关键特性:
- 自包含——容器包含运行所需的一切,不依赖宿主机上预装的任何东西
- 隔离——容器之间互不影响,一个容器崩了不影响其他容器
- 独立——每个容器独立管理,删除一个不影响其他容器
- 可移植——在你的Mac上跑的容器,在Linux服务器上也能跑
3.1 第一个容器
安装好Docker Desktop之后,试一下:
docker run -d -p 8080:80 docker/welcome-to-docker这条命令做了什么:
- 从Docker Hub拉取
docker/welcome-to-docker镜像 - 创建一个新容器
- 把容器的80端口映射到宿主机的8080端口
- 在后台运行(
-d)
打开浏览器访问http://localhost:8080,你会看到一个欢迎页面。
3.2 常用容器命令
# 查看正在运行的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop <容器ID>
# 启动已停止的容器
docker start <容器ID>
# 删除容器
docker rm <容器ID>
# 进入容器内部
docker exec -it <容器ID> /bin/bashdocker ps输出里有容器ID、使用的镜像、运行状态、端口映射等信息。用容器ID的前几位就够了,不需要写全。
四、镜像
镜像是一个只读的模板,包含了运行容器所需的所有文件和配置。你可以把镜像理解成一个"安装光盘",容器就是从光盘安装出来的"系统"。
镜像有两个重要特点:
- 不可变——镜像一旦创建就不能修改,只能基于它创建新镜像
- 分层存储——镜像由多个层(layer)组成,每一层代表一组文件系统变更
4.1 镜像的分层结构
一个典型的Python应用镜像可能长这样:
第5层:复制应用源代码 (几KB)
第4层:安装pip依赖 (几十MB)
第3层:复制requirements.txt (几百字节)
第2层:安装Python运行时 (几百MB)
第1层:基础Linux系统 (几十MB)层的好处是可以复用。如果你有两个Python应用,它们共享前两层(基础系统+Python运行时),不需要重复存储。改了代码只重建最上面几层,不用全部重来。
4.2 镜像操作命令
# 拉取镜像
docker pull python:3.12-alpine
# 查看本地镜像列表
docker images
# 查看镜像的层信息
docker image history <镜像名>
# 删除镜像
docker rmi <镜像名>
# 给镜像打标签
docker tag <镜像名> <新标签>4.3 镜像标签
镜像用标签来区分版本。python:3.12-alpine中,python是镜像名,3.12-alpine是标签。如果不写标签,默认是latest。
注意:不要在生产环境用latest标签。 因为latest指向的版本可能会变,今天构建用的latest和三个月后的latest可能是不同版本。明确指定版本号才能保证构建结果一致。
五、仓库
Docker Registry(仓库)是用来存储和分发镜像的服务。Docker Hub是最常用的公共仓库,类似GitHub之于代码,Docker Hub之于镜像。
5.1 Docker Hub
Docker Hub上有三类镜像:
| 类型 | 说明 | 示例 |
|---|---|---|
| Docker Official Images | 官方维护,安全可靠 | python、nginx、redis |
| Docker Verified Publishers | 经过Docker认证的商业镜像 | datadog、gitlab |
| 社区镜像 | 任何人可以发布 | 各种第三方镜像 |
生产环境优先使用官方镜像或Verified Publisher镜像,社区镜像需要仔细审查。
5.2 推送镜像到仓库
# 登录Docker Hub
docker login
# 给镜像打标签(格式:用户名/镜像名:标签)
docker tag my-app:1.0 yourusername/my-app:1.0
# 推送镜像
docker push yourusername/my-app:1.0也可以搭建私有仓库来存储内部镜像,不在这里展开。
六、总结
Docker的核心概念就四个:
| 概念 | 是什么 | 类比 |
|---|---|---|
| 容器(Container) | 镜像的运行实例 | 运行中的程序 |
| 镜像(Image) | 只读的模板 | 安装光盘 |
| 仓库(Registry) | 存储镜像的服务 | 应用商店 |
| Dockerfile | 构建镜像的脚本 | 安装说明书(下篇讲) |
最常用的命令:
| 命令 | 作用 |
|---|---|
docker run | 创建并启动容器 |
docker ps | 查看运行中的容器 |
docker images | 查看本地镜像 |
docker pull | 拉取镜像 |
docker stop | 停止容器 |
docker rm | 删除容器 |
这些概念和命令是后面所有内容的基础。下一篇我们会学习Dockerfile——用一个文本文件来定义镜像的构建过程,这才是Docker真正强大的地方。