Docker核心知识点和常用指令(命令)速通
作者:敲上瘾
前言:
本文梳理了 Docker 的核心知识点与常用命令,涵盖镜像管理、容器操作、数据卷、网络配置、Dockerfile 编写及 Compose 编排。适合快速查阅和日常备忘,希望能帮你提升容器化开发效率。
一、Docker 解决了什么问题?
| 问题 | Docker 的解决方式 |
|---|---|
| 环境不一致 | 将应用及其依赖打包成镜像,保证在任何机器上行为一致 |
| 可移植性差 | 镜像可跨平台运行,一次构建,到处运行 |
| 资源隔离 | 容器间相互隔离,沙箱运行,互不干扰 |
| 部署效率低 | 秒级启动,自动化部署流程更简洁 |
Docker VS 虚拟机
| 对比项 | 虚拟机 | Docker 容器 |
|---|---|---|
| 隔离级别 | 模拟完整硬件,有独立 OS,隔离度强 | 共享宿主机内核,隔离度相对弱 |
| 资源占用 | 重,启动慢(分钟级) | 轻,启动快(秒级) |
| 可移植性 | 镜像体积大 | 镜像体积小,分发方便 |
| 适用场景 | 需要强隔离或不同 OS | 微服务、快速部署、CI/CD |
二、镜像管理(images)
常用指令
# 拉取镜像 docker pull 镜像名[:标签] # 查看本地镜像 docker images # 删除指定镜像(-f 强制删除) docker rmi [-f] 镜像名或id # 删除所有未被使用的镜像 docker image prune
离线迁移(无网络环境)
# 1. 导出镜像为文件 docker save -o 文件名.tar 镜像名 # 2. 传输到目标机器(普通文件拷贝) scp 文件名.tar root@目标ip:目录 # 3. 在目标机器导入镜像 docker load -i 文件名.tar
打标签
# 类比 cp 指令,给镜像打一个新标签(原镜像保留) docker tag 原镜像名[:标签] 新镜像名[:标签]
三、容器管理(container)
运行容器
docker run [选项] 镜像名 [命令]
常用选项:
| 选项 | 说明 |
|---|---|
-p 宿主机端口:容器端口 | 端口映射,将容器端口暴露给外部 |
-d | 后台(守护进程)模式运行 |
--name 名字 | 指定容器名称 |
-e KEY=VALUE | 设置环境变量 |
--rm | 容器停止后自动删除 |
-v 卷名或路径:容器目录 | 挂载数据卷(详见数据卷章节) |
--network 网络名 | 指定网络模式 |
停止与删除
docker stop 容器名或id # 优雅停止容器 docker kill 容器名或id # 强制终止容器 docker rm 容器名或id # 删除容器(需先停止) docker rm -f 容器名或id # 强制删除运行中的容器
查看容器
docker ps # 查看正在运行的容器 docker ps -a # 查看所有容器(含已停止) docker logs 容器名或id # 查看容器日志 docker logs -f 容器名或id # 实时追踪日志输出 docker inspect 容器名或id # 查看容器详细信息
进入运行中的容器
docker exec -it 容器名或id /bin/bash # 退出容器但不停止:Ctrl+P,Ctrl+Q # 退出并停止:exit
四、数据卷(docker volume)
为什么需要数据卷?
- 数据持久化:容器默认是临时的,删除后数据随之消失。
- 宿主机 ↔ 容器:方便在两者之间共享文件。
- 容器 ↔ 容器:多个容器挂载同一个卷即可实现数据共享。
三种数据卷类型
1. 管理卷(Managed Volume)
由 Docker 统一创建和管理,存储在 Docker 内部目录(如 /var/lib/docker/volumes/),可移植性强,推荐优先使用。
docker volume create 卷名 # 创建卷 docker volume ls # 列出所有卷 docker volume inspect 卷名 # 查看卷详情 docker volume rm 卷名 # 删除指定卷 docker volume prune # 删除所有未使用的卷 # 挂载到容器 docker run [...] -v 卷名:容器目录 镜像名
2. 绑定卷(Bind Mount)
将宿主机上的具体目录或文件直接挂载到容器,由用户自己管理路径,没有 docker volume 系列指令。
# 挂载到容器(卷名替换为宿主机的绝对路径) docker run [...] -v /宿主机/路径:容器目录 镜像名 # 只读挂载(容器内只能读取,不能修改) docker run [...] -v /宿主机/路径:容器目录:ro 镜像名
注意:挂载时容器对应目录会被宿主机目录的内容覆盖同步。
:ro是对容器的限制,容器内只读,宿主机仍可正常修改文件。
3. 临时卷(tmpfs Mount)
数据存储在宿主机内存中,容器停止后数据随之消失。适合存放敏感信息或高频读写的临时数据,没有 docker volume 系列指令。
docker run [...] --tmpfs 容器目录 镜像名
五、容器网络(docker network)
为什么需要网络?
- 容器与容器之间通信(如 Web 服务访问数据库)
- 容器与外部网络通信
- 容器与宿主机交互
四种常见网络模式
| 模式 | 说明 |
|---|---|
| Bridge(桥接) | 默认模式。Docker 创建虚拟网桥,容器通过它与外部通信,容器间可通过容器名互相访问(同一自定义网络下) |
| Host(宿主机网络) | 容器直接使用宿主机的网络栈,无网络隔离,性能最好,但端口冲突风险高 |
| Container(容器网络) | 与指定的另一个容器共享网络命名空间,两者共用同一个 IP |
| None(无网络) | 容器没有任何网络接口,完全隔离,适合纯计算任务 |
网络管理指令
docker network create 网络名 # 创建自定义网络 docker network ls # 列出所有网络 docker network inspect 网络名 # 查看网络详情 docker network rm 网络名 # 删除指定网络 docker network prune # 删除所有未使用的网络 docker network connect 网络名 容器名 # 将容器加入网络 docker network disconnect 网络名 容器名 # 将容器从网络移除
指定网络模式
# 默认:Bridge 模式,无需额外参数 docker run [...] 镜像名 # Host 模式 docker run --network host 镜像名 # Container 模式(共享容器 A 的网络,A 断网则本容器也断网) docker run --network container:容器A的名字 镜像名 # None 模式 docker run --network none 镜像名
六、镜像制作(Dockerfile)
方式一:容器快照(不推荐用于生产)
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
# 只用 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)在构建时需要完整的编译环境,但运行时只需要编译产物。若把编译工具也打包进最终镜像,会导致镜像体积庞大。
优势:最终镜像只包含运行时所需文件,体积大幅缩减,安全面也更小。
# 阶段一:构建(使用完整编译环境) 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"]
构建镜像
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
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
常用指令
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 # 拉取所有服务的最新镜像
附:常见使用场景示例
运行一个 Nginx 容器,映射端口 80,挂载本地 html 目录
docker run -d --name web \ -p 8080:80 \ -v /my/html:/usr/share/nginx/html \ nginx
通过 Dockerfile 构建并运行一个 Python 应用
FROM python:3.11-slim WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD ["python", "app.py"]
docker build -t myapp . docker run -d --name app -p 5000:5000 myapp
创建自定义网络,让两个容器通信
docker network create app-net docker run -d --name redis --network app-net redis docker run -d --name web --network app-net -p 80:80 mywebapp
总结
到此这篇关于Docker核心知识点和常用指令的文章就介绍到这了,更多相关Docker核心知识点内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
