Docker开发笔记(详解)

Docker 是什么?

Docker 是一个工具,能把你的程序和它需要的环境(比如 JDK、配置、依赖)打包成一个"集装箱"(叫容器),在任何装了 Docker 的电脑上都能直接运行,不用再配环境。

✅ 解决问题:

"在我电脑能跑,你电脑跑不了" → 一次打包,到处运行!


核心名词

名词 是什么 一句话理解
镜像(Image) 程序的"安装包" 只读模板,不能运行,但可以用来启动容器(如 mysqlnginx
容器(Container) 正在运行的程序 镜像启动后的实例,能运行、能停止、能删除
Dockerfile 打包说明书 一个文本文件,告诉 Docker 怎么把你的代码做成镜像
卷(Volume) 持久化存储 容器删了数据也不丢(比如数据库文件存这里)
网络(Network) 容器之间的"对讲机" 同一网络下的容器可以用名字 互相访问(如 mysqlredis

问题 1:Dockerfile 是用来构建项目运行的 JDK 环境是吧?

答:不完全是。

  • Dockerfile 不是专门用来装 JDK 的 ,而是基于已有的 JDK 镜像(如 eclipse-temurin:17-jre-alpine ,把你的 Spring Boot JAR 包打包进去,形成一个完整的可运行应用镜像
  • JDK 环境由 FROM 指令直接复用官方镜像,你无需手动安装。
  • 所以:Dockerfile = 官方 JDK + 你的代码 + 启动命令

问题 2:COPY u2vd_cloud.jar app.jar 为什么有两个 jar?Spring Cloud 项目也这样部署吗?

答:

  • 这行命令的意思是:把虚拟机当前目录下的 u2vd_cloud.jar 复制到容器里,并改名为 app.jar
    • 左边是源文件名(你上传的 JAR)
    • 右边是容器内的目标文件名 (可自定义,通常简化为 app.jar
  • Spring Cloud 项目完全一样部署
    • 每个微服务(user-service、order-service 等)各自打成一个 JAR
    • 每个服务单独写自己的 Dockerfile
    • 各自构建镜像、各自运行容器
    • 通过 --network 加入同一网络,用服务名互相调用

核心原则:一个 JAR → 一个容器


问题 3:我的环境是本地开发 + 虚拟机跑 Docker,用 MobaXterm 连接,操作流程是什么?

答:四步极简流程:

  1. 本地打包 :IDEA 执行 Maven package,得到 xxx.jar

  2. 上传 JAR :用 MobaXterm 左侧 SFTP 面板,把 JAR 拖到虚拟机目录(如 /root/app/

  3. 写 Dockerfile :在虚拟机同目录下创建 Dockerfile,内容包含:dockerfile

    复制代码
       FROM eclipse-temurin:17-jre-alpine
       WORKDIR /app
       COPY 你的真实文件名.jar app.jar
       EXPOSE 8080
       ENTRYPOINT ["java", "-jar", "app.jar"]
  4. 构建并运行

    复制代码
       FROM eclipse-temurin:17-jre-alpine
       WORKDIR /app
       COPY 你的真实文件名.jar app.jar
       EXPOSE 8080
       ENTRYPOINT ["java", "-jar", "app.jar"]

    ⚠️ 关键提醒 :Docker 只能访问虚拟机上的文件,必须先上传 JAR 到虚拟机

高频命令速查表

场景 命令 说明
镜像 docker images 列出本地镜像
docker build -t myapp . 用当前目录 Dockerfile 构建
docker rmi 镜像名 删除镜像
容器 docker ps 运行中的容器
docker ps -a 所有容器(含停止的)
docker run -d --name xx 镜像 后台启动新容器
docker start/stop/restart xx 管理已有容器
docker logs -f xx 实时看日志(调试神器)
docker exec -it xx bash 进入容器调试
网络 docker network ls 列出网络
docker network create net 创建自定义网络
docker network inspect net 查看哪些容器连入
docker volume ls 列出命名卷
docker volume inspect xx 查看卷存储位置
清理 docker system prune -a 清理无用资源(慎用)
复制代码
# 启动 MySQL 容器
docker run -d \                                      # 后台运行(detached 模式)
  --name mysql \                                     # 给容器起名为 "mysql"
  -p 3306:3306 \                                     # 将虚拟机的 3306 端口映射到容器的 3306 端口(供外部连接)
  -e TZ=Asia/Shanghai \                              # 设置容器时区为上海(避免时间差8小时)
  -e MYSQL_ROOT_PASSWORD=123 \                       # 设置 MySQL root 用户密码(必须设置!)
  -v /root/mysql/data:/var/lib/mysql \               # 挂载数据卷:持久化数据库文件(删容器不丢数据)
  -v /root/mysql/conf:/etc/mysql/conf.d \            # 挂载配置目录:可放入自定义 my.cnf 配置文件
  -v /root/mysql/init:/docker-entrypoint-initdb.d \  # 挂载初始化脚本目录:首次启动时自动执行 .sql 或 .sh 文件
  --network net \                                    # 加入自定义网络 "net",便于与其他容器(如 Java 应用)通过容器名通信
  mysql                                              # 使用官方 mysql 镜像(默认 latest)

# 启动 RabbitMQ 容器(带管理界面)
docker run \
 -e RABBITMQ_DEFAULT_USER=itheima \                  # 设置默认用户名(覆盖 guest)
 -e RABBITMQ_DEFAULT_PASS=123321 \                   # 设置默认密码
 -v mq-plugins:/plugins \                            # 挂载命名卷:持久化已安装的插件(重启不丢失)
 --name mq \                                        # 容器名称设为 "mq"
 --hostname mq \                                    # 设置容器内主机名为 "mq"(RabbitMQ 对 hostname 敏感,建议显式指定)
 -p 15672:15672 \                                   # 映射 Web 管理界面端口(浏览器访问 http://IP:15672)
 -p 5672:5672 \                                     # 映射 AMQP 协议端口(Java 应用通过此端口连接)
 --network net \                                    # 加入同一自定义网络 "net",可被其他服务用 "mq" 名称访问
 -d \                                               # 后台运行
 rabbitmq:3.8-management                            # 使用带 management 插件的 RabbitMQ 3.8 版本镜像

本机(Windows)有 MySQL 占用 3306,Docker 在虚拟机也用 -p 3306:3306,会冲突吗?

✅ 答案:不会冲突!

原因:
  • Windows 的 3306虚拟机的 3306两台不同机器的端口,互不影响。
  • 你在 Windows 访问:
    • localhost:3306 → 连的是 本机 MySQL
    • 虚拟机IP:3306 → 连的是 Docker 里的 MySQL

⚠️ 但注意:

如果虚拟机自己也装了 MySQL(非 Docker) ,再运行 docker run -p 3306:3306 就会端口冲突

解决方法:
  1. 推荐 :停掉虚拟机本地的 MySQLbash

    复制代码
       sudo systemctl stop mysqld
       sudo systemctl disable mysqld
  2. 或改 Docker 映射端口(如 -p 3307:3306),但需连 虚拟机IP:3307


✅ 最佳实践:

  • 虚拟机只跑 Docker 容器,不装原生数据库/中间件
  • 本机服务和虚拟机 Docker 服务完全隔离,放心共存

💡 记住:端口冲突只发生在同一台机器上,跨机器(Windows ↔ 虚拟机)永远不冲突!

相关推荐
zmjjdank1ng3 小时前
Linux 输出重定向
linux·运维
路由侠内网穿透.3 小时前
本地部署智能家居集成解决方案 ESPHome 并实现外部访问( Linux 版本)
linux·运维·服务器·网络协议·智能家居
树℡独3 小时前
ns-3仿真之应用层(三)
运维·服务器·ns3
VekiSon3 小时前
Linux内核驱动——基础概念与开发环境搭建
linux·运维·服务器·c语言·arm开发
禅口魔心4 小时前
Win10 + WSL2 + Docker:K510(DongshanPI-Vision)开发环境从踩坑到跑通全记录(交叉编译 + 上板运行)
docker·嵌入式开发·wsl2·k510
Ankie Wan4 小时前
cgroup(Control Group)是 Linux 内核提供的一种机制,用来“控制、限制、隔离、统计”进程对系统资源的使用。
linux·容器·cgroup·lxc
skywalk81634 小时前
尝试在openi启智社区的dcu环境安装ollama最新版0.15.2(失败)
linux·运维·服务器·ollama
MMME~5 小时前
Ansible模块速查指南:高效定位与实战技巧
大数据·运维·数据库
zhengfei6115 小时前
AutoPentestX – Linux 自动化渗透测试和漏洞报告工具
linux·运维·自动化