Docker 最新超详细版教程(通俗易懂)
本文档基于 Docker 最新稳定版(截至 2025/2026)编写,面向零基础学习者,力求"人话讲解 + 实战命令 + 常见坑"。 阅读建议:按章节顺序通读一遍,再结合第 9 章的实战项目动手敲一遍,基本就能上手。
目录
-
[Docker 是什么?为什么人人都在用?](#Docker 是什么?为什么人人都在用?)
-
[第一个容器:5 分钟跑起来](#第一个容器:5 分钟跑起来)
-
[数据持久化:Volume 与 Bind Mount](#数据持久化:Volume 与 Bind Mount)
-
[Docker Compose:一键编排多容器](#Docker Compose:一键编排多容器)
-
[实战项目:用 Compose 搭一套 Web+数据库](#实战项目:用 Compose 搭一套 Web+数据库)
-
[Docker vs Podman / Kubernetes 速览](#Docker vs Podman / Kubernetes 速览)
1. Docker 是什么?为什么人人都在用?
一句话定义
Docker 是一个把"应用 + 它运行所需的所有环境(系统库、依赖、配置)"打包成一个标准化盒子(容器)的工具。
为什么需要它?先看一个真实场景
小明在自己 Windows 电脑上写了一个 Python 网站,跑得好好的。 上传到服务器(Linux)后报错:
ModuleNotFoundError: No module named 'flask'。 装完 flask 又报glibc 版本太低,修完又报端口被占用......搞了一整天。
这就是经典的 "在我电脑上能跑啊!" 问题。根源是:开发环境和运行环境不一致。
Docker 的解决思路:
你的代码 + Python + flask + 系统库 → 打包成一个"容器镜像"
把这个镜像拷到任何一台装了 Docker 的机器上 → 一行命令直接跑,行为完全一致
Docker 的三大价值
| 价值 | 说明 |
|---|---|
| 环境一致 | 开发、测试、生产用同一个镜像,告别"我电脑能跑" |
| 轻量快速 | 容器共享宿主机内核,秒级启动,比虚拟机轻得多 |
| 隔离干净 | 每个容器互不干扰,删掉就干净,不污染系统 |
Docker 和虚拟机的区别(最经典的一张对比)
| 对比项 | 虚拟机 (VM) | Docker 容器 |
|---|---|---|
| 启动时间 | 几十秒~几分钟 | 秒级 |
| 资源占用 | 每个 GB 级 | 每个 MB 级 |
| 隔离方式 | 每个有完整操作系统 | 共享内核,进程级隔离 |
| 一台机能跑多少个 | 几个~十几个 | 几十~几百个 |
打个比方:虚拟机像"每户独立别墅,自带厨房水电"(重);Docker 像"酒店式公寓,共享水电但房间独立"(轻)。
2. 核心概念:镜像、容器、仓库(一句话懂)
Docker 整个体系就围绕三个词转:
📦 镜像(Image)------ 模板 / 蓝图
类比:面向对象里的"类",或做月饼的"模具"。
镜像是一个只读的模板,里面装着运行应用所需的所有东西(代码、运行时、库、配置)。它本身不能直接运行,是用来"造容器"的。
例如 nginx:latest 就是一个装好 Nginx 的镜像。
🏃 容器(Container)------ 镜像跑起来的实例
类比:面向对象里的"对象",或用模具压出来的"月饼"。
镜像 ——(docker run)——> 容器
类 ——(new) ——> 对象
一个镜像可以同时跑出多个容器(就像一个月饼模具能压出很多月饼)。
docker run nginx # 用 nginx 镜像启动一个容器
docker run nginx # 再启动一个,互不影响
🗄️ 仓库(Registry)------ 存放镜像的地方
类比:应用商店 / GitHub,不过存的是镜像。
最知名的是 Docker Hub(hub.docker.com),类似 npm 的 registry。你也可以搭私有仓库(Harbor 等)。
docker pull nginx # 从默认仓库(Docker Hub) 下载 nginx 镜像
docker push myrepo/app # 把自己造的镜像推上去
三者关系一张图
仓库 (Docker Hub) 本地 运行
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ nginx 镜像 │──pull──>│ 本地镜像列表 │──run────>│ 容器实例 │
│ mysql 镜像 │<─push──│ nginx/mysql │ │ (可多个) │
└───────────────┘ └───────────────┘ └───────────────┘
3. 安装与环境准备
3.1 Windows 安装
推荐使用 Docker Desktop(图形界面 + 命令行都有)。
-
前往官网下载:Docker Desktop: The #1 Containerization Tool for Developers | Docker
-
双击安装,一路下一步。
-
前提条件:Windows 10/11 64 位,并开启 WSL 2(Windows Subsystem for Linux)。
-
管理员 PowerShell 执行:
wsl --install -
重启电脑。
-
-
启动 Docker Desktop,等右下角鲸鱼图标变绿,即表示就绪。
3.2 macOS 安装
同样下载 Docker Desktop for Mac,按芯片选 Apple Silicon(M1/M2/M3)或 Intel 版本,拖进 Applications 即可。
3.3 Linux 安装(Ubuntu/Debian 示例)
推荐用官方一键脚本(最快):
# 1. 卸载旧版本
sudo apt remove docker docker-engine docker.io containerd runc
# 2. 用官方脚本安装最新版
curl -fsSL https://get.docker.com | sudo bash
# 3. 把当前用户加入 docker 组(免每次 sudo)
sudo usermod -aG docker $USER
# 重新登录生效
# 4. 验证
docker --version
docker run hello-world
3.4 配置国内镜像加速(强烈建议)
国内拉 Docker Hub 镜像很慢,必须配加速。编辑(或新建)/etc/docker/daemon.json(Linux)或 Docker Desktop → Settings → Docker Engine 里改:
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.com",
"https://docker.nju.edu.cn"
]
}
Linux 改完重启服务:
sudo systemctl restart docker
3.5 验证安装
docker version # 看版本
docker info # 看详细环境信息
docker run hello-world # 跑测试镜像,看到 "Hello from Docker!" 即成功
4. 第一个容器:5 分钟跑起来
启动一个 Nginx Web 服务器:
docker run -d -p 8080:80 --name myweb nginx
拆解这条命令(这是 Docker 最常用的格式,务必记住):
| 部分 | 含义 |
|---|---|
docker run |
用镜像创建并启动容器 |
-d |
detach,后台运行(不占终端) |
-p 8080:80 |
端口映射:宿主机 8080 → 容器内 80 |
--name myweb |
给容器起个名字(不写会随机生成) |
nginx |
用的镜像名(本地没有会自动去仓库拉) |
浏览器打开 http://localhost:8080 ,看到 Nginx 欢迎页 = 成功!
常用后续操作:
docker ps # 看正在运行的容器
docker ps -a # 看所有容器(包括已停止的)
docker stop myweb # 停止
docker start myweb # 再次启动
docker restart myweb # 重启
docker rm myweb # 删除(必须先 stop)
docker logs myweb # 看日志
docker logs -f myweb # 实时跟踪日志(类似 tail -f)
💡 记忆口诀:run 启动、ps 查看、stop/start/rm 控制、logs 看日志。掌握这五个词已经能玩转 80% 场景。
5. 镜像操作全攻略
# 搜索镜像
docker search nginx
# 拉取镜像(不加标签默认 :latest)
docker pull nginx
docker pull nginx:1.25-alpine # 指定版本(推荐,别总用 latest)
# 列出本地镜像
docker images
# 查看镜像详情(层结构、环境变量、暴露端口等)
docker inspect nginx
# 查看镜像历史(每层做了什么)
docker history nginx
# 删除镜像
docker rmi nginx # 删除前要确保没有容器在用它
docker rmi $(docker images -q) # 删除所有本地镜像(慎用)
# 给镜像打标签(重命名,常用于推送)
docker tag nginx:1.25 myrepo/nginx:v1
# 清理无用的镜像/容器/缓存(释放磁盘)
docker system prune -a
镜像标签的讲究
-
nginx:latest------ 最新版(不推荐生产用,因为每次 pull 可能变,导致行为不可复现) -
nginx:1.25------ 指定大版本 -
nginx:1.25-alpine------ 基于 Alpine Linux 的精简版(镜像小,约 1/5 大小) -
nginx@sha256:abc...------ 用 digest 锁定,绝对精确
⚠️ 生产环境铁律 :永远指定明确的版本号,禁用
latest。
6. 容器操作全攻略
# 创建并启动
docker run [选项] 镜像 [命令]
docker run -it ubuntu bash # 交互式进入容器(-i 保持输入 -t 分配终端)
# 进入正在运行的容器
docker exec -it myweb bash # 开一个新终端进去
docker attach myweb # 接入主进程(退出会停容器,慎用 Ctrl+P Ctrl+Q 退出)
# 容器与宿主机之间拷贝文件
docker cp 文件 myweb:/path # 宿主 → 容器
docker cp myweb:/path 文件 # 容器 → 宿主
# 查看容器资源占用(CPU/内存/网络)
docker stats
docker stats myweb
# 查看容器内部进程
docker top myweb
# 查看容器元数据
docker inspect myweb
# 停止 / 启动 / 重启 / 删除
docker stop myweb
docker start myweb
docker restart myweb
docker rm myweb # 删除容器
docker rm -f myweb # 强制删除(即使正在运行)
docker rm $(docker ps -aq) # 删除所有容器(慎用)
run 的常用选项速查
| 选项 | 作用 | 示例 |
|---|---|---|
-d |
后台运行 | docker run -d nginx |
-it |
交互模式 | docker run -it ubuntu bash |
--name |
命名 | --name myweb |
-p |
端口映射 | -p 8080:80 |
-P |
随机端口映射 | -P(大写) |
-v |
挂载目录/卷 | -v /host:/container |
-e |
环境变量 | -e MYSQL_ROOT_PASSWORD=123456 |
--network |
加入网络 | --network mynet |
--restart |
重启策略 | --restart=always |
--rm |
退出后自动删容器 | 适合一次性任务 |
-w |
工作目录 | -w /app |
--memory |
限制内存 | --memory=512m |
重启策略(生产必备)
--restart=no # 默认,不自动重启
--restart=always # 总是重启(包括宿主机重启后)
--restart=on-failure:3 # 异常退出时重启,最多 3 次
--restart=unless-stopped # 除非手动 stop,否则总是重启(推荐)
7. Dockerfile:自己造镜像
前面用的都是别人做好的镜像。真正的工作中,你需要把自己的应用打包成镜像,用的就是 Dockerfile。
7.1 Dockerfile 是什么
一个纯文本文件,里面写一行行指令,告诉 Docker "怎么一步步构建我的镜像"。
7.2 一个最简单的例子
项目结构:
myapp/
├── app.py
└── Dockerfile
app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello from Docker!'
app.run(host='0.0.0.0', port=5000)
Dockerfile:
# 1. 选一个基础镜像(必须)
FROM python:3.12-slim
# 2. 设置工作目录(容器内的路径)
WORKDIR /app
# 3. 把宿主机的代码复制到容器里
COPY app.py .
# 4. 安装依赖
RUN pip install flask --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple
# 5. 暴露端口(只是声明,真正映射还要 -p)
EXPOSE 5000
# 6. 容器启动时默认执行的命令
CMD ["python", "app.py"]
构建并运行:
docker build -t myapp:v1 . # 注意最后那个点,表示构建上下文=当前目录
docker run -d -p 5000:5000 myapp:v1
浏览器打开 http://localhost:5000 ,看到 "Hello from Docker!" 即成功。
7.3 常用指令详解
| 指令 | 作用 | 示例 |
|---|---|---|
FROM |
基础镜像(第一条非注释指令) | FROM node:20-alpine |
WORKDIR |
设置工作目录 | WORKDIR /app |
COPY |
复制宿主文件到镜像 | COPY . . |
ADD |
类似 COPY,支持自动解压 tar、URL(一般用 COPY 即可) | ADD app.tar.gz /opt |
RUN |
构建时执行命令(会形成新层) | RUN apt update && apt install -y curl |
CMD |
容器启动默认命令(可被 run 覆盖) | CMD ["python","app.py"] |
ENTRYPOINT |
容器启动固定命令(不易被覆盖) | ENTRYPOINT ["python"] |
ENV |
环境变量(构建+运行都生效) | ENV NODE_ENV=production |
ARG |
仅构建时变量 | ARG VERSION=1.0 |
EXPOSE |
声明端口 | EXPOSE 80 |
VOLUME |
声明匿名卷 | VOLUME /data |
USER |
切换运行用户(安全) | USER node |
HEALTHCHECK |
健康检查 | HEALTHCHECK CMD curl -f http://localhost/ || exit 1 |
7.4 CMD vs ENTRYPOINT(最容易混淆)
-
CMD :默认命令,
docker run后面加参数会完全替换它。 -
ENTRYPOINT :固定入口,
docker run后面的参数会作为追加参数传给它。
最佳实践:ENTRYPOINT 定程序 + CMD 定默认参数:
ENTRYPOINT ["python", "app.py"]
CMD ["--help"] # 默认参数,run 时可覆盖
7.5 多阶段构建(生产必备,镜像瘦身神器)
一个 Go 程序为例。传统做法镜像有几百 MB,多阶段后只有十几 MB:
# ====== 阶段 1:构建 ======
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o myapp -ldflags="-s -w" .
# ====== 阶段 2:运行 ======
FROM alpine:3.19
WORKDIR /app
COPY --from=builder /src/myapp .
EXPOSE 8080
CMD ["./myapp"]
原理:阶段 1 用完整 Go SDK 编译出二进制;阶段 2 只把这个二进制拷到极小的 alpine 里。最终镜像不含编译器和源码,又小又安全。
7.6 写 Dockerfile 的 7 条黄金法则
-
选小基础镜像 :
alpine、slim、distroless。 -
合并 RUN :多条命令用
&&连起来,减少镜像层数。 -
合理利用缓存:把"变化少"的步骤(装依赖)放前面,"变化多"的(拷代码)放后面。
-
用 .dockerignore:像 .gitignore 一样,排除不需要的文件(node_modules、.git 等),加快构建。
-
别用 root 跑 :加
USER切到非特权用户。 -
固定版本 :
FROM node:20.11-alpine而非node:latest。 -
能多阶段就多阶段:镜像越小越安全越快。
.dockerignore 示例:
node_modules
.git
*.log
.env
Dockerfile
8. 数据持久化:Volume 与 Bind Mount
8.1 为什么需要这个?
容器是"一次性"的------删掉容器,里面的数据就没了。
数据库、上传的文件、日志这些必须能持久化,所以要把数据放在容器外面。
8.2 三种方式对比
| 方式 | 说明 | 命令示例 | 适用场景 |
|---|---|---|---|
| Volume | Docker 管理的命名卷,存在 Docker 区域 | -v myvol:/data |
数据库、生产数据(推荐) |
| Bind Mount | 直接挂宿主机某个目录 | -v /home/me/data:/data |
开发时热更新代码 |
| tmpfs | 内存中,不落盘 | --tmpfs /cache |
临时敏感数据 |
8.3 Volume 用法
docker volume create myvol # 创建
docker volume ls # 列出
docker volume inspect myvol # 看详情(存储位置等)
docker volume rm myvol # 删除
# 跑一个 MySQL,数据存到卷里(删容器数据不丢)
docker run -d \
-e MYSQL_ROOT_PASSWORD=123456 \
-v mydbdata:/var/lib/mysql \
--name mysql mysql:8
8.4 Bind Mount 用法(开发神器)
# 把宿主机 ./code 挂到容器 /app,改代码容器里立即生效
docker run -d -p 5000:5000 -v $(pwd)/code:/app myapp:v1
⚠️ Windows 路径要用正斜杠或双反斜杠:
-v C:\Users\me\code:/app或在 Docker Desktop 设置里开启 C 盘共享。
8.5 只读挂载
docker run -v /host/conf:/etc/conf:ro nginx # ro = read only,容器内不能改
9. 网络:容器之间怎么通信
9.1 默认网络类型
| 类型 | 说明 |
|---|---|
| bridge | 默认。容器间通过 IP 互通,需 -p 才能被外部访问 |
| host | 容器直接用宿主机网络栈(性能好但隔离差) |
| none | 没有网络(完全隔离) |
| 自定义 bridge | 推荐做法,容器间可用名字互相访问 |
9.2 自定义网络(核心用法)
# 创建网络
docker network create mynet
# 启动容器并加入网络,并指定名字
docker run -d --name db --network mynet -e MYSQL_ROOT_PASSWORD=123456 mysql:8
docker run -d --name web --network mynet -p 8080:80 nginx
关键好处 :同一个自定义网络里,容器之间可以用名字直接访问!
web 容器里访问 db: mysql -h db -u root -p
(不是用 IP,而是用容器名 "db")
9.3 网络命令
docker network ls
docker network inspect mynet # 看网络里有谁
docker network connect mynet 容器 # 把已有容器加入网络
docker network disconnect mynet 容器
docker network rm mynet
10. Docker Compose:一键编排多容器
10.1 为什么需要 Compose?
一个真实项目常常是:Web + API + 数据库 + 缓存 + 反向代理,五六个容器,互相依赖、要组网络、要存数据。用 docker run 一条条敲又长又容易错。
Compose 让你用一个 YAML 文件描述所有容器,一行命令 up 全部启动,down 全部停止。
10.2 安装
新版 Docker Desktop 已内置 docker compose(注意是空格,不是 docker-compose 短横线)。Linux 用 apt install docker-compose-plugin。
10.3 一个最小例子
docker-compose.yml:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: "appdb"
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
操作命令:
docker compose up -d # 后台启动全部
docker compose ps # 查看状态
docker compose logs -f web # 看某个服务日志
docker compose stop # 停止(保留容器)
docker compose down # 停止并删除容器/网络
docker compose down -v # 连带删除卷(慎用,数据会丢!)
docker compose build # 重新构建镜像
docker compose up -d --build # 重建并启动(改了 Dockerfile 后用)
docker compose restart web # 重启单个服务
docker compose exec web sh # 进入容器
10.4 关键字段速查
| 字段 | 作用 |
|---|---|
image / build |
用现成镜像 / 用本地 Dockerfile 构建 |
ports |
端口映射 |
volumes |
挂载卷或目录 |
environment / env_file |
环境变量 / 从 .env 文件读 |
depends_on |
启动依赖顺序(不等待"就绪",只等启动) |
networks |
加入网络 |
restart |
重启策略 |
healthcheck |
健康检查 |
11. 实战项目:用 Compose 搭一套 Web+数据库
目标:用 Node.js 写一个 API,连 MySQL,全用 Docker 跑起来。
项目结构
demo/
├── docker-compose.yml
├── api/
│ ├── Dockerfile
│ ├── package.json
│ └── index.js
└── init.sql
api/package.json
{
"name": "demo-api",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"express": "^4.19.2",
"mysql2": "^3.9.0"
}
}
api/index.js
const express = require('express');
const mysql = require('mysql2/promise');
const app = express();
// 从环境变量读数据库连接信息(主机名直接用 compose 里的服务名 db)
const pool = mysql.createPool({
host: process.env.DB_HOST || 'db',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '123456',
database: process.env.DB_NAME || 'appdb',
});
app.get('/', async (req, res) => {
const [rows] = await pool.query('SELECT NOW() AS now');
res.json({ message: 'Hello from Docker API!', dbTime: rows[0].now });
});
app.listen(3000, () => console.log('API on :3000'));
api/Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package.json .
RUN npm install --registry=https://registry.npmmirror.com
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
init.sql(自动建表)
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
);
INSERT INTO users (name) VALUES ('docker');
docker-compose.yml
services:
api:
build: ./api
ports:
- "3000:3000"
environment:
DB_HOST: db
DB_USER: root
DB_PASSWORD: "123456"
DB_NAME: appdb
depends_on:
db:
condition: service_healthy
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: appdb
volumes:
- dbdata:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 10
volumes:
dbdata:
启动
docker compose up -d --build
docker compose ps
curl http://localhost:3000
看到返回带数据库时间的 JSON,全套就跑通了!
💡 注意
depends_on: condition: service_healthy------ 这能让 api 等 db 真正就绪(健康检查通过)才启动,避免一启动就连不上数据库的经典坑。
12. 镜像仓库与分发
12.1 Docker Hub(公共)
docker login # 输入 Docker Hub 账号密码
docker tag myapp:v1 yourname/myapp:v1
docker push yourname/myapp:v1
docker pull yourname/myapp:v1
docker logout
12.2 私有仓库 Harbor(企业常用)
# 假设 Harbor 地址 registry.company.com
docker login registry.company.com
docker tag myapp:v1 registry.company.com/project/myapp:v1
docker push registry.company.com/project/myapp:v1
12.3 本地临时仓库(测试用)
docker run -d -p 5000:5000 --name registry registry:2
docker tag myapp:v1 localhost:5000/myapp:v1
docker push localhost:5000/myapp:v1
13. 性能与优化技巧
-
镜像尽量小:用 alpine/slim/distroless + 多阶段构建。
-
合并 RUN 层 :
RUN apt update && apt install -y curl && rm -rf /var/lib/apt/lists/*。 -
善用构建缓存:依赖文件先 COPY 再安装,代码最后 COPY。
-
用 BuildKit :
DOCKER_BUILDKIT=1 docker build或新版默认开启,构建更快、日志更清晰。 -
限制资源 :
docker run --memory=512m --cpus=1,防止单容器吃光资源。 -
读时挂载 :配置文件加
:ro,减少误写。 -
定期清理 :
docker system prune -a --volumes清理无用资源(注意会删无用卷)。 -
看磁盘占用 :
docker system df。
14. 安全注意事项
-
不用 root 跑容器 :Dockerfile 里加
USER appuser。 -
不直接装最新 latest:固定版本 + digest。
-
扫描漏洞 :
docker scout quickview(官方)或 Trivy、Grype。 -
限制权限 :
docker run --read-only --cap-drop=ALL --security-opt=no-new-privileges。 -
别在镜像里塞密钥:用环境变量 / Docker Secrets / 外部密钥管理(Vault)。
-
用 distroless 基础镜像:连 shell 都没有,攻击面极小。
-
及时更新基础镜像:定期重建。
-
避免挂载 Docker Socket :挂了
/var/run/docker.sock等于把宿主机 root 给了容器。
15. 常见报错与排查
| 报错 | 原因 | 解决 |
|---|---|---|
Cannot connect to the Docker daemon |
Docker 服务没启动 | Windows 启动 Docker Desktop;Linux sudo systemctl start docker |
permission denied while trying to connect |
当前用户不在 docker 组 | sudo usermod -aG docker $USER 后重新登录 |
port is already allocated |
宿主机端口被占 | 换个端口,或 netstat -ano | findstr :8080 查占用 |
no space left on device |
磁盘满(镜像/容器太多) | docker system prune -a |
manifest not found |
镜像标签拼错或不存在 | 检查 docker search 和正确标签 |
image is being used by stopped container |
还有容器用着这个镜像 | 先 docker rm 容器再删镜像 |
| 容器秒退/立即停止 | 启动命令是前台进程退出 | 看日志 docker logs;常见是 CMD 写错或程序崩了 |
| 国内拉镜像超时 | 网络问题 | 配置镜像加速(见 3.4) |
bind address already in use |
端口冲突 | 同端口占用问题 |
| Windows 卷挂载看不到文件 | 路径未共享 | Docker Desktop → Settings → Resources → File Sharing 加上目录 |
万能排查三连
docker logs <容器> # 看日志
docker ps -a # 看容器状态(Exited 多半是启动失败)
docker inspect <容器> # 看详细配置
16. Docker vs Podman / Kubernetes 速览
| 工具 | 定位 | 一句话 |
|---|---|---|
| Docker | 容器引擎 + 工具链 | 单机部署王者,上手最简单 |
| Podman | Docker 替代品 | 无守护进程、无 root、命令兼容 alias docker=podman |
| Docker Compose | 单机多容器编排 | 一台机器上的多容器组合 |
| Docker Swarm | Docker 原生集群 | 多机,但已被 K8s 边缘化 |
| Kubernetes (K8s) | 容器编排平台 | 生产级、跨多机、自动扩缩容/自愈,学习曲线陡 |
学习路径建议:Docker → Compose → (按需)K8s。Docker 是后面所有东西的基础。
17. 速查命令表
# ===== 镜像 =====
docker images # 列出本地镜像
docker pull <镜像>:<tag> # 拉取
docker push <镜像> # 推送
docker rmi <镜像> # 删除
docker build -t <名字>:<tag> . # 构建
docker tag <旧> <新> # 打标签
docker save -o file.tar <镜像> # 导出
docker load -i file.tar # 导入
docker history <镜像> # 看层历史
# ===== 容器 =====
docker ps # 运行中
docker ps -a # 全部
docker run -d --name x -p 8080:80 <镜像> # 启动
docker start/stop/restart <容器> # 控制
docker rm <容器> # 删除
docker exec -it <容器> bash # 进入
docker cp <src> <容器>:<dst> # 拷贝
docker logs -f <容器> # 日志
docker stats # 资源占用
docker inspect <容器> # 详情
# ===== 数据 =====
docker volume create/ls/rm <卷>
docker run -v <卷>:/path <镜像>
# ===== 网络 =====
docker network create/ls/rm <网络>
docker run --network <网络> <镜像>
# ===== 系统 =====
docker system df # 磁盘占用
docker system prune -a # 清理
docker info # 环境信息
# ===== Compose =====
docker compose up -d # 启动
docker compose down # 停止删除
docker compose logs -f # 日志
docker compose ps # 状态
docker compose build # 构建
结语
Docker 的核心其实就三件事:用 Dockerfile 造镜像、用 run/compose 跑容器、用 volume/network 连数据和容器。
掌握本文内容后,你已经具备:
-
✅ 理解镜像/容器/仓库的本质
-
✅ 独立安装与配置 Docker 环境
-
✅ 熟练操作镜像与容器
-
✅ 编写规范的 Dockerfile(含多阶段构建)
-
✅ 管理数据持久化与容器网络
-
✅ 用 Compose 编排多容器项目
-
✅ 排查常见问题
下一步建议:
-
把第 11 章的实战项目亲手敲一遍(不要复制粘贴)。
-
尝试把你自己的一个项目容器化。
-
了解 CI/CD 中如何用 Docker 构建并推送镜像。
-
进阶学习 Kubernetes(当你需要跨多机部署时)。
容器化的世界很大,但入口很小------从
docker run hello-world开始,你已经上路了。🚀