Docker 核心学习笔记
模块一:Docker 基础镜像与容器命令
为什么要这么做(核心思路): 在服务器上部署应用时,我们需要一种标准化的方式来获取(Pull)、查看、运行(Run)和清理这些独立的应用环境。掌握这些基础命令,是完整接管容器生命周期的关键。
1. 镜像管理
docker pull(拉取镜像)
从镜像仓库下载指定的镜像。完整命令格式如下:
BASH
docker pull docker.io/library/nginx:latest
docker.io:Registry(仓库地址),这里表示是 Docker Hub 的官方仓库,可省略不写。
library:Namespace(命名空间/作者名),library 是 Docker Hub 官方的命名空间,官方镜像的命名空间可省略不写。
nginx:latest:Tag(标签/版本号)。
简化命令:
BASH
docker pull nginx
表示从 Docker 官方仓库的官方命名空间里面下载最新版的 Nginx Docker 镜像。
更多例子(拉取第三方/非官方镜像):
BASH
docker pull docker.n8n.io/n8nio/n8n
docker images(查看镜像)
列出本地所有已经下载的 Docker 镜像。
docker rmi(删除镜像)
rmi:
rm是 remove 的缩写,i指的是 image,即删除指定的镜像。用法:
docker rmi <镜像ID>指定要删除镜像的 ID。
2. 容器生命周期管理
docker run(运行容器)
基于指定的镜像创建并运行容器。
BASH
docker run nginx
注:上述的 docker pull nginx 和 docker run nginx 可以简化成只执行 docker run nginx。因为执行运行命令时,若发现本地没有对应的镜像,Docker 会自动尝试拉取。
docker ps(查看容器状态)
查看当前正在运行的进程/容器状况。输出核心字段说明:
CONTAINER ID:容器的 ID。每创建一个容器,就会自动分配一个唯一的 ID。
IMAGE:基于哪个指定的镜像创建出来的。
PORTS:设置占用的端口。
NAMES:若没有手动设置名字,系统会随机分配一个名字。
docker create(仅创建容器)
- 与
docker run的区别:docker create只创建容器,但不启动它,需要后续手动启动。
BASH
docker create -p 27017:27017 --name my_mongo mongo # 创建容器
docker start my_mongo # 手动启动容器
3. docker run 的常用核心参数
为什么要这么做(核心思路): 默认的容器是一个完全封闭且占用当前终端黑盒。通过组合参数,我们可以让它在后台持续运行、暴露服务端口给外部访问、注入密码等环境变量,以及允许我们进入内部进行调试。
-d(分离模式/后台运行)
直接运行 docker run nginx,日志会一直占据当前控制台。使用 -d (detached mode) 可以让容器在后台运行。
BASH
root@VM-0-15-ubuntu:~# docker run -d nginx
0bd9d13cf51b419ed53670c0b28cb122809ad1a5c71dc64ff56fbead68d90f61
注:以这种方式运行,显示的 CONTAINER ID 比较长;再运行 docker ps 发现显示的 ID 比较短(0bd9d13cf51b),这是将长 ID 截取了前面的一部分,不影响功能使用。
-p(端口映射)
每个 Docker 容器都运行在一个独立的虚拟环境中,网络与宿主机是隔离的。默认情况下,不能直接从宿主机访问到 Docker 的内部网络。
用法:
-p 宿主机端口:容器内端口原理:进行端口映射,将外部的请求转发到容器内部。
-e(环境变量)
启动容器时附带环境变量。例如使用 MongoDB 作为数据库时,一般需要设置初始化账号名和密码,就可以使用 -e 参数传递进去:
BASH
docker run -d \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=chirabx \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
mongo
--name(自定义容器名)
为该容器取一个自定义名字(注意:该名字在整个宿主机上必须唯一)。
BASH
docker run -d --name my_nginx nginx
- 好处:方便后续管理。比如删除容器时,无需去查难记的 ID,直接执行
docker rm -f my_nginx即可。
-it(交互式终端)
这是 Docker 中最常用的组合参数,由 -i 和 -t 合并而成。
作用:交互式地进入容器内部,并且可以使用虚拟终端。
-i (interactive):保持容器的标准输入(STDIN)处于打开状态,让你可以向容器输入命令。
-t (tty):分配一个伪终端(pseudo-TTY),为容器创建一个虚拟终端界面,提供命令提示符、支持颜色、退格/方向键等。
BASH
docker run -it --rm alpine
CONSOLE
/ # ls
bin dev etc home lib media mnt proc root run sbin srv sys tmp usr var
/ #
--restart(重启策略)
配置容器在退出或宿主机重启时的自动拉起策略。
BASH
docker run -d --restart always nginx # 任何情况下都自动重启
docker run -d --restart unless-stopped nginx # 除非被手动停止,否则总是尝试重启
4. 容器调试与运维
docker logs(查看日志)
查看容器内部应用的标准输出日志。
- -f (follow):追踪输出,可以持续滚动查看实时日志。
BASH
docker logs -f my_mongo
docker exec(执行命令)
在已经运行的容器内部执行 Linux 命令或进入其环境。
- 执行单条命令:
BASH
docker exec <容器ID或名字> ps -ef
- 进入容器内部调试(拿到容器内的 Shell 环境):
BASH
docker exec -it <容器ID或名字> /bin/sh
模块二:数据持久化(挂载卷)
为什么要这么做(核心思路): 容器本身是临时的“阅后即焚”环境。当我们删除容器时,其内部产生的所有数据(如数据库数据、网页静态文件)都会随之灰飞烟灭。挂载机制用于打破这种封闭,实现数据的持久化保存,并在宿主机和容器之间共享文件。
1. 绑定挂载 (Bind Mounts)
直接把宿主机的具体目录绑定到容器的目录。容器内对该文件夹的修改会直接影响宿主机,反之亦然。
- 语法:
-v 宿主机绝对路径:容器内绝对路径
BASH
docker run -d -p 80:80 -v /website/html:/usr/share/nginx/html nginx
2. 命名卷挂载 (Named Volumes)
让 Docker 自己在宿主机上划分并管理一块存储空间。我们只需为这块空间起个名字,挂载时直接引用名字即可,无需关心底层存放的物理路径。
- 操作前置(清理旧容器):
BASH
docker ps # 显示要删除的容器id
docker rm 容器id # 删除之前的容器
- 创建命名卷:
BASH
docker volume create nginx_html # nginx_html 是你取的卷名字
使用命名卷挂载运行:
语法:
-v 卷的名字:容器内目录
BASH
docker run -d -p 80:80 -v nginx_html:/usr/share/nginx/html nginx
3. 相关挂载卷管理命令
BASH
docker volume inspect nginx_html # 查询指定挂载卷的详细信息
docker volume list # 列出所有创建过的卷(同 docker volume ls)
docker volume rm nginx_html # 删除某个指定的卷
docker volume prune -a # 清理删除所有没有任何容器在使用的无用卷
模块三:Dockerfile 镜像构建
为什么要这么做(核心思路): 手动拉取一个纯净系统环境,再进入容器一步步安装 Python、依赖包并拷贝代码,既繁琐又容易遗漏步骤(难以复现)。Dockerfile 提供了“基础设施即代码”的能力,通过按规则写好的一条条指令集,让 Docker 自动批量构建出包含完整业务代码和环境的专属镜像。
Dockerfile 是一个纯文本格式的配置文件,用来定义镜像的基础环境、安装依赖、复制文件、设置启动命令等内容。
实战练习:构建 FastAPI 项目镜像
1. 准备工作
在指定的项目文件夹下创建以下三个文件,保持如下目录结构:
TEXT
项目目录/
├── Dockerfile # 构建镜像的脚本
├── main.py # Python 主程序代码
└── requirements.txt # 依赖包列表
main.py
PYTHON
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8080)
requirements.txt
TXT
fastapi
uvicorn
Dockerfile
DOCKERFILE
FROM python:3.13-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8080
CMD ["python3", "main.py"]
2. 构建镜像
在当前目录(包含 Dockerfile 的目录)运行构建命令,-t 用于指定新镜像的名称,最后的 . 代表当前上下文目录。
BASH
docker build -t docker_test .
3. 运行自定义镜像
BASH
docker run -d -p 8080:8080 docker_test
模块四:Docker 网络 (Network)
为什么要这么做(核心思路): 在实际业务架构中,不同的服务往往需要互相通信,同时又要与外部网络保持适当的隔离。合理配置 Docker 网络,可以实现让容器使用自定义内部域名互相访问,或者直接共享宿主机的高性能网络栈。
1. 网络模式分类
Bridge 模式(桥接模式 / 默认)
Docker 默认的网络模式。所有的容器都会连接到这个桥接网络中,并分配到一个内部的 IP 地址(一般是 172.17.x.x 开头)。在这个内部子网里,容器可以通过内部 IP 互相访问。
注意:容器网络和宿主机的网络默认是相互隔离的。
自定义子网:可以使用命令创建自定义网桥,让特定的容器加入。优势在于:借助于 Docker 内部的 DNS 机制,在自定义子网中的容器可以使用容器名称(而非会变化的 IP 地址)直接互相解析和访问。跨子网的容器则天然隔离,无法通信。
BASH
# 创建一个名叫 network1 的子网
docker network create network1
# 创建一个 nginx 容器,并指定加入 network1 子网
docker run -d --network network1 nginx
Host 模式(主机模式)
在此模式下,Docker 容器不再拥有独立的网络隔离,而是直接共享宿主机的网络栈和 IP 地址。
- 特点:无需再使用
-p参数进行端口映射。容器内的服务(比如配置了 80 端口)会直接运行在宿主机的对应端口上,通过宿主机的 IP 和端口就能直接访问。
BASH
docker run -d --network host nginx
None 模式
容器拥有独立的网络命名空间,但不进行任何网络配置(没有网卡、没有 IP)。即完全不联网的封闭容器。
2. 网络管理命令
- 创建网络:
BASH
docker network create network1
- 查看网络列表:
BASH
docker network list
输出示例:
CONSOLE
NETWORK ID NAME DRIVER SCOPE
552b8c3bfe0f bridge bridge local
72add3ec9295 host host local
a81d73d580b2 network1 bridge local
6fddf7eefde0 none null local
注:除了自己创建的网络外,bridge、host 和 none 是自带的三种基础网络模式,不可删除。
- 删除网络:
BASH
docker network rm network1
模块五:Docker Compose 多容器编排
为什么要这么做(核心思路): 一个完整的现代化系统通常由多个组件构成(如前端 UI + 后端接口 + 数据库)。把所有东西塞进一个“巨型容器”会导致耦合度过高、容错率低且无法单独对某一层做水平扩容。 最佳实践是将每个模块打包成独立容器。但这带来了管理难题:每次启动都需要执行十几条复杂的 docker run 命令配置挂载和网络。Docker Compose 通过 YAML 配置文件将所有容器的启动规则、相互依赖关系和网络结构“固化”下来,实现一键式的自动化编排与启停。
1. 编写配置文件
在启动目录下创建 docker-compose.yaml (或 compose.yaml) 文件,内容如下:
YAML
services:
my_mongodb:
image: mongo
environment:
MONGO_INITDB_ROOT_USERNAME: name
MONGO_INITDB_ROOT_PASSWORD: pass
volumes:
- /my/datadir:/data/db
my_mongodb_express:
image: mongo-express
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_SERVER: my_mongodb
ME_CONFIG_MONGODB_ADMINUSERNAME: name
ME_CONFIG_MONGODB_ADMINPASSWORD: pass
depends_on:
- my_mongodb
(注:在 ME_CONFIG_MONGODB_SERVER 中,Express 服务直接通过内部 DNS 使用了数据库的服务名 my_mongodb 进行连接,这就是 Compose 自动配置内部网络带来的便利。)
2. 常用操作命令
启动服务 (up)
创建并后台运行配置中的所有容器。如果容器已在运行,重复执行此命令不会有副作用。执行时会自动在当前目录寻找 YAML 文件。
BASH
docker compose up -d
如果你想指定特定名字的配置文件,可以加上 -f 参数:
BASH
docker compose -f test.yaml up -d
运行日志示例:
CONSOLE
PS E:\dbkuaizi\mongodb> docker compose up -d
[+] Running 3/3
✔ Network mongodb_default Created 0.0s
✔ Container mongodb-my_mongodb-1 Started 0.6s
✔ Container mongodb-my_mongodb_express-1 Started 0.7s
停止并删除环境 (down)
停止所有相关联的容器,并清理删除它们以及自动生成的桥接网络。
BASH
docker compose down
运行日志示例:
CONSOLE
PS E:\docker\mongodb> docker compose down
[+] Running 3/3
✔ Container mongodb-my_mongodb_express-1 Removed 0.3s
✔ Container mongodb-my_mongodb-1 Removed 0.3s
✔ Network mongodb_default Removed 0.4s
仅停止不删除 (stop)
仅仅停止容器的运行状态,但不销毁容器本身(数据与状态保留)。
BASH
docker compose stop
重新启动 (start)
启动之前已经被 stop 暂停运行的组合容器。
BASH
docker compose start
