Docker 快速入门:从零到实践的全方位学习笔记
篇章一:Docker 核心概念入门
在深入实践之前,我们首先需要理解 Docker 的几个基本概念,这就像学习一门新语言前先掌握它的字母表一样重要。
1. 什么是 Docker?
简单来说,Docker 是一种容器化技术,它能将你的应用程序及其所有依赖打包到一个独立的、标准化的运行环境——容器(Container)中。运行这些容器的计算机我们称之为宿主机(Host)。
2. Docker vs. 虚拟机 (VM)
你可能会问,这听起来和虚拟机很像,它们有什么区别?
- 虚拟机:每个虚拟机都包含一个完整的操作系统内核。这使得它们相对笨重,启动慢,资源消耗大。
- Docker 容器:所有容器共享宿主机的操作系统内核。这使得容器非常轻量级,启动速度极快(秒级甚至毫秒级),资源占用也更少。
3. 镜像 (Image)
镜像是创建容器的模板。你可以把它想象成软件的“安装包”或者制作糕点的“模具”。我们用一个镜像(模具)可以创建出多个一模一样的容器(糕点)。
4. 仓库 (Registry)
仓库是集中存放和分发镜像的地方。这就像是 GitHub 存储代码仓库一样。
- Docker Hub 是 Docker 官方的公共仓库,上面有海量由官方或社区贡献的镜像,任何人都可以上传或下载。
理解了容器、镜像、仓库这三大核心概念,你就已经敲开了 Docker 的大门!
篇章二:Docker 环境安装
万事俱备,只欠东风。接下来,我们将在不同操作系统上安装 Docker。Docker 本质上是基于 Linux 内核的技术,因此在 Windows 和 macOS 上,它会通过一个轻量级的 Linux 子系统来运行。
1. 在 Linux (Ubuntu) 上安装
在 Linux 上安装 Docker 是最原生、最推荐的方式。
打开终端,执行以下命令下载安装脚本:
curl -fsSL https://get.docker.com -o get-docker.sh
使用管理员权限执行安装脚本:
sudo sh get-docker.sh
提示:
sudo
(Superuser Do) 用于获取管理员权限。如果你的当前用户不是root
,在后续执行所有docker
命令时,都需要在前面加上sudo
。
等待片刻,安装即可完成。
2. 在 Windows 上安装
开启所需功能:
- 在任务栏搜索 "启用或关闭 Windows 功能"。
- 勾选 "虚拟机平台 (Virtual Machine Platform)" 和 "适用于 Linux 的 Windows 子系统 (Windows Subsystem for Linux, WSL)"。
- 根据提示重启电脑。
安装并配置 WSL:
电脑重启后,以管理员身份打开命令提示符 (CMD)。
设置 WSL 默认版本为 2:
wsl --set-default-version 2
更新 WSL 内核:
wsl --update # 国内网络建议使用以下命令,加速下载 wsl --update --web-download
安装 Docker Desktop:
- 从 Docker 官网下载适用于 Windows 的 Docker Desktop 安装包。
- 双击安装,一路 "Next" 即可。安装完成后,确保 Docker Desktop 处于运行状态。
验证安装:
打开一个新的终端(CMD 或 PowerShell),输入:
docker --version
如果成功打印出版本号,说明安装成功。
3. 在 macOS 上安装
在 Mac 上安装最为简单。根据你的芯片(Intel 或 Apple Silicon M系列)从 Docker 官网下载对应的 .dmg
安装包,拖拽安装即可。
篇章三:Docker 镜像管理
环境就绪,我们来学习如何管理 Docker 的“模具”——镜像。
1. 拉取镜像 (docker pull
)
docker pull
命令用于从仓库下载镜像。一个完整的镜像名结构如下: [registry_address]/[namespace]/[repository_name]:[tag]
registry_address
: 仓库地址,如docker.io
(Docker Hub)。官方仓库地址可以省略。namespace
: 命名空间,通常是作者或组织名。官方镜像的library
命名空间可以省略。repository_name
: 镜像库名称,如nginx
。tag
: 标签,通常是版本号,如1.28.0
。latest
或不写表示最新版。
示例:
# 完整写法
sudo docker pull docker.io/library/nginx:latest
# 简化写法(最常用)
sudo docker pull nginx
国内网络加速: 如果
docker pull
因网络问题失败,可以配置国内镜像加速器。
Linux: 修改
/etc/docker/daemon.json
文件,添加以下内容后重启 Docker 服务。{ "registry-mirrors": ["https://hub-mirror.c.163.com", "https://mirror.baidubce.com"] }
重启命令:
sudo systemctl restart docker
Windows/Mac: 打开 Docker Desktop -> Settings -> Docker Engine,在 JSON 配置中加入
"registry-mirrors": [...]
字段,然后点击 "Apply & Restart"。
2. 查看本地镜像 (docker images
)
此命令可以列出所有已经下载到本地的镜像。
sudo docker images
3. 删除本地镜像 (docker rmi
)
rmi
是 Remove Image 的缩写。你可以通过镜像名或镜像ID来删除。
# 通过镜像名删除
sudo docker rmi nginx
# 通过镜像ID删除(ID可以只写前几位,能唯一区分即可)
sudo docker rmi 3f8a00f42922
4. 指定 CPU 架构 (--platform
)
在某些场景下,如在 ARM 架构的设备(如树莓派、香橙派)上运行时,需要拉取特定 CPU 架构的镜像。
# 拉取 ARM64 架构的镜像
docker pull --platform=linux/arm64 some-image
注意:Mac M系列芯片也是 ARM64 架构,但 Docker Desktop 会通过 QEMU 模拟来兼容部分 AMD64 镜像,不过可能会有性能损耗或兼容性问题。
篇章四:Docker 容器操作(核心)
这是本篇笔记最重要的部分,我们将学习如何使用镜像创建和管理容器。
1. 创建并运行容器 (docker run
)
这是最核心的命令,它从一个镜像创建一个新的容器并启动它。
# 启动一个 nginx 容器
sudo docker run nginx
这会在前台启动容器,并会持续输出日志,阻塞当前终端。
docker run
的常用参数:
-d
(Detached): 后台运行容器,并返回容器ID。这是最常用的模式。sudo docker run -d nginx
-p
(Port Mapping): 端口映射,格式为-p <宿主机端口>:<容器端口>
。 Docker 容器网络默认与宿主机隔离,需要通过端口映射才能从外部访问容器内的服务。# 将宿主机的8080端口映射到容器的80端口 sudo docker run -d -p 8080:80 nginx
现在,访问
http://<宿主机IP>:8080
就能看到 Nginx 的欢迎页面了。-v
(Volume): 挂载卷,用于数据持久化,格式为-v <宿主机目录/卷名>:<容器内目录>
。 容器被删除时,其内部数据也会丢失。挂载卷可以将容器内的数据同步到宿主机,实现持久化。绑定挂载 (Bind Mount): 直接指定宿主机路径。
# 将宿主机的 /home/user/html 目录挂载到容器的 /usr/share/nginx/html sudo docker run -d -p 8080:80 -v /home/user/html:/usr/share/nginx/html nginx
注意:绑定挂载时,宿主机目录会覆盖容器内目录。如果宿主机目录为空,容器内对应目录也会变空。
命名卷挂载 (Named Volume): 由 Docker 管理的存储空间。
# 1. 创建一个命名卷 sudo docker volume create my-nginx-data # 2. 运行时使用卷名挂载 sudo docker run -d -p 8080:80 -v my-nginx-data:/usr/share/nginx/html nginx
优点:命名卷首次挂载时,会将容器内目录的原始文件复制到卷中,避免了空目录覆盖的问题。
-e
(Environment): 设置环境变量。# 启动一个 MongoDB,并通过环境变量设置用户名和密码 sudo docker run -d -p 27017:27017 \ -e MONGO_INITDB_ROOT_USERNAME=myuser \ -e MONGO_INITDB_ROOT_PASSWORD=mypassword \ mongo
--name
: 给容器指定一个自定义的名字,方便管理。sudo docker run -d --name my-web-server -p 8080:80 nginx
--restart
: 配置重启策略。--restart=always
: 无论因何种原因停止,容器都会自动重启。--restart=unless-stopped
: 除非是手动执行docker stop
停止,否则都会自动重启(推荐用于生产环境)。
-it
和--rm
: 常用组合,用于临时调试。-it
: 提供一个交互式的 TTY 终端。--rm
: 容器退出后自动删除。
# 启动一个临时的、轻量级的 Alpine Linux 容器进行调试 sudo docker run -it --rm alpine sh # (进入容器内) # exit (退出后容器自动销毁)
2. 容器生命周期管理
docker ps
: 查看正在运行的容器 (ps: Process Status)。docker ps -a
: 查看所有容器(包括已停止的)。
docker stop <容器名/ID>
: 停止一个正在运行的容器。docker start <容器名/ID>
: 启动一个已停止的容器。docker rm <容器名/ID>
: 删除一个已停止的容器。docker rm -f <容器名/ID>
: 强制删除一个正在运行的容器。
docker logs <容器名/ID>
: 查看容器日志。docker logs -f <容器名/ID>
: 实时滚动查看日志。
3. 进入容器内部 (docker exec
)
exec
命令可以在一个正在运行的容器内部执行命令。最常见的用法是进入容器的 shell 环境进行调试。
# 1. 先启动一个 nginx 容器
sudo docker run -d --name my-nginx nginx
# 2. 进入该容器的 shell 环境
sudo docker exec -it my-nginx /bin/sh
-it
: 保持交互式连接。/bin/sh
或/bin/bash
: 容器内可用的 shell 程序。
进入容器后,你就可以像在普通 Linux 系统里一样执行命令,查看文件,调试程序了。
篇章五:自定义镜像 (Dockerfile)
当官方镜像无法满足你的需求时,就需要自己构建镜像。Dockerfile 就是一个用来定义镜像构建步骤的文本文件。
类比:如果镜像是“模具”,那 Dockerfile 就是“模具的设计图纸”。
Dockerfile 实战:打包一个 Python Web 应用
假设我们有一个简单的 FastAPI 应用:
main.py
:from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"}
requirements.txt
:fastapi uvicorn
1. 编写 Dockerfile
(文件名固定,D大写,无后缀)
# 1. 选择一个包含 Python 环境的基础镜像
FROM python:3.11-slim
# 2. 设置工作目录
WORKDIR /app
# 3. 将当前目录下的所有文件复制到镜像的 /app 目录
COPY . .
# 4. 在镜像内执行命令,安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 5. 声明容器对外暴露的端口(仅为文档作用,无实际效果)
EXPOSE 8000
# 6. 定义容器启动时默认执行的命令
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
2. 构建镜像 (docker build
) 在 Dockerfile
所在目录下执行:
# -t 表示 tag,给镜像命名
# . 表示使用当前目录作为构建上下文
sudo docker build -t my-python-app:1.0 .
3. 运行自定义镜像
sudo docker run -d --name my-app-instance -p 8000:8000 my-python-app:1.0
现在访问 http://<宿主机IP>:8000
就可以看到 {"Hello": "World"}
了。
4. 推送镜像到 Docker Hub (docker push
)
登录 Docker Hub:
sudo docker login
给镜像打上符合规范的标签:
<你的DockerHub用户名>/<镜像名>:<版本号>
sudo docker tag my-python-app:1.0 your-username/my-python-app:1.0
推送镜像:
sudo docker push your-username/my-python-app:1.0
现在,任何人都可以通过 docker pull your-username/my-python-app:1.0
下载你的镜像了!
篇章六:Docker 网络
Docker 提供了多种网络模式来满足不同场景的需求。
Bridge (桥接模式): 默认模式。Docker 会创建一个虚拟网桥,所有容器连接到这个网桥上,并分配一个内部 IP。容器间可以通过内部 IP 通信,但与宿主机隔离。
自定义 Bridge 网络: 这是推荐的做法。我们可以创建一个自定义网络,让相关的容器加入其中。
# 1. 创建网络 sudo docker network create my-app-net # 2. 启动容器并加入网络 sudo docker run -d --name db --network my-app-net mongo sudo docker run -d --name web --network my-app-net -p 80:80 my-webapp
好处:在同一个自定义网络中,容器之间可以直接通过容器名(如
db
)作为主机名进行通信,Docker 内置了 DNS 解析。Host (主机模式): 容器直接共享宿主机的网络栈,不再有网络隔离。容器的服务直接暴露在宿主机的端口上,无需
-p
映射。性能最好,但牺牲了安全性。sudo docker run -d --network host nginx
None (无网络模式): 容器拥有自己的网络栈,但不进行任何网络配置。一个完全隔离的网络环境。
篇章七:容器编排 (Docker Compose)
当你的应用由多个容器(如前端、后端、数据库、缓存)组成时,手动管理 docker run
命令会变得非常繁琐。Docker Compose 正是为此而生。它是一个用于定义和运行多容器 Docker 应用程序的工具。
你只需使用一个 YAML
文件来配置应用的服务,然后用一条命令,就可以创建并启动所有服务。
Docker Compose 实战:部署 MongoDB 和 Mongo Express
1. 创建 docker-compose.yml
文件 这个文件清晰地定义了两个服务:一个数据库 (db
) 和一个数据库管理界面 (mongo-express
)。
version: '3.8'
services:
db:
image: mongo:latest
container_name: my-mongo-db
restart: unless-stopped
volumes:
- mongo-data:/data/db
mongo-express:
image: mongo-express:latest
container_name: my-mongo-express
restart: unless-stopped
ports:
- "8081:8081"
environment:
- ME_CONFIG_MONGODB_SERVER=db # 使用服务名 'db' 连接数据库
- ME_CONFIG_MONGODB_ADMINUSERNAME=myuser
- ME_CONFIG_MONGODB_ADMINPASSWORD=mypassword
depends_on:
- db # 确保 db 服务先于此服务启动
volumes:
mongo-data:
亮点:
services
下的db
和mongo-express
分别对应一个容器。image
,ports
,volumes
,environment
等参数与docker run
的标志一一对应。- Docker Compose 会自动创建一个默认网络,并将所有服务加入其中,所以
mongo-express
可以直接通过服务名db
访问数据库。 depends_on
定义了服务间的启动依赖。
2. 使用 Docker Compose 命令 在 docker-compose.yml
文件所在目录下执行:
启动所有服务 (后台模式):
docker compose up -d
停止并删除所有服务、网络和卷:
docker compose down
仅停止服务 (不删除):
docker compose stop
启动已停止的服务:
docker compose start
Docker Compose 极大地简化了多容器应用的部署和管理,是开发和测试环境的利器。对于更大规模、更复杂的生产环境集群,你可能需要了解更强大的编排工具,如 Kubernetes (K8s)。
总结
恭喜你!通过这篇笔记,你已经系统地学习了 Docker 的核心知识体系:
- 三大概念:镜像、容器、仓库。
- 环境搭建:在主流操作系统上安装 Docker。
- 镜像管理:
pull
,images
,rmi
。 - 容器全生命周期管理:
run
,ps
,stop
,start
,rm
,logs
,exec
。 - 自定义镜像:通过
Dockerfile
和build
命令创建自己的镜像。 - 网络模型:理解 Bridge 和 Host 模式,并学会使用自定义网络。
- 容器编排:使用
Docker Compose
优雅地管理多容器应用。