从本地到云端:我如何用 Docker 部署 Spring Boot + MySQL 项目的全过程实录

🚀 从本地到云端:我如何用 Docker 部署 Spring Boot + MySQL 项目的全过程实录

嘿,各位在代码世界里构筑梦想的伙伴们!👋

将我们在本地精心打造的 Java 项目,部署到远程的 Linux 服务器上,是每一位后端开发者都会面临的“最后一公里”。传统的方式(直接在服务器上运行 jar 包和安装数据库)虽然可行,但却面临着环境不一致、依赖管理混乱、迁移困难等诸多问题。

今天,我想和大家完整地分享一次我亲身经历的、使用 Docker 将一个 Spring Boot 项目 (productQualification.jar) 及其依赖的 MySQL (My Structured Query Language) 数据库,完整地部署到远程 Ubuntu 服务器的全过程。

这不仅仅是一份操作指南,更是一次从“传统部署”迈向“现代化 DevOps (Development and Operations, 开发运维一体化)”的思维转变之旅。我们将看到,如何通过几个简单的 docker 命令,轻松地“一键启动”整个应用栈。

序章:两大“战场”介绍

我们的故事发生在两个“战场”:

  1. 开发电脑 (Mac): 这是我的源代码所在地,我在这里编写代码、修改配置、打包项目。
  2. 虚拟机服务器 (Ubuntu): IP (Internet Protocol, 互联网协议) 地址为 192.168.31.73,这是我们项目的最终“归宿”。

第一幕:云端奠基 - 部署 MySQL 数据库容器

在部署我们的应用之前,首先要为它准备好“粮仓”——数据库。我们将使用 Docker 来运行一个 MySQL 5.6 的容器。

1. SSH (Secure Shell, 安全外壳协议) 登录服务器
我首先登录到我的 Ubuntu 服务器 192.168.31.73

2. 创建专属的“对话通道” - Docker 网络
为了让应用和数据库能够方便地相互“对话”,我为它们创建了一个专属的虚拟网络:

$ docker network create my-app-net
1a186067f7c8d0...
  • 关键点: 在这个网络里的容器,可以通过容器名直接通信,无需关心 IP 地址。

3. “点火,发射!” - 启动 MySQL 容器
接下来是最激动人心的一步,用一条命令启动我们的数据库服务:

$ docker run -d \
  --name mysql-db \
  -p 3306:3306 \
  -v /home/dgq/mysql-data:/var/lib/mysql \
  --network my-app-net \
  -e MYSQL_ROOT_PASSWORD=your_strong_password \
  -e MYSQL_DATABASE=product_qualification \
  mysql:5.6 

这条命令就像发射火箭的指令,每一项参数都有其精确的含义:

  • -d: 后台运行。
  • --name mysql-db: 命名容器为 mysql-db。这是我们应用连接数据库的“地址”。
  • -p 3306:3306: 将服务器的 3306 端口映射到容器的 3306 端口。
  • -v ...: 数据持久化!将服务器的 /home/dgq/mysql-data 目录挂载到容器内部,确保数据库数据不会因容器删除而丢失。
  • --network my-app-net: 将容器加入我们创建的网络。
  • -e ...: 设置环境变量,初始化 root 密码和数据库名。
  • mysql:5.6: 指定使用的镜像。

执行 docker ps 后,我看到 mysql-db 容器正在稳定运行,数据库地基已成功打下!

第二幕:本地备战 - 修改配置、编写图纸、打包上传

现在,轮到我们的主角——productQualification.jar 登场了。在部署前,我们需要完成三件关键事情:修改配置编写“建筑图纸”(Dockerfile打包并上传

1. 修改数据库连接配置
我打开了项目的 application-test.yml 文件,将 datasource.url 中的主机名修改为我们刚刚启动的 MySQL 容器的名称 mysql-db

spring:
  datasource:
    # url: jdbc:mysql://localhost:3306/productQualification # 本地开发配置
    url: jdbc:mysql://mysql-db:3306/product_qualification # Docker 环境配置
    username: root
    password: your_strong_password
  • 关键点: mysql-db 这个名字,现在就是数据库的“域名”。

2. 编写“建筑图纸” - Dockerfile 详解
Dockerfile 是一个文本文件,它包含了一系列指令,告诉 Docker 如何一步步地构建我们的应用镜像。我在 api 模块的根目录下创建了这个文件。

Dockerfile:

# ----------------------------------
# 阶段 1: 选择基础环境
# ----------------------------------
# 使用一个官方的、包含 Java 8 运行环境(JRE)的基础镜像。
# eclipse-temurin:8-jre-jammy 是一个轻量、稳定且受良好支持的选择。
FROM eclipse-temurin:8-jre-jammy

# ----------------------------------
# 阶段 2: 准备工作区
# ----------------------------------
# 在容器内部创建一个名为 /app 的工作目录。
# 后续的所有命令都将在这个目录下执行。
WORKDIR /app

# ----------------------------------
# 阶段 3: 复制应用程序
# ----------------------------------
# 将我们打包好的 jar 包,从构建上下文(我们上传文件的目录)
# 复制到容器的 /app 目录中,并重命名为 app.jar,方便后续引用。
COPY productQualification.jar app.jar

# ----------------------------------
# 阶段 4: 声明端口
# ----------------------------------
# 告诉 Docker,这个容器在运行时,将会监听 8087 端口。
# 这本身不会自动映射端口,但它是一个重要的元数据声明。
EXPOSE 8087

# ----------------------------------
# 阶段 5: 定义启动命令
# ----------------------------------
# 这是容器启动时要执行的默认命令。
# 它等同于在终端里运行:java -jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

这份“图纸”清晰地定义了我们应用“集装箱”的每一个构建步骤,确保了无论在哪里构建,环境都是完全一致的。

3. 重新打包并“星际传送”
修改配置和创建 Dockerfile 后,我在项目根目录下运行 mvn clean package 重新打包,然后使用 scp (Secure Copy) 命令,将最新的 productQualification.jarDockerfile 一起传送到了远程的 Ubuntu 服务器。

第三幕:云端施工 - 构建镜像、运行容器

回到 Ubuntu 服务器,开始最后的施工。

1. 构建应用的“集装箱” - docker build
我进入刚刚上传文件的目录,执行 docker build 命令:

$ cd /home/dgq/my-java-app
$ docker build -t product-qualification-app .
[+] Building 20.5s (8/8) FINISHED
...

当看到 FINISHED 时,我知道,我的应用已经被成功打包成了一个名为 product-qualification-app 的 Docker 镜像。

2. 应用升空 - docker run
最后一步,就是启动我们的应用容器,并将它也加入到 my-app-net 网络中。

docker run -d \
  --name product-qualification-container \
  -p 8087:8087 \
  --network my-app-net \
  --restart always \
  product-qualification-app

终端返回了一长串容器 ID (Identifier),2a61ed61...,宣告我们的应用已成功“升空”!

最终章:确认成功 - 聆听应用的“心跳”

容器启动了,但它是否真的在健康运行?我立刻使用 docker logs 命令,来查看应用的“心跳”——启动日志。

$ docker logs -f product-qualification-container

终端开始实时滚动输出 Spring Boot 的启动日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
...
 :: Spring Boot ::        (v2.1.1.RELEASE)

... INFO ... : The following profiles are active: test
... INFO ... : {dataSource-1} inited
Hibernate: create table admin ...
Hibernate: create table admin_mini_program ...
...
... INFO ... : Started ApiApplication in 18.543 seconds ...
----------------------------------------------------------
	Application 'api' is running! ...
----------------------------------------------------------

当看到 Started ApiApplication... 这行日志时,我的心终于放下了。

  • {dataSource-1} inited: Druid 数据源初始化成功。
  • Hibernate: create table ...: Hibernate 正在执行 ddl-auto: update,自动创建数据库表。这证明应用已经成功连接到了 mysql-db 容器!

结论与反思

这次部署的成功,完美地展示了 Docker 带来的巨大优势:

  1. 环境隔离: 我不需要在我的 Ubuntu 服务器上手动安装 Java 8 或 MySQL。所有依赖都被各自打包在了独立的容器里。
  2. 服务发现: 通过 Docker 的自定义网络,我的应用仅通过一个简单的名称 mysql-db 就找到了数据库,无需关心复杂的 IP 地址。
  3. 部署标准化: 整个流程——上传、构建、运行——是完全标准化的,可以在任何安装了 Docker 的服务器上轻松复现。
  4. 易于管理: 通过 docker ps, docker logs 等简单的命令,我可以轻松地管理和监控我的整个应用栈。

从本地的一堆源代码,到一个在云端稳定运行的、由多个容器组成的完整服务,Docker 为我们铺平了这条通往现代化部署的康庄大道。

Happy Dockering! 🐳✨


总结与图表分析 📊

📝 Docker 部署流程总结表
阶段核心动作关键命令 / 配置目标
1️⃣ 网络准备创建 Docker 网络docker network create my-app-net为容器间通信建立桥梁
2️⃣ 部署数据库运行 MySQL 容器docker run --name mysql-db ...启动并持久化数据库服务
3️⃣ 应用配置修改 Spring Boot 配置url: jdbc:mysql://mysql-db:3306/...让应用能通过容器名找到数据库
4️⃣ 打包上传重新打包并上传文件mvn package, scp将最新的应用代码和Dockerfile传到服务器
5️⃣ 构建镜像编写 Dockerfile 并构建COPY app.jar, docker build -t ...将应用和其环境打包成一个标准单元
6️⃣ 启动应用运行应用容器docker run --network my-app-net ...启动应用并连接到数据库网络
7️⃣ 验证查看日志和访问docker logs, curl确认整个应用栈工作正常
🗺️ 流程图:从本地开发到服务器部署
远程 Ubuntu 服务器
本地开发电脑
docker network create
docker run mysql:5.6
docker build
docker run my-app
通过浏览器访问
http://服务器IP:8087
修改 application.yml
(url -> mysql-db)
mvn clean package
scp 上传 jar 和 Dockerfile
🔄 时序图:应用容器如何连接到数据库容器
应用容器Docker内部DNSMySQL容器Spring Boot 启动请求解析主机名 "mysql-db"返回 MySQL 容器的内部IP发起数据库连接 (TCP)连接成功应用容器Docker内部DNSMySQL容器
🚦 状态图:从代码到运行中服务的状态
mvn package
docker build
docker run
docker stop/rm
源代码
Jar包
Docker镜像
运行中容器
🏛️ 类图:部署涉及的核心概念
"管理"
1
*
"用于构建"
"读取"
"实例化为"
1
*
"连接"
1
*
DockerHost
+runContainer()
+buildImage()
Dockerfile
+FROM
+COPY
+ENTRYPOINT
DockerImage
-layers
DockerContainer
+start()
+stop()
DockerNetwork
+connect(container)
🔗 实体关系图:最终部署架构

在这里插入图片描述

🧠 思维导图 (Markdown Format)
  • 使用 Docker 部署 Spring Boot + MySQL 项目
    • 🎯 目标
      • 在远程 Ubuntu 服务器上,容器化部署整个应用栈
    • 1️⃣ 准备数据库 (mysql-db 容器)
      • 网络: docker network create my-app-net -> 为容器通信创建桥梁
      • 数据持久化: 在宿主机创建目录 mkdir /home/dgq/mysql-data
      • 启动: docker run -d --name mysql-db -p 3306:3306 -v ... --network ... -e ... mysql:5.6
        • 关键: --name 用于服务发现, -v 用于持久化, --network 用于连接
    • 2️⃣ 准备应用程序 (本地电脑)
      • 修改配置:
        • 文件: application.yml
        • 核心: spring.datasource.url 的主机名改为 mysql-db
      • 打包: mvn package -> 生成包含新配置的 productQualification.jar
      • 创建 Dockerfile:
        • FROM eclipse-temurin:8-jre-jammy
        • COPY productQualification.jar app.jar
        • EXPOSE 8087
        • ENTRYPOINT ["java", "-jar", "app.jar"]
      • 上传: 使用 scp (Secure Copy, 安全拷贝) 将 jar 包和 Dockerfile 上传到服务器
    • 3️⃣ 部署应用程序 (服务器)
      • 构建镜像: docker build -t product-qualification-app . -> 根据 Dockerfile 创建镜像
      • 启动容器: docker run -d --name ... -p 8087:8087 --network my-app-net ... product-qualification-app
        • 关键: --network my-app-net 确保应用能找到 mysql-db
    • 4️⃣ 验证
      • 检查容器: docker ps -> 确认 mysql-db 和应用容器都在 Up 状态
      • 检查日志: docker logs -f <应用容器名> -> 查看 Spring Boot 启动日志,确认数据库连接成功
      • 访问应用: 浏览器访问 http://服务器IP:8087
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值