前言:本文梳理了 Docker 的核心知识点与常用命令,涵盖镜像管理、容器操作、数据卷、网络配置、Dockerfile 编写及 Compose 编排。适合快速查阅和日常备忘,希望能帮你提升容器化开发效率。
文章目录
- [一、Docker 解决了什么问题?](#一、Docker 解决了什么问题?)
- 二、镜像管理(images)
- 三、容器管理(container)
- [四、数据卷(docker volume)](#四、数据卷(docker volume))
- [五、容器网络(docker network)](#五、容器网络(docker network))
- 六、镜像制作(Dockerfile)
- [七、容器编排(docker compose)](#七、容器编排(docker compose))
一、Docker 解决了什么问题?
| 问题 | Docker 的解决方式 |
|---|---|
| 环境不一致 | 将应用及其依赖打包成镜像,保证在任何机器上行为一致 |
| 可移植性差 | 镜像可跨平台运行,一次构建,到处运行 |
| 资源隔离 | 容器间相互隔离,沙箱运行,互不干扰 |
| 部署效率低 | 秒级启动,自动化部署流程更简洁 |
Docker VS 虚拟机
| 对比项 | 虚拟机 | Docker 容器 |
|---|---|---|
| 隔离级别 | 模拟完整硬件,有独立 OS,隔离度强 | 共享宿主机内核,隔离度相对弱 |
| 资源占用 | 重,启动慢(分钟级) | 轻,启动快(秒级) |
| 可移植性 | 镜像体积大 | 镜像体积小,分发方便 |
| 适用场景 | 需要强隔离或不同 OS | 微服务、快速部署、CI/CD |
二、镜像管理(images)
常用指令
bash
# 拉取镜像
docker pull 镜像名[:标签]
# 查看本地镜像
docker images
# 删除指定镜像(-f 强制删除)
docker rmi [-f] 镜像名或id
# 删除所有未被使用的镜像
docker image prune
离线迁移(无网络环境)
bash
# 1. 导出镜像为文件
docker save -o 文件名.tar 镜像名
# 2. 传输到目标机器(普通文件拷贝)
scp 文件名.tar root@目标ip:目录
# 3. 在目标机器导入镜像
docker load -i 文件名.tar
打标签
bash
# 类比 cp 指令,给镜像打一个新标签(原镜像保留)
docker tag 原镜像名[:标签] 新镜像名[:标签]
三、容器管理(container)
运行容器
bash
docker run [选项] 镜像名 [命令]
常用选项:
| 选项 | 说明 |
|---|---|
-p 宿主机端口:容器端口 |
端口映射,将容器端口暴露给外部 |
-d |
后台(守护进程)模式运行 |
--name 名字 |
指定容器名称 |
-e KEY=VALUE |
设置环境变量 |
--rm |
容器停止后自动删除 |
-v 卷名或路径:容器目录 |
挂载数据卷(详见数据卷章节) |
--network 网络名 |
指定网络模式 |
停止与删除
bash
docker stop 容器名或id # 优雅停止容器
docker kill 容器名或id # 强制终止容器
docker rm 容器名或id # 删除容器(需先停止)
docker rm -f 容器名或id # 强制删除运行中的容器
查看容器
bash
docker ps # 查看正在运行的容器
docker ps -a # 查看所有容器(含已停止)
docker logs 容器名或id # 查看容器日志
docker logs -f 容器名或id # 实时追踪日志输出
docker inspect 容器名或id # 查看容器详细信息
进入运行中的容器
bash
docker exec -it 容器名或id /bin/bash
# 退出容器但不停止:Ctrl+P,Ctrl+Q
# 退出并停止:exit
四、数据卷(docker volume)
为什么需要数据卷?
- 数据持久化:容器默认是临时的,删除后数据随之消失。
- 宿主机 ↔ 容器:方便在两者之间共享文件。
- 容器 ↔ 容器:多个容器挂载同一个卷即可实现数据共享。
三种数据卷类型
1. 管理卷(Managed Volume)
由 Docker 统一创建和管理,存储在 Docker 内部目录(如 /var/lib/docker/volumes/),可移植性强,推荐优先使用。
bash
docker volume create 卷名 # 创建卷
docker volume ls # 列出所有卷
docker volume inspect 卷名 # 查看卷详情
docker volume rm 卷名 # 删除指定卷
docker volume prune # 删除所有未使用的卷
# 挂载到容器
docker run [...] -v 卷名:容器目录 镜像名
2. 绑定卷(Bind Mount)
将宿主机上的具体目录或文件直接挂载到容器,由用户自己管理路径,没有 docker volume 系列指令。
bash
# 挂载到容器(卷名替换为宿主机的绝对路径)
docker run [...] -v /宿主机/路径:容器目录 镜像名
# 只读挂载(容器内只能读取,不能修改)
docker run [...] -v /宿主机/路径:容器目录:ro 镜像名
注意 :挂载时容器对应目录会被宿主机目录的内容覆盖同步 。
:ro是对容器的限制,容器内只读,宿主机仍可正常修改文件。
3. 临时卷(tmpfs Mount)
数据存储在宿主机内存 中,容器停止后数据随之消失。适合存放敏感信息或高频读写的临时数据,没有 docker volume 系列指令。
bash
docker run [...] --tmpfs 容器目录 镜像名
五、容器网络(docker network)
为什么需要网络?
- 容器与容器之间通信(如 Web 服务访问数据库)
- 容器与外部网络通信
- 容器与宿主机交互
四种常见网络模式
| 模式 | 说明 |
|---|---|
| Bridge(桥接) | 默认模式。Docker 创建虚拟网桥,容器通过它与外部通信,容器间可通过容器名互相访问(同一自定义网络下) |
| Host(宿主机网络) | 容器直接使用宿主机的网络栈,无网络隔离,性能最好,但端口冲突风险高 |
| Container(容器网络) | 与指定的另一个容器共享网络命名空间,两者共用同一个 IP |
| None(无网络) | 容器没有任何网络接口,完全隔离,适合纯计算任务 |
网络管理指令
bash
docker network create 网络名 # 创建自定义网络
docker network ls # 列出所有网络
docker network inspect 网络名 # 查看网络详情
docker network rm 网络名 # 删除指定网络
docker network prune # 删除所有未使用的网络
docker network connect 网络名 容器名 # 将容器加入网络
docker network disconnect 网络名 容器名 # 将容器从网络移除
指定网络模式
bash
# 默认:Bridge 模式,无需额外参数
docker run [...] 镜像名
# Host 模式
docker run --network host 镜像名
# Container 模式(共享容器 A 的网络,A 断网则本容器也断网)
docker run --network container:容器A的名字 镜像名
# None 模式
docker run --network none 镜像名
六、镜像制作(Dockerfile)
方式一:容器快照(不推荐用于生产)
bash
docker commit [选项] 容器id 镜像名[:标签]
将运行中容器的当前状态保存为镜像。缺点是不可复现、历史不透明。
方式二:Dockerfile(推荐)
通过脚本描述镜像的构建过程,可版本控制、可复现。
常用指令
| 指令 | 说明 |
|---|---|
FROM 基础镜像 |
指定基础镜像,必须放在第一行 |
COPY 宿主机文件 镜像目录 |
将文件从构建上下文复制到镜像 |
ADD 宿主机文件或URL 镜像目录 |
COPY 的增强版:本地 .tar 压缩包会自动解压;支持通过 URL 拉取文件(URL 不会自动解压) |
ENV KEY=VALUE |
设置环境变量,可在后续指令中用 ${KEY} 引用 |
ARG 变量名[=默认值] |
构建时变量,仅在构建阶段有效,不会保留到镜像中 |
WORKDIR 目录 |
设置工作目录,后续 RUN/COPY/CMD 等均在此目录下执行 |
RUN 命令 |
构建时 执行命令(如安装依赖)。每条 RUN 会新增一层,建议用 && 合并减少层数 |
CMD 命令 |
容器启动时 执行的默认命令。可被 docker run 末尾传入的命令覆盖 |
ENTRYPOINT 命令 |
容器启动时 执行的入口点。不会被 docker run 末尾的命令覆盖,而是将其作为参数传入 |
EXPOSE 端口 |
声明容器监听的端口(文档用途,需配合 -p 才实际映射) |
VOLUME 容器目录 |
声明匿名数据卷挂载点 |
USER 用户名 |
指定后续指令和容器运行时的用户 |
HEALTHCHECK |
定义容器健康检查命令 |
CMD vs ENTRYPOINT
dockerfile
# 只用 CMD:启动命令可被覆盖
CMD ["python", "app.py"]
# docker run 镜像名 bash → 执行 bash,app.py 不会启动
# 只用 ENTRYPOINT:入口固定,docker run 后的参数追加进来
ENTRYPOINT ["python", "app.py"]
# docker run 镜像名 --port=8080 → 执行 python app.py --port=8080
# 两者结合(推荐):ENTRYPOINT 定义固定入口,CMD 提供默认参数
ENTRYPOINT ["python", "app.py"]
CMD ["--port=80"]
# docker run 镜像名 → python app.py --port=80(使用 CMD 默认值)
# docker run 镜像名 --port=8080 → python app.py --port=8080(CMD 被覆盖)
多阶段构建(Multi-stage Build)
为什么需要? 编译型语言(如 Go、Java)在构建时需要完整的编译环境,但运行时只需要编译产物。若把编译工具也打包进最终镜像,会导致镜像体积庞大。
优势:最终镜像只包含运行时所需文件,体积大幅缩减,安全面也更小。
dockerfile
# 阶段一:构建(使用完整编译环境)
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .
# 阶段二:运行(使用最小基础镜像)
FROM alpine:latest
WORKDIR /app
# 只从构建阶段复制编译产物
COPY --from=builder /app/myapp .
CMD ["./myapp"]
构建镜像
bash
docker build [选项] 构建上下文路径
# 常用选项:
# -t 镜像名:标签 指定镜像名和标签
# -f Dockerfile路径 指定 Dockerfile 文件(默认找当前目录的 Dockerfile)
# --no-cache 不使用缓存,强制重新构建
# 示例
docker build -t myapp:1.0 .
docker build -f ./docker/Dockerfile -t myapp:1.0 .
七、容器编排(docker compose)
为什么需要编排?
实际应用往往由多个服务组成(如 Web 服务 + 数据库 + 缓存),手动逐一 docker run 不仅繁琐,还难以管理服务间的依赖关系和网络配置。Docker Compose 通过一个 YAML 文件统一描述和管理多容器应用。
解决的问题:
- 一条命令启动 / 停止整个应用栈
- 自动处理服务间的网络与依赖顺序
- 配置即代码,便于版本控制和团队协作
配置文件 docker-compose.yml
yaml
version: "3.9" # 指定 Compose 文件格式版本
services: # 定义各个服务
web: # 服务名(可自定义)
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db # 声明依赖,db 先于 web 启动
networks:
- app-net
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: mydb
volumes:
- db-data:/var/lib/mysql
networks:
- app-net
volumes: # 声明管理卷
db-data:
networks: # 声明自定义网络
app-net:
driver: bridge
常用指令
bash
docker compose config # 校验并查看合并后的配置
docker compose up # 创建并启动所有服务(前台)
docker compose up -d # 后台启动
docker compose up --build # 启动前重新构建镜像
docker compose down # 停止并删除容器、网络(数据卷默认保留)
docker compose down -v # 同时删除数据卷
docker compose ps # 查看服务状态
docker compose logs -f # 实时查看所有服务日志
docker compose logs -f 服务名 # 查看指定服务日志
docker compose exec 服务名 bash # 进入指定服务的容器
docker compose restart 服务名 # 重启指定服务
docker compose pull # 拉取所有服务的最新镜像
非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!🎉
