👋 关于作者
你好,这里是一条泥憨鱼 | 专注于 后端开发、AI 前沿技术与计算机基础 。

🏠 个人主页:一条泥憨鱼
通过技术博客记录技术成长,分享学习心得与经验。期待与您共同交流!
第一部分:认识 Docker
1.1 Docker 是什么
Docker 是一个把「应用 + 运行环境」打包成标准单元,并在任何机器上以同样方式运行的容器工具。
你写了一个 Spring Boot 项目,本机能跑;发给同学,他启动报错——他装的是 JDK 8,你用的是 JDK 17;他 MySQL 是 5.7,你建表用了 8.0 的语法;他的 Redis 没设密码,你的配置文件里写了密码。于是你们花了一下午排查「环境问题」,而不是写代码。
Docker 的解决思路很直接:不要再让对方去装环境,而是把环境本身一起打包给你。
它把「JDK 17 + 你的 jar 包 + 启动命令 + 时区配置」打包成一个叫镜像的东西。同学只要装好 Docker,一条命令就能得到一个和你完全一致的环境。这就是常说的「一次构建,到处运行」。
1.2 为什么开发者需要 Docker
- 装软件不再污染本机:想试 MySQL 8.0,直接起个容器;试完删掉,本机干干净净,不用卸载、不用改注册表、不用清残留目录。
- 环境可复现:项目需要的 MySQL、Redis、Nacos、Kafka 版本全部写进配置文件,换台电脑照样一键拉起。
- 团队协作一致:不再出现「在我电脑上是好的」。
- 贴近真实工作:现在绝大多数公司的后端服务都是用 Docker 镜像部署的,镜像 + 编排是面试和实习的常见考点。
1.3 镜像、容器、仓库
这三个词是 Docker 的全部基础,用「类与对象」来类比最好记:
| Docker 概念 | 类比 | 说明 |
|---|---|---|
| 镜像(Image) | 类(Class) | 一个只读模板,包含文件系统、环境变量、启动命令。不能直接运行 |
| 容器(Container) | 对象(实例) | 镜像运行起来的实例。可以启动、停止、删除,彼此隔离 |
| 仓库(Registry) | Maven 中央仓库 | 存放和分发镜像的地方,默认是 Docker Hub |
| 标签(Tag) | 版本号 | 如 mysql:8.0、mysql:8.4。不写 tag 默认是 latest |
串起来:从仓库拉取镜像 → 用镜像创建容器 → 容器里跑着你的程序。
补充两个后面会反复出现的概念:
- Dockerfile:一份文本说明书,描述「如何构建一个镜像」。
- 数据卷(Volume):宿主机上的一块持久化存储,挂给容器用。容器删了,卷里的数据还在。
1.4 Docker 与虚拟机的区别
| 对比项 | 虚拟机(VM) | Docker 容器 |
|---|---|---|
| 隔离级别 | 硬件级,每个 VM 有完整操作系统 | 进程级,共享宿主机内核 |
| 启动速度 | 几十秒到几分钟 | 秒级甚至更快 |
| 资源占用 | 每个 VM 几 GB 内存 | 一个容器几十到几百 MB |
| 体积 | 镜像动辄几个 GB | 常见镜像几十到几百 MB |
| 典型用途 | 强隔离、多操作系统 | 应用打包、微服务部署 |
容器比虚拟机轻得多、快得多,所以适合开发环境和服务部署。
Windows 上的 Docker Desktop 实际是通过 WSL2 跑一个轻量 Linux 环境,所以你拉取的镜像绝大多数是 Linux 镜像。这属于正常现象,不用关心细节。
1.5 Docker 在 Java 后端开发中的常见用途
- 本地依赖服务:MySQL、Redis、RabbitMQ、Kafka、Nacos、MinIO 全部用容器起,一条命令切换版本。
- 打包部署自己的服务:把 Spring Boot 的 jar 打成镜像,推送到镜像仓库,服务器拉取即运行。
- 一键起整套环境:用 Docker Compose 把「应用 + 数据库 + 缓存」一次拉起,新同事入职十分钟就能跑通项目。
- CI/CD:流水线里自动构建镜像并发布。
第二部分:安装与第一次使用
2.1 安装 Docker
安装方式请以官方文档为准,下面只给结论和入口。
Windows
- 开启虚拟化:任务管理器 → 性能 → CPU,确认「虚拟化:已启用」。未启用需进 BIOS 开启。
- 安装 WSL2(Docker Desktop 依赖它),管理员 PowerShell 执行:
安装后重启电脑。wsl --install - 从官网下载 Docker Desktop 安装:https://docs.docker.com/desktop/setup/install/windows-install/
- 安装完成后启动 Docker Desktop,等待左下角状态变成 Engine running。
macOS
- 从 https://docs.docker.com/desktop/setup/install/mac-install/ 下载对应芯片版本(Apple Silicon 选 Apple chip,Intel 选 Intel chip),拖入「应用程序」后启动即可。
Linux(Ubuntu 为例)
按官方文档用 apt 源安装:https://docs.docker.com/engine/install/ubuntu/。安装后把当前用户加入 docker 组,避免每条命令都要 sudo:
sudo usermod -aG docker $USER
# 重新登录终端后生效
2.2 检查是否安装成功
docker version
docker info
docker version 能看到 Client 和 Server 两段信息,说明客户端和引擎都正常。如果只有 Client 没有 Server,通常是 Docker Desktop 没启动,或当前用户没有权限。
再跑一个官方示例验证整条链路:
docker run hello-world
出现 Hello from Docker! 说明拉取镜像、创建容器、运行容器全部正常。这个容器运行完就自动退出了,属于正常现象。
2.3 第一次完整操作:用 Nginx 走一遍流程
下面用 Nginx 演示「拉取 → 运行 → 查看 → 停止 → 启动 → 删除」的完整闭环。
# 1. 拉取镜像(不拉也行,docker run 会自动拉,但显式拉取更清楚)
docker pull nginx:1.27
# 2. 后台运行一个容器,名字叫 web-demo,把宿主机 8080 端口映射到容器 80 端口
docker run -d --name web-demo -p 8080:80 nginx:1.27
# 3. 查看运行中的容器
docker ps
# 4. 浏览器访问 http://localhost:8080 ,能看到 Welcome to nginx! 即成功
接着练习生命周期操作:
docker stop web-demo # 停止容器
docker ps # 此时列表里看不到它了
docker ps -a # 加 -a 才能看到已停止的容器
docker start web-demo # 重新启动
docker rm -f web-demo # 强制删除(会先停止再删除)
docker ps -a # 确认已删除
注意:本节用完请执行
docker rm -f web-demo,释放 8080 端口,后面运行 Spring Boot 还要用它。
第三部分:必须掌握的常用命令
3.1 先搞懂 docker run 的五个核心参数
docker run 是使用频率最高的命令,格式为 docker run [参数] 镜像名 [容器内执行的命令]。
| 参数 | 作用 | 例子 | 注意事项 |
|---|---|---|---|
-d | 后台运行(detach) | -d | 不加会占用当前终端,Ctrl+C 就退出容器 |
-p | 端口映射,格式 宿主机端口:容器端口 | -p 3306:3306 | 左边是你能访问的端口,右边是容器内程序监听的端口,顺序别写反 |
--name | 给容器起名字 | --name mysql-demo | 不写会随机生成。名字必须唯一,重复会报错 |
-e | 设置环境变量 | -e MYSQL_ROOT_PASSWORD=123456 | 不同镜像支持的变量不同,要查对应镜像文档 |
-v | 挂载数据卷或目录 | -v mysql-data:/var/lib/mysql | 冒号左边是宿主机侧,右边是容器内路径 |
再加两个常用参数:
--rm:容器停止后自动删除,适合临时跑一次的命令。--restart unless-stopped:异常退出或开机后自动重启,适合常驻服务。
3.2 命令详解
docker pull —— 拉取镜像
docker pull mysql:8.0
作用:从镜像仓库下载镜像到本地。注意:不写 tag 默认拉 latest,生产环境务必写明版本号,否则哪天 latest 变了行为会变。
docker images —— 查看本地镜像
docker images
作用:列出本地所有镜像,包含仓库名、标签、镜像 ID、大小、创建时间。注意:镜像 ID 是唯一的,删除时可以用 ID 的前几位。
docker run —— 创建并运行容器
docker run -d --name redis-demo -p 6379:6379 redis:7
作用:以镜像为模板创建一个新容器并启动。注意:每次执行都会创建一个新容器,不会复用同名容器;同名会报 Conflict,需要先删除旧容器或换个名字。
docker ps —— 查看运行中的容器
docker ps
作用:只显示正在运行的容器,包含容器 ID、镜像、状态、端口映射、名字。注意:这是排错第一步,先确认容器到底有没有在跑。
docker ps -a —— 查看所有容器
docker ps -a
作用:包括已停止、已退出的容器。注意:Exited (1) 表示异常退出,需要去看日志。
docker start —— 启动已存在的容器
docker start mysql-demo
作用:重新启动一个已停止的容器,保留原来的配置和数据。注意:start 只接受容器名或 ID,不能用来创建新容器。
docker stop —— 停止容器
docker stop mysql-demo
作用:向容器发送停止信号,容器内进程正常退出。注意:默认等待 10 秒,超时会强杀;想立刻停止可以用 docker kill。
docker rm —— 删除容器
docker rm mysql-demo
作用:删除已停止的容器。注意:运行中的容器删不掉,需要加 -f 强制删除。删除容器本身不会删除数据卷里的数据,但如果启动时没挂载卷,数据会一起消失。
docker rmi —— 删除镜像
docker rmi mysql:8.0
作用:删除本地镜像。注意:有容器(包括已停止的)正在使用该镜像时删不掉,需要先删除容器。加 -f 可以强制删除,但可能留下悬空镜像。
docker logs —— 查看容器日志
docker logs -f --tail 100 mysql-demo
作用:查看容器内程序的标准输出和错误输出,-f 持续跟踪,--tail 100 只看最后 100 行。注意:容器启动失败时,这是排查原因的第一现场。
docker exec -it —— 进入容器执行命令
docker exec -it mysql-demo bash
作用:在运行中的容器里开一个交互式终端,方便查看文件、连数据库。注意:-it 中 -i 保持输入、-t 分配终端,缺一不可;有些精简镜像没有 bash,可换成 sh。用 exit 退出,退出不会停止容器。
docker build —— 构建镜像
docker build -t demo-app:1.0 .
作用:根据当前目录下的 Dockerfile 构建镜像,-t 指定「仓库名:标签」。注意:最后那个 . 是构建上下文目录,不能省略,它决定 Docker 能读取哪些文件。
docker inspect —— 查看容器或镜像详情
docker inspect mysql-demo
作用:输出完整的 JSON 配置,包括 IP 地址、挂载信息、环境变量、启动命令。注意:常用 docker inspect -f '{{.NetworkSettings.IPAddress}}' mysql-demo 只取某个字段。
3.3 命令速查表
| 命令 | 作用 | 常用写法 |
|---|---|---|
docker pull | 拉取镜像 | docker pull mysql:8.0 |
docker images | 查看本地镜像 | docker images |
docker run | 创建并运行容器 | docker run -d --name x -p 宿:容 image:tag |
docker ps | 查看运行中的容器 | docker ps |
docker ps -a | 查看所有容器 | docker ps -a |
docker start | 启动已停止的容器 | docker start 容器名 |
docker stop | 停止容器 | docker stop 容器名 |
docker rm | 删除容器 | docker rm -f 容器名 |
docker rmi | 删除镜像 | docker rmi 镜像:标签 |
docker logs | 查看日志 | docker logs -f --tail 100 容器名 |
docker exec -it | 进入容器 | docker exec -it 容器名 bash |
docker build | 构建镜像 | docker build -t 名称:标签 . |
docker inspect | 查看详情 | docker inspect 容器名 |
第四部分:使用 Docker 运行 MySQL 和 Redis
这是日常开发中使用频率最高的场景。下面命令可以直接复制执行,前后连贯。
4.1 运行 MySQL
# 1. 拉取镜像(使用 8.0 版本,兼容性最好)
docker pull mysql:8.0
# 2. 创建并运行容器
docker run -d \
--name mysql-demo \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=demo_db \
-e TZ=Asia/Shanghai \
-v mysql-data:/var/lib/mysql \
--restart unless-stopped \
mysql:8.0
PowerShell 用户注意:PowerShell 的续行符是反引号
`,不是反斜杠\。上面这段在 PowerShell 里要么写成一行,要么把每行末尾的\换成反引号。
下面的命令同理,为通用性统一用\,实际执行时按你的终端替换。
逐段解释:
| 片段 | 含义 |
|---|---|
-p 3306:3306 | 把宿主机的 3306 端口映射到容器的 3306 端口。Navicat、IDEA 连 localhost:3306,实际连的是容器里的 MySQL |
-e MYSQL_ROOT_PASSWORD=123456 | 设置 root 密码,这是 MySQL 镜像的必填变量,不写容器会直接退出 |
-e MYSQL_DATABASE=demo_db | 首次启动时自动创建一个数据库 |
-e TZ=Asia/Shanghai | 设置时区,避免插入的时间差 8 小时 |
-v mysql-data:/var/lib/mysql | 把名为 mysql-data 的数据卷挂到 MySQL 的数据目录,数据持久化 |
--restart unless-stopped | 开机或异常退出后自动重启 |
验证服务是否正常
# 查看容器状态,STATUS 应为 Up
docker ps
# 查看启动日志,看到 "ready for connections" 即初始化完成
docker logs mysql-demo
# 在容器内执行 SQL 验证
docker exec -it mysql-demo mysql -uroot -p123456 -e "SELECT VERSION();"
也可以用本机客户端连接:主机 127.0.0.1,端口 3306,用户 root,密码 123456。
4.2 运行 Redis
docker pull redis:7
docker run -d \
--name redis-demo \
-p 6379:6379 \
-v redis-data:/data \
--restart unless-stopped \
redis:7 redis-server --appendonly yes
解释:
-p 6379:6379:本机客户端连localhost:6379。-v redis-data:/data:Redis 的数据目录是/data,挂卷后 RDB/AOF 文件持久化。redis-server --appendonly yes:镜像名后面的内容会作为容器内启动命令,这里开启 AOF 持久化,避免重启丢数据。
验证
docker ps
docker logs redis-demo
docker exec -it redis-demo redis-cli ping
# 返回 PONG 即正常
4.3 为什么数据库容器必须考虑持久化
容器的设计哲学是「用完即弃」:容器删除后,容器内写入的文件全部消失。MySQL 的数据默认写在容器内的 /var/lib/mysql,如果不挂卷,执行 docker rm mysql-demo 后,你建的库、表、数据会一起没掉。
数据卷就是解决这个问题的:数据实际落在宿主机上,容器只是「借用」这个目录。删容器、重建容器、换镜像版本,数据都还在。
4.4 停止、重启、删除
docker stop mysql-demo # 停止
docker start mysql-demo # 再次启动,数据仍在
docker restart mysql-demo # 重启
docker rm -f mysql-demo # 删除容器(数据卷仍在)
docker volume ls # 查看数据卷
docker volume rm mysql-data # 删除数据卷 —— 数据会真正丢失
数据卷对比:
docker rm 容器:只删容器,卷保留。docker volume rm 卷名:删除卷,数据不可恢复。- 如果你想彻底重来(比如密码忘了、初始化失败),执行
docker rm -f mysql-demo && docker volume rm mysql-data,再重新docker run,就会得到一个全新的库。
安全提醒:本文所有密码
123456仅用于本地学习。真实项目不要把密码硬编码进命令、配置文件或提交到 Git,应使用环境变量、密钥管理服务等方式管理。
说明:以上参数是为了「本地开发快速跑通」而给出的最小配置,不涉及主从、备份、资源限制、权限收敛等生产环境要考虑的内容。
第五部分:Dockerfile 与 Docker Compose 入门
5.1 Dockerfile 是什么
Dockerfile 是一份文本文件,逐行描述「如何从基础镜像一步步做出你的镜像」。三者关系是:
Dockerfile --(docker build)--> 镜像 --(docker run)--> 容器
常用指令
| 指令 | 作用 | 示例 |
|---|---|---|
FROM | 指定基础镜像,必须是第一条指令 | FROM eclipse-temurin:17-jre |
WORKDIR | 设置后续命令的工作目录,不存在会自动创建 | WORKDIR /app |
COPY | 把构建上下文中的文件复制进镜像 | COPY target/*.jar app.jar |
RUN | 构建镜像时执行命令,结果固化进镜像层 | RUN mkdir -p /app/logs |
EXPOSE | 声明容器监听的端口(仅作文档说明,不实际开放) | EXPOSE 8080 |
CMD | 容器启动时执行的默认命令,可被 docker run 后面的命令覆盖 | CMD ["java","-jar","app.jar"] |
两个容易混的点:
RUN在构建时执行,CMD在容器启动时执行。EXPOSE只是声明,真正的端口映射要靠docker run -p或 compose 的ports。
5.2 把 Spring Boot 项目打成镜像
前置条件:项目已用 Maven 打成可执行 jar。
mvn clean package -DskipTests
# 产物在 target/ 目录下,例如 target/demo-0.0.1-SNAPSHOT.jar
在项目根目录(与 pom.xml 同级)新建 Dockerfile:
# 1. 基础镜像:JDK 17 运行时(只含 JRE,体积比 JDK 小)
FROM eclipse-temurin:17-jre
# 2. 工作目录
WORKDIR /app
# 3. 复制构建产物(target 下只有一个可执行 jar,用通配符避免写死版本号)
COPY target/*.jar app.jar
# 4. 创建一个日志目录(演示 RUN 指令)
RUN mkdir -p /app/logs
# 5. 声明服务端口(仅声明,映射仍需 -p)
EXPOSE 8080
# 6. 容器启动命令
CMD ["java", "-jar", "app.jar"]
再新建 .dockerignore,避免把无用文件打进构建上下文(构建更快,也不会误把本地配置带进镜像):
target/*.original
.idea
.git
*.log
注意:
target目录不能被完全忽略,因为我们要复制里面的 jar。这里的写法只排除了.original文件。
构建并运行
docker build -t demo-app:1.0 .
docker run -d --name demo-app -p 8080:8080 demo-app:1.0
docker ps
docker logs -f demo-app
浏览器访问 http://localhost:8080 验证。
关键点:如果这个服务要连 MySQL,不能再用 localhost
容器里的 localhost 指的是容器自己,不是你的电脑。正确做法有两种:
- 连接宿主机上跑着的 MySQL:把配置里的地址改成
host.docker.internal(Docker Desktop 提供的宿主机别名)。 - 连接另一个 MySQL 容器:让两个容器在同一个网络里,用容器名当主机名(见 6.3 的 FAQ 和 Compose 部分)。
例如用环境变量覆盖 Spring Boot 配置:
docker run -d --name demo-app -p 8080:8080 \
-e SPRING_DATASOURCE_URL="jdbc:mysql://host.docker.internal:3306/demo_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true" \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=123456 \
demo-app:1.0
5.3 为什么需要 Docker Compose
上面每个服务都要写一长串 docker run,而且 MySQL 和 Redis 起来的顺序、网络、依赖关系都要手动维护。服务一多就管不过来。
Docker Compose 用一个 YAML 文件描述「一整套服务」,然后一条命令全部拉起。
和 Dockerfile 的区别:
| Dockerfile | Docker Compose | |
|---|---|---|
| 解决的问题 | 如何构建一个镜像 | 如何运行多个容器并组织它们 |
| 输入 | Dockerfile | compose.yaml |
| 典型输出 | 镜像 | 一组运行中的容器(网络、卷、依赖关系) |
两者是配合关系,不是替代关系:Compose 可以引用现成镜像(MySQL、Redis),也可以用 Dockerfile 构建自己的服务。
5.4 compose.yaml 示例:同时启动 MySQL 和 Redis
在项目根目录新建 compose.yaml:
services:
mysql:
image: mysql:8.0
container_name: mysql-demo
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: demo_db
TZ: Asia/Shanghai
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
restart: unless-stopped
redis:
image: redis:7
container_name: redis-demo
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes
restart: unless-stopped
volumes:
mysql-data:
redis-data:
对照前面的 docker run 命令看,字段是一一对应的:image 对应镜像名,ports 对应 -p,environment 对应 -e,volumes 对应 -v,command 对应镜像名后面那串启动命令。末尾的 volumes: 是在声明具名数据卷。
注意:如果之前已经用
docker run起过同名的mysql-demo、redis-demo,再执行docker compose up -d会报容器名冲突。先执行docker rm -f mysql-demo redis-demo即可(数据卷保留,数据不会丢)。
常用命令
docker compose up -d # 后台启动所有服务
docker compose ps # 查看本 compose 项目下的容器
docker compose logs -f # 查看所有服务日志(-f 持续跟踪)
docker compose logs mysql # 只看某个服务的日志
docker compose down # 停止并删除容器和网络(数据卷默认保留)
对比一下:
docker compose down默认不删数据卷,下次up -d数据还在。如果想连数据一起清掉,用docker compose down -v,这会删除 compose 中声明的具名卷,数据不可恢复。
Compose 文件在较新版本中推荐命名为
compose.yaml,且不再需要写version:字段。
5.5 用它搭本地开发环境
日常流程就三步:
# 1. 进入项目根目录
# 2. 一键拉起依赖服务
docker compose up -d
# 3. 在 IDEA 里直接启动 Spring Boot,连 localhost:3306 / localhost:6379
下班或换项目时:
docker compose down # 停服务,数据保留
这样本机不需要装 MySQL、Redis,每个项目各有一套独立的依赖环境。
第六部分:常见问题与快速复习
6.1 常见问题
Q1:容器启动失败,怎么查原因?
按顺序三步:
docker ps -a # 1. 看状态,Exited 后面的数字就是退出码
docker logs mysql-demo # 2. 看日志,异常信息通常在最后几行
docker inspect mysql-demo # 3. 看配置,确认环境变量、端口、挂载是否写对
最常见的原因:必填环境变量没写(如 MYSQL_ROOT_PASSWORD)、端口被占用、挂载路径写错、启动命令写错。
Q2:宿主机访问不了容器里的服务,检查什么?
依次检查:
docker ps确认容器是Up状态,不是Restarting或Exited。docker port 容器名确认端口映射生效,且宿主机端口没有被别的程序占用(Windows 可用netstat -ano | findstr :8080)。- 确认映射的是容器内程序实际监听的端口,比如 Spring Boot 配置的是 8081,就不能写
-p 8080:8080。 - 程序是否监听
0.0.0.0。如果只监听127.0.0.1,容器外访问不到。Spring Boot 默认是0.0.0.0,一般不用改。
Q3:为什么容器之间不能随意用 localhost 通信?
每个容器有自己独立的网络命名空间,容器里的 localhost 指向容器自己。所以 Spring Boot 容器里写 localhost:3306,它找的是自己内部的 3306,而不是 MySQL 容器。
正确做法:
- 同一 Compose 网络内,用服务名作主机名,例如
jdbc:mysql://mysql:3306/demo_db。 - 访问宿主机上的服务,用
host.docker.internal(Docker Desktop)。 - 实在要用容器 IP,可以用
docker inspect查,但 IP 会变,不推荐。
Q4:删除容器后数据为什么可能丢失?
容器的可写层随容器一起删除。启动时没有用 -v 把数据目录挂出来,数据就写在容器自己的文件系统里,删容器即删数据。
所以数据库类容器必须挂卷:
- MySQL:
-v mysql-data:/var/lib/mysql - Redis:
-v redis-data:/data - 通用做法:查镜像文档,确认它的数据目录在哪里。
Q5:改了 Java 代码,为什么必须重新构建?
镜像里的 jar 是构建那一刻拷进去的静态文件,代码改了不会自动同步。容器每次启动执行的是镜像里那份旧 jar。
正确流程:
mvn clean package -DskipTests
docker build -t demo-app:1.0 .
docker rm -f demo-app
docker run -d --name demo-app -p 8080:8080 demo-app:1.0
如果是用 Compose 且写了 build: .,可以简化为:
docker compose up -d --build
本地开发时,更推荐在 IDEA 里直接运行 Spring Boot(热部署、调试方便),只在需要验证镜像时才构建;容器主要用来跑 MySQL、Redis 这类依赖服务。
Q6:如何安全地清理不用的容器和镜像?
先看占用:
docker ps -a # 看有哪些已停止的容器
docker images # 看本地镜像
docker volume ls # 看数据卷
docker system df # 看磁盘占用汇总
逐个精确清理(推荐先做这一步):
docker stop 容器名
docker rm 容器名 # 只删已停止的容器
docker rmi 镜像:标签
高风险命令,务必看清楚再执行:
docker system prune:删除所有已停止的容器、未使用的网络、悬空镜像。数据卷默认会被保留,相对安全。docker system prune -a:额外删除所有未被容器使用的镜像。docker system prune -a --volumes:连数据卷一起删,运行中的容器数据也可能受影响,确认没有要保留的数据库再执行。拿不准的时候,先
docker system df -v看清楚是什么再删。
6.2 核心概念总结
| 概念 | 一句话理解 |
|---|---|
| 镜像 Image | 只读模板,相当于「类」 |
| 容器 Container | 镜像的运行实例,相当于「对象」 |
| 仓库 Registry | 存放镜像的地方,默认 Docker Hub |
| 标签 Tag | 镜像版本,如 mysql:8.0 |
| Dockerfile | 构建镜像的说明书 |
| 数据卷 Volume | 宿主机上的持久化存储,删容器不删数据 |
| 端口映射 | -p 宿主机端口:容器端口,把容器服务暴露到本机 |
| Compose | 用一个 YAML 管理多个容器 |
6.3 常用命令速查
| 场景 | 命令 |
|---|---|
| 拉镜像 | docker pull mysql:8.0 |
| 看镜像 | docker images |
| 跑容器 | docker run -d --name x -p 3306:3306 -e K=V image:tag |
| 看运行中容器 | docker ps |
| 看全部容器 | docker ps -a |
| 启动 / 停止 / 重启 | docker start x / docker stop x / docker restart x |
| 删容器 | docker rm -f x |
| 删镜像 | docker rmi image:tag |
| 看日志 | docker logs -f --tail 100 x |
| 进容器 | docker exec -it x bash |
| 构建镜像 | docker build -t app:1.0 . |
| 看详情 | docker inspect x |
| 清理 | docker system prune |
6.4 最小化实战任务
按顺序完成,全部跑通说明你已经能上手用了。
任务 1:用 Docker 启动 MySQL 和 Redis(不用 Compose)
docker pull mysql:8.0
docker pull redis:7
docker run -d --name mysql-demo -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=demo_db \
-e TZ=Asia/Shanghai -v mysql-data:/var/lib/mysql mysql:8.0
docker run -d --name redis-demo -p 6379:6379 \
-v redis-data:/data redis:7 redis-server --appendonly yes
docker ps
docker exec -it mysql-demo mysql -uroot -p123456 -e "SHOW DATABASES;"
docker exec -it redis-demo redis-cli ping
验收标准:两个容器都是 Up,MySQL 能看到 demo_db,Redis 返回 PONG。
任务 2:用 Dockerfile 运行 Spring Boot 项目
mvn clean package -DskipTests,确认target/下生成了可执行 jar。- 在项目根目录创建 5.2 节给出的
Dockerfile和.dockerignore。 - 构建并运行:
docker build -t demo-app:1.0 .
docker run -d --name demo-app -p 8080:8080 demo-app:1.0
docker logs -f demo-app
- 浏览器访问
http://localhost:8080,接口正常返回。 - 用环境变量
SPRING_DATASOURCE_URL把数据库地址指向host.docker.internal:3306,验证容器内应用能连上任务 1 的 MySQL。
任务 3(选做):把任务 1 改写成 compose.yaml
参照 5.4 节示例,把 MySQL、Redis 写进 compose.yaml,练习 up -d、ps、logs、down 四个命令。注意先删掉任务 1 手动创建的同名容器,再用 Compose 启动。之后每次开发只需要一条 docker compose up -d。
收尾
docker rm -f demo-app mysql-demo redis-demo
# 如果确认不需要数据了,再删卷
docker volume rm mysql-data redis-data
最后提醒:Docker 的命令不需要背,用三次就熟了。真正要建立的是两个习惯——容器出问题先看 docker ps -a 和 docker logs;涉及删除的命令,先确认数据卷里有没有你要的东西。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2503_94545876/article/details/169554634




