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 ↔ 虚拟机)永远不冲突!

相关推荐
~黄夫人~2 小时前
Linux 权限管理:用户组 + 特殊权限 + ACL 解析
linux·运维·计算机·学习笔记·权限管理
2501_907136822 小时前
手搓仓库管理系统Senbar-1.0.4(附带财务管理板块)
运维·服务器·软件需求
盟接之桥4 小时前
盟接之桥EDI软件:API数据采集模块深度解析,打造企业数据协同新引擎
java·运维·服务器·网络·数据库·人工智能·制造
时空潮汐4 小时前
神卓N600 NAS身份核验功能深度解析
linux·运维·网络·神卓nas·神卓n600 pro·家庭轻nas
小李独爱秋4 小时前
模拟面试:用自己的话解释一下lvs的工作原理
linux·运维·面试·职场和发展·操作系统·lvs
百锦再4 小时前
Jenkins 全面精通指南:从入门到脚本大师
运维·后端·python·servlet·django·flask·jenkins
隔壁老王的代码4 小时前
Jenkins的流水线详解
运维·servlet·jenkins
珹洺5 小时前
Java-servlet(五)手把手教你利用Servlet配置HTML请求与相应
java·运维·服务器·前端·servlet·html·maven
一路往蓝-Anbo5 小时前
第 8 章:M33 领航——引导 A35 加载 U-Boot 与 Linux 内核
linux·运维·服务器·stm32·单片机·嵌入式硬件·网络协议
何中应5 小时前
从零搭建JumpServer
运维·堡垒机·jumpserver