阿撒亚丽 發表於 2025-1-20 11:29:00

我干了两个月的大项目,开源了!

<p class="md-end-block md-heading"><span class="md-plain">大家好,我是程序员鱼皮。我肝了 2 个多月的大项目《智能协同云图库》,终于完结了!</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1735878225578-955f3e74-7033-4ff1-930c-1d03972ef453.png"><img src="https://pic.yupi.icu/1/1735878225578-955f3e74-7033-4ff1-930c-1d03972ef453.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">为了让更多同学参与学习,我特么直接把所有代码 <span class="md-pair-s "><strong>完整开源</strong><span class="md-plain"> !</span></span></span></p>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">开源仓库:<span class="md-link md-pair-s">https://github.com/liyupi/yu-picture</span></span></p>
</blockquote>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/image-20250116123632636.png"><img src="https://pic.yupi.icu/1/image-20250116123632636.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">光分享源码还不够,我还录制了一套将源码快速上线的视频教程:<span class="md-link md-pair-s">https://bilibili.com/video/BV1akwGeSERK<span class="md-plain"> ,有关这个项目的介绍、前后端部署方法、项目功能演示,都在这个视频里了~</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">不过虽然代码是开源的,项目的视频教程 + 文字教程 + 简历写法 + 面试题解是仅供 <span class="md-meta-i-cmd-link"><span class="md-plain">编程导航</span><span class="md-plain"> 的鱼友学习的,毕竟我连续肝了 2 个月嘛。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/image-20250116124218981.png"><img src="https://pic.yupi.icu/1/image-20250116124218981.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">下面分享将智能协同云图库项目上线的文字教程,推荐配合前面的视频教程食用。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<div class="md-hr md-end-block"><hr></div>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">本节重点内容是项目部署上线,可以独立学习,希望大家能够掌握这种快速上线项目的方法。</span></p>
<p class="md-end-block md-p"><span class="md-plain">包括:</span></p>
<ol class="ol-list" start="">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">服务器初始化</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">部署规划</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">安装依赖</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">后端部署</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">前端部署</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">测试验证</span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-plain">扩展知识</span></p>
</li>
</ol>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">一、服务器初始化</span></h2>
<p class="md-end-block md-p"><span class="md-plain">首先购买一台服务器,各大云服务商的新用户都比较便宜,建议先看 <span class="md-meta-i-cmd-link"><span class="md-plain">云产品</span><span class="md-plain"> 页面。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">推荐选择轻量应用服务器,提供了很多开箱即用的模板,帮我们预装了环境和软件,省时省力。</span></p>
<p class="md-end-block md-p"><span class="md-plain">鱼皮这里选择一台预装了宝塔 Linux 应用的轻量应用服务器,配置为 2 核 2 G,部署咱们的项目足够了。应用模板一般选择最新版本就好了,如下图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1727248104987-b129e975-2cbd-4a64-a2db-f770c519ac4f.png"><img src="https://pic.yupi.icu/1/1727248104987-b129e975-2cbd-4a64-a2db-f770c519ac4f.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">宝塔 Linux 是一个可视化 Linux 运维管理工具,提供了很多帮助我们管理服务器的功能,适合中小团队或者个人学习使用。</span></p>
<p class="md-end-block md-p"><span class="md-plain">购买好服务器后,进入控制台,可以看到新增的服务器信息,注意不要主动对外暴露公网 IP!</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736820777990-93b3eb0f-fa13-4e52-ba53-93f4d5d43968.png"><img src="https://pic.yupi.icu/1/1736820777990-93b3eb0f-fa13-4e52-ba53-93f4d5d43968.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">点击服务器进入详情页,在防火墙标签页中放通 8888 宝塔面板端口,否则无法在自己的电脑上访问宝塔。</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736820851710-b8e1df10-dbc1-47c7-8131-bc50816b9c13.png"><img src="https://pic.yupi.icu/1/1736820851710-b8e1df10-dbc1-47c7-8131-bc50816b9c13.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">新版本的轻量应用服务器已经自动为我们放通该端口。否则需要手动新增一条防火墙规则:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1727248461577-ddd18cf9-9754-4409-94a0-d62d943f76c0.png"><img src="https://pic.yupi.icu/1/1727248461577-ddd18cf9-9754-4409-94a0-d62d943f76c0.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">进入应用管理标签页,登录宝塔。</span></p>
<p class="md-end-block md-p"><span class="md-plain">首次登录时,需要先登录服务器,通过输入命令的方式获取宝塔默认账号密码,如图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736820908310-2c1e539f-a936-4be7-bfdc-77fd00a0081d.png"><img src="https://pic.yupi.icu/1/1736820908310-2c1e539f-a936-4be7-bfdc-77fd00a0081d.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">点击登录后,进入到 web 终端,复制脚本并执行:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736820955676-2927899e-9af4-4e8e-a15f-a4adc093887c.png"><img src="https://pic.yupi.icu/1/1736820955676-2927899e-9af4-4e8e-a15f-a4adc093887c.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">根据终端输出的信息,访问宝塔面板,输入初始用户名和密码:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1727248615289-c68e08eb-e5eb-4e1c-bdc2-83a643d6d849.png"><img src="https://pic.yupi.icu/1/1727248615289-c68e08eb-e5eb-4e1c-bdc2-83a643d6d849.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">首次进入宝塔时,会提示我们安装环境,这里推荐安装 LNMP(包含 Nginx 服务器),适合部署前后端分离的项目:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736821032080-4be9c9e5-6dfe-434b-8db8-7eb8d7068a16.png"><img src="https://pic.yupi.icu/1/1736821032080-4be9c9e5-6dfe-434b-8db8-7eb8d7068a16.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">首次进入宝塔面板时,记得修改面板账号密码(每次修改完都要重新登录):</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1727248755605-f14e4ce0-b33a-4b48-90b5-6faa3a04e9c3.png"><img src="https://pic.yupi.icu/1/1727248755605-f14e4ce0-b33a-4b48-90b5-6faa3a04e9c3.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">二、部署规划</span></h2>
<p class="md-end-block md-p"><span class="md-plain">在正式操作前后端部署前,我们要先进行一个规划,比如要部署哪些项目和服务、需要哪些依赖、占用哪些端口等。</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">1、获取源码</span></h3>
<p class="md-end-block md-p"><span class="md-plain">本项目代码开源:<span class="md-link md-pair-s">https://github.com/liyupi/yu-picture</span></span></p>
<p class="md-end-block md-p"><span class="md-plain">建议新手学习和部署 yu-picture-backend 目录,使用传统的分层架构:<span class="md-link md-pair-s">https://github.com/liyupi/yu-picture/tree/master/yu-picture-backend</span></span></p>
<p class="md-end-block md-p"><span class="md-plain">有一定经验的同学可以学习部署 yu-picture-backend-ddd 目录,使用 DDD 领域驱动设计:<span class="md-link md-pair-s">https://github.com/liyupi/yu-picture/tree/master/yu-picture-backend-ddd</span></span></p>
<p class="md-end-block md-p"><span class="md-plain">但这两种架构的部署方式是一致的~</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">2、部署方案</span></h3>
<p class="md-end-block md-p"><span class="md-plain">为了提高效率,本项目前端和后端均使用宝塔面板进行部署,可以很方便地管理服务器。</span></p>
<p class="md-end-block md-p"><span class="md-plain">涉及到具体的部署方式,前端要遵循 Vue 项目的部署模式,基于 Nginx 运行;后端可以直接利用宝塔的 Java 项目管理器运行 jar 包。</span></p>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">在鱼皮编程导航的 <span class="md-meta-i-cmd-link"><span class="md-plain">代码生成器共享平台项目</span><span class="md-plain"> 中,讲解过宝塔 + Nginx + 后端 Java 项目管理器(jar 包)的部署方式。在鱼皮编程导航的 <span class="md-meta-i-cmd-link"><span class="md-plain">AI 答题应用平台项目</span><span class="md-plain"> 中,讲解过 Vercel + Docker + 云托管平台的部署方式,感兴趣的同学可以学习。基本上学会这几种部署方式,能够应对绝大多数部署需求了。</span></span></span></span></span></p>
</blockquote>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3、地址规划</span></h3>
<p class="md-end-block md-p"><span class="md-plain">前端:通过 Nginx 进行转发,访问地址为 <span class="md-pair-s"><code>http://{域名}</code><span class="md-plain">。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">后端:通过 Nginx 进行转发,访问地址为 <span class="md-pair-s"><code>http://{域名}/api</code><span class="md-plain">。实际运行在 8123 端口。<span class="md-pair-s "><strong>JDK 建议选择 17 版本!</strong></span></span></span></span></p>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">为什么要用 Nginx 转发?</span></p>
<p class="md-end-block md-p"><span class="md-plain">前端和后端域名一致,保证不会出现跨域问题。</span></p>
</blockquote>
<p class="md-end-block md-p"><span class="md-plain">Nginx:服务器 80 端口,默认已安装。</span></p>
<p class="md-end-block md-p"><span class="md-plain">数据库:服务器 3306 端口,默认已安装。</span></p>
<p class="md-end-block md-p"><span class="md-plain">Redis:服务器 6379 端口,需要手动安装。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">4、注意事项</span></h3>
<p class="md-end-block md-p"><span class="md-plain">做好规划后,我们需要在腾讯云控制台的防火墙中开通需要外网访问的服务端口,比如 MySQL 和 Redis:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736823033530-55a82571-58ab-420d-b672-1cf0dd77d5bf.png"><img src="https://pic.yupi.icu/1/1736823033530-55a82571-58ab-420d-b672-1cf0dd77d5bf.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">三、安装依赖</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">1、数据库</span></h3>
<p class="md-end-block md-p"><span class="md-plain">宝塔面板已经自动安装 MySQL 数据库,我们可以直接使用。</span></p>
<p class="md-end-block md-p"><span class="md-plain">先为后端项目添加一个数据库。数据库名称和我们项目需要的数据库名称保持一致(此处为 mianshiya),注意用户名、密码和访问权限:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736823436494-00acbd12-3e8e-40d0-9ad1-e4f4823289d3.png"><img src="https://pic.yupi.icu/1/1736823436494-00acbd12-3e8e-40d0-9ad1-e4f4823289d3.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">在 IDEA 中打开后端项目,通过数据库面板在本地检查连接是否正常:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736823590747-1168f865-d940-4a2b-9bc8-8b534056a93b.png"><img src="https://pic.yupi.icu/1/1736823590747-1168f865-d940-4a2b-9bc8-8b534056a93b.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">执行脚本,初始化库表:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736823659602-c1ccd7c5-1b6b-4a8c-b5d2-9dd0ab4fda25.png"><img src="https://pic.yupi.icu/1/1736823659602-c1ccd7c5-1b6b-4a8c-b5d2-9dd0ab4fda25.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">记得验证数据库表是否创建成功,如下图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736823703886-083cb8bd-7124-4007-8427-d048a14de531.png"><img src="https://pic.yupi.icu/1/1736823703886-083cb8bd-7124-4007-8427-d048a14de531.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">2、Redis</span></h3>
<p class="md-end-block md-p"><span class="md-plain">在宝塔面板的软件商店中,搜索并安装 Redis:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1727251186974-06b1690e-ae35-49fa-939f-8423bbdf411f.png"><img src="https://pic.yupi.icu/1/1727251186974-06b1690e-ae35-49fa-939f-8423bbdf411f.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">版本选择默认的即可:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736823849973-dc8a0d7e-c4f3-4ec0-9857-5a29bee0f7b3.png"><img src="https://pic.yupi.icu/1/1736823849973-dc8a0d7e-c4f3-4ec0-9857-5a29bee0f7b3.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">安装完成后,需要配置 Redis,开启远程访问并配置密码,否则我们自己的电脑是无法连接 Redis 的:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736824403660-f1488a81-a35a-4870-ade2-01828f52db88.png"><img src="https://pic.yupi.icu/1/1736824403660-f1488a81-a35a-4870-ade2-01828f52db88.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">修改配置后,一定要重载配置才能生效:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736824425493-34028e4b-06bb-4eec-bb28-8a5f324c5c8a.png"><img src="https://pic.yupi.icu/1/1736824425493-34028e4b-06bb-4eec-bb28-8a5f324c5c8a.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">最后,在 IDEA 数据库面板中验证本地能否连接远程 Redis:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736824532974-e0a5421f-071d-4f96-a08b-30e570124ad6.png"><img src="https://pic.yupi.icu/1/1736824532974-e0a5421f-071d-4f96-a08b-30e570124ad6.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3、Java 环境</span></h3>
<p class="md-end-block md-p"><span class="md-plain">要部署 Java 项目,必须安装 JDK。在宝塔面板中,可以通过下图的方式快速安装指定版本的 JDK。此处我们先安装 JDK 17:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736824607783-2816da67-3c21-4c06-a150-d759787fc0ae.png"><img src="https://pic.yupi.icu/1/1736824607783-2816da67-3c21-4c06-a150-d759787fc0ae.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">建议多安装几个版本,比如 JDK 8、11、17,需要用哪个版本的时候可以随时切换。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">4、其他服务</span></h3>
<p class="md-end-block md-p"><span class="md-plain">比如 <span class="md-meta-i-cmd-link"><span class="md-plain">腾讯云 COS 对象存储</span><span class="md-plain">、<span class="md-meta-i-cmd-link"><span class="md-plain">阿里云百炼 AI</span><span class="md-plain">,可以去对应的官网开通。</span></span></span></span></span></p>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">如果不会开通的话,可以通过第 4 章教程开通 COS 对象存储,第 9 章教程开通阿里云百炼 AI。</span></p>
</blockquote>
<p class="md-end-block md-p"><span class="md-plain">注意,要给对象存储增加该服务器 IP(或者实际访问前端域名)的跨域配置,否则编辑图片时将无法正确加载图片。</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736831344317-ff7042af-4a3f-4e15-bd98-afe47369ee6b.png"><img src="https://pic.yupi.icu/1/1736831344317-ff7042af-4a3f-4e15-bd98-afe47369ee6b.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<div class="md-hr md-end-block"><hr></div>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">接下来,我们分别进行后端和前端部署。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">四、后端部署</span></h2>
<h3 class="md-end-block md-heading"><span class="md-plain">1、修改配置</span></h3>
<p class="md-end-block md-p"><span class="md-plain">修改 <span class="md-pair-s"><code>application-prod</code><span class="md-plain"> 生产环境配置,包括数据库、Redis、对象存储、阿里云百炼 AI 的 key 等,替换为上述安装依赖时指定的配置(如用户名、密码)。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">注意为了性能,还要关闭 MyBatis Plus 的日志;为了安全,要给 Knife4j 接口文档设置用户名和密码。</span></p>
<p class="md-end-block md-p"><span class="md-plain">参考配置如下:</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-comment"># 线上配置文件<br><span><span class="cm-comment"># @author &lt;a href="https://github.com/liyupi"&gt;程序员鱼皮&lt;/a&gt;<br><span><span class="cm-comment"># @from &lt;a href="https://codefather.cn"&gt;编程导航&lt;/a&gt;<br><span><span class="cm-atom">server<span class="cm-meta">:<br><span><span class="cm-atom">port<span class="cm-meta">:&nbsp;<span class="cm-number">8123<br><span><span class="cm-atom">spring<span class="cm-meta">:<br><span>&nbsp;<span class="cm-comment"># 数据库配置<br><span>&nbsp;<span class="cm-comment"># todo 需替换配置<br><span><span class="cm-atom">datasource<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; driver-class-name<span class="cm-meta">:&nbsp;com.mysql.cj.jdbc.Driver<br><span><span class="cm-atom">&nbsp; url<span class="cm-meta">:&nbsp;jdbc<span class="cm-meta">:mysql<span class="cm-meta">://81.69.229.63<span class="cm-meta">:3306/yu_picture<br><span><span class="cm-atom">&nbsp; username<span class="cm-meta">:&nbsp;yu_picture_root<br><span><span class="cm-atom">&nbsp; password<span class="cm-meta">:&nbsp;yu_picture_123456<br><span>&nbsp;<span class="cm-comment"># Redis 配置<br><span>&nbsp;<span class="cm-comment"># todo 需替换配置<br><span><span class="cm-atom">redis<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; database<span class="cm-meta">:&nbsp;<span class="cm-number">0<br><span><span class="cm-atom">&nbsp; host<span class="cm-meta">:&nbsp;<span class="cm-number">81.69.229.63<br><span><span class="cm-atom">&nbsp; port<span class="cm-meta">:&nbsp;<span class="cm-number">6379<br><span><span class="cm-atom">&nbsp; timeout<span class="cm-meta">:&nbsp;<span class="cm-number">5000<br><span><span class="cm-atom">&nbsp; password<span class="cm-meta">:&nbsp;<span class="cm-number">123456<br><span><span class="cm-atom">mybatis-plus<span class="cm-meta">:<br><span><span class="cm-atom">configuration<span class="cm-meta">:<br><span>&nbsp; &nbsp;<span class="cm-comment"># 生产环境关闭日志<br><span><span class="cm-atom">&nbsp; log-impl<span class="cm-meta">:&nbsp;<span class="cm-string">''<br><span><span class="cm-comment"># 接口文档配置<br><span><span class="cm-atom">knife4j<span class="cm-meta">:<br><span><span class="cm-atom">basic<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; enable<span class="cm-meta">:&nbsp;<span class="cm-keyword">true<br><span><span class="cm-atom">&nbsp; username<span class="cm-meta">:&nbsp;root<br><span><span class="cm-atom">&nbsp; password<span class="cm-meta">:&nbsp;<span class="cm-number">123456<br><span><span class="cm-comment"># 对象存储配置<br><span><span class="cm-atom">cos<span class="cm-meta">:<br><span><span class="cm-atom">client<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; host<span class="cm-meta">:&nbsp;xxx<br><span><span class="cm-atom">&nbsp; secretId<span class="cm-meta">:&nbsp;xxx<br><span><span class="cm-atom">&nbsp; secretKey<span class="cm-meta">:&nbsp;xxx<br><span><span class="cm-atom">&nbsp; region<span class="cm-meta">:&nbsp;xxx<br><span><span class="cm-atom">&nbsp; bucket<span class="cm-meta">:&nbsp;xxx<br><span><span class="cm-comment"># 阿里云 AI 配置<br><span><span class="cm-atom">aliYunAi<span class="cm-meta">:<br><span><span class="cm-atom">apiKey<span class="cm-meta">:&nbsp;xxx</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">2、打包部署</span></h3>
<p class="md-end-block md-p"><span class="md-plain">首先更改 pom.xml 文件的打包配置,删除掉主类配置的 <span class="md-pair-s"><code>skip</code><span class="md-plain"> 配置,才能打包:</span></span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-tag cm-bracket">&lt;<span class="cm-tag">build<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">plugins<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">plugin<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">groupId<span class="cm-tag cm-bracket">&gt;org.springframework.boot<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">groupId<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">artifactId<span class="cm-tag cm-bracket">&gt;spring-boot-maven-plugin<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">artifactId<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">version<span class="cm-tag cm-bracket">&gt;${spring-boot.version}<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">version<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">configuration<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">mainClass<span class="cm-tag cm-bracket">&gt;com.yupi.yupicturebackend.YuPictureBackendApplication<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">mainClass<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;<span class="cm-tag">skip<span class="cm-tag cm-bracket">&gt;true<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">skip<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">configuration<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">plugin<span class="cm-tag cm-bracket">&gt;<br><span>&nbsp; &nbsp;<span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">plugins<span class="cm-tag cm-bracket">&gt;<br><span><span class="cm-tag cm-bracket">&lt;/<span class="cm-tag">build<span class="cm-tag cm-bracket">&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">在 IDEA 中打开后端项目,忽略测试并打包:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736824989133-cbae0c04-d3dd-414d-9fc5-f9bfb164a6ed.png"><img src="https://pic.yupi.icu/1/1736824989133-cbae0c04-d3dd-414d-9fc5-f9bfb164a6ed.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">打包成功,得到 jar 包文件:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736825047389-eb078b33-601f-4493-a48e-964f7905361b.png"><img src="https://pic.yupi.icu/1/1736825047389-eb078b33-601f-4493-a48e-964f7905361b.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">上传 jar 包到服务器,此处为了方便,就放到 web 根目录:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736825857679-13e11acb-80cb-477a-8632-954d5579b1c9.png"><img src="https://pic.yupi.icu/1/1736825857679-13e11acb-80cb-477a-8632-954d5579b1c9.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">然后添加 Java 项目,<span class="md-pair-s "><strong>在项目执行命令中,必须指定生产环境的配置!</strong><span class="md-plain">还可以根据需要调整内存:</span></span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736825196166-52539996-d462-482e-bc38-65e41cd73a16.png"><img src="https://pic.yupi.icu/1/1736825196166-52539996-d462-482e-bc38-65e41cd73a16.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">启动成功后,能够看到状态和端口占用如图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736825898998-5227749e-c917-4e16-98b7-06dc9976d3ea.png"><img src="https://pic.yupi.icu/1/1736825898998-5227749e-c917-4e16-98b7-06dc9976d3ea.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">如果发现启动失败,需要先观察日志,下图仅为一个示例:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1706154336729-f7464cdf-99f8-42ef-8f24-cca2967a131e.png"><img src="https://pic.yupi.icu/1/1706154336729-f7464cdf-99f8-42ef-8f24-cca2967a131e.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<p class="md-end-block md-p"><span class="md-plain">但是,我们现在无法通过浏览器访问接口文档:<span class="md-link md-pair-s">http://81.69.229.63:8123/api/doc.html</span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736825991896-0ce18bfb-3e8b-4e9b-aa97-4050d47c0166.png"><img src="https://pic.yupi.icu/1/1736825991896-0ce18bfb-3e8b-4e9b-aa97-4050d47c0166.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">这是因为我们的服务器防火墙没有放开 8123 端口。<span class="md-pair-s "><strong>这里我们故意不放开</strong><span class="md-plain">,因为在之前的部署规划中,后端需要通过 Nginx 进行转发,从而解决跨域问题。</span></span></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3、Nginx 转发</span></h3>
<p class="md-end-block md-p"><span class="md-plain">新建一个 Nginx 站点,域名填写当前服务器 IP 或者自己的域名,根目录随意填写即可(只要不包含中文):</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736826094234-923bc743-4013-4139-8b3e-8c3aaf714783.png"><img src="https://pic.yupi.icu/1/1736826094234-923bc743-4013-4139-8b3e-8c3aaf714783.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">如果访问的是后端接口(地址有 <span class="md-pair-s"><code>/api</code><span class="md-plain"> 前缀),则 Nginx 将请求转发到后端服务,对应配置代码如下:</span></span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-variable-2">location&nbsp;/<span class="cm-tag">api&nbsp;{<br><span>&nbsp;<span class="cm-string-2">proxy_pass&nbsp;&nbsp;<span class="cm-variable-2">http://127.0.0.1:8123;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">Host&nbsp;$proxy_host;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">X-Real-IP&nbsp;$remote_addr;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">X-Forwarded-For&nbsp;$proxy_add_x_forwarded_for;<br><span>&nbsp;<span class="cm-keyword">proxy_buffering&nbsp;off;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">Connection&nbsp;<span class="cm-string">"";<br><span>}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">但是,对于本项目,光有 HTTP 转发配置还不够!后端还需要提供 WebSocket 连接,所以也要对 WebSocket 进行转发,再给 Nginx 补充下列配置:</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-comment"># 代理 WebSocket 连接 (专门用于 WebSocket 请求)<br><span><span class="cm-variable-2">location&nbsp;/api/<span class="cm-tag">ws&nbsp;{<br><span>&nbsp;<span class="cm-string-2">proxy_pass&nbsp;<span class="cm-variable-2">http://127.0.0.1:8123;<br><span>&nbsp;<span class="cm-variable">proxy_http_version 1.1;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">Upgrade&nbsp;$http_upgrade;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">Connection&nbsp;<span class="cm-string">"upgrade";<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">Host&nbsp;$host;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">X-Real-IP&nbsp;$remote_addr;<br><span>&nbsp;<span class="cm-keyword">proxy_set_header&nbsp;<span class="cm-number">X-Forwarded-For&nbsp;$proxy_add_x_forwarded_for;<br><span>&nbsp;<span class="cm-keyword">proxy_buffering&nbsp;off;<br><span>&nbsp;<span class="cm-keyword">proxy_read_timeout&nbsp;86400s;<br><span>}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">修改 Nginx 配置如图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736832443490-d839d5c8-0b99-4bcd-8c82-f84ee55e5f88.png"><img src="https://pic.yupi.icu/1/1736832443490-d839d5c8-0b99-4bcd-8c82-f84ee55e5f88.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">修改完后,就可以通过 80 端口(可以省略)访问到接口了。</span></p>
<p class="md-end-block md-p"><span class="md-pair-s"><strong>一定要注释掉下列配置!</strong><span class="md-plain">否则访问接口文档时,静态资源的加载可能会出错。因为浏览器会从本地缓存加载资源,而不是动态请求资源。</span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1727258259642-b591c3f0-3e46-4c9e-aaed-736bbc87ac6a.png"><img src="https://pic.yupi.icu/1/1727258259642-b591c3f0-3e46-4c9e-aaed-736bbc87ac6a.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">五、前端部署</span></h2>
<p class="md-end-block md-p"><span class="md-plain">前端部署可以参考 Vite 官方文档:<span class="md-link md-pair-s">https://cn.vitejs.dev/guide/static-deploy.html</span></span></p>
<p class="md-end-block md-p"><span class="md-plain">分为修改配置、打包部署和 Nginx 转发这 3 个步骤。</span></p>
<h3 class="md-end-block md-heading"><span class="md-plain">1、修改配置</span></h3>
<p class="md-end-block md-p"><span class="md-plain">线上的前端需要请求线上的后端接口,所以需要修改 <span class="md-pair-s"><code>request.ts</code><span class="md-plain"> 文件中的请求地址为线上:</span></span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-comment">// 区分开发和生产环境<br><span><span class="cm-keyword">const&nbsp;<span class="cm-def">DEV_BASE_URL&nbsp;<span class="cm-operator">=&nbsp;<span class="cm-string">"http://localhost:8123";<br><span><span class="cm-keyword">const&nbsp;<span class="cm-def">PROD_BASE_URL&nbsp;<span class="cm-operator">=&nbsp;<span class="cm-string">"http://81.69.229.63";<br><span><span class="cm-comment">// 创建 Axios 实例<br><span><span class="cm-keyword">const&nbsp;<span class="cm-def">myAxios&nbsp;<span class="cm-operator">=&nbsp;<span class="cm-variable">axios.<span class="cm-property">create({<br><span>&nbsp;<span class="cm-property">baseURL:&nbsp;<span class="cm-variable">PROD_BASE_URL,<br><span>&nbsp;<span class="cm-property">timeout:&nbsp;<span class="cm-number">10000,<br><span>&nbsp;<span class="cm-property">withCredentials:&nbsp;<span class="cm-atom">true,<br><span>});</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">此外,由于本项目用到了 WebSocket,还要同步修改 <span class="md-pair-s"><code>pictureEditWebSocket.ts</code><span class="md-plain"> 文件中的 WebSocket 的连接地址:</span></span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-keyword">const&nbsp;<span class="cm-def">DEV_BASE_URL&nbsp;<span class="cm-operator">=&nbsp;<span class="cm-string">"ws://localhost:8123";<br><span><span class="cm-keyword">const&nbsp;<span class="cm-def">PROD_BASE_URL&nbsp;<span class="cm-operator">=&nbsp;<span class="cm-string">"ws://81.69.229.63";<br><span><span class="cm-keyword">const&nbsp;<span class="cm-def">url&nbsp;<span class="cm-operator">=&nbsp;<span class="cm-string-2">`${<span class="cm-variable">PROD_BASE_URL<span class="cm-string-2">}/api/ws/picture/edit?pictureId=${<span class="cm-keyword">this.<span class="cm-property">pictureId<span class="cm-string-2">}`</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">2、打包部署</span></h3>
<p class="md-end-block md-p"><span class="md-plain">1)参考 Vite 官网,在 <span class="md-pair-s"><code>package.json</code><span class="md-plain"> 文件中定义 <span class="md-pair-s"><code>pure-build</code><span class="md-plain"> 命令:</span></span></span></span></span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span>{<br><span>&nbsp;<span class="cm-string cm-property">"scripts": {<br><span>&nbsp; &nbsp;<span class="cm-string cm-property">"dev":&nbsp;<span class="cm-string">"vite",<br><span>&nbsp; &nbsp;<span class="cm-string cm-property">"pure-build":&nbsp;<span class="cm-string">"vite build",<br><span>&nbsp; &nbsp;<span class="cm-string cm-property">"build":&nbsp;<span class="cm-string">"run-p type-check \"build-only {@}\" --",<br><span>}<br><span>}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">为什么明明已经有 <span class="md-pair-s"><code>build</code><span class="md-plain"> 命令了,我们还要自己定义 <span class="md-pair-s"><code>pure-build</code><span class="md-plain"> 命令呢?</span></span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">因为脚手架内置的 <span class="md-pair-s"><code>build</code><span class="md-plain"> 命令会执行类型检查,如果项目代码中有任何类型不规范的地方,都会导致打包失败!</span></span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736829734802-1a7a170c-882c-408f-b039-18f503d79a8c.png"><img src="https://pic.yupi.icu/1/1736829734802-1a7a170c-882c-408f-b039-18f503d79a8c.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">虽然可以自己一个个修复类型,但是太影响效率了,得不偿失,所以引入一个更干净的构建命令。</span></p>
<p class="md-end-block md-p"><span class="md-plain">2)执行 <span class="md-pair-s"><code>pure-build</code><span class="md-plain"> 命令,执行打包构建。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">注意,如果 Node.js 版本较低,会构建失败,这时可以到 <span class="md-meta-i-cmd-link"><span class="md-plain">官网</span><span class="md-plain"> 安装更新的版本,比如 v20.17.0 等长期支持版本。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">构建成功后,可以得到用于部署的静态文件 <span class="md-pair-s"><code>dist</code><span class="md-plain"> 目录:</span></span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736829834651-52dd76c1-b3ba-4731-93c3-a4341f023ae2.png"><img src="https://pic.yupi.icu/1/1736829834651-52dd76c1-b3ba-4731-93c3-a4341f023ae2.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">把 dist 目录下的所有文件上传到服务器上(可以新建一个 yu-picture-frontend 目录)。文件较多时,建议先在本地压缩,上传压缩包到服务器后再解压。如图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830043889-35546f3b-d234-41af-90b4-c0f69e9167f9.png"><img src="https://pic.yupi.icu/1/1736830043889-35546f3b-d234-41af-90b4-c0f69e9167f9.png"></span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h3 class="md-end-block md-heading"><span class="md-plain">3、Nginx 转发</span></h3>
<p class="md-end-block md-p"><span class="md-plain">一般来说,用户无法直接访问服务器上的文件,需要使用 Nginx 提供静态文件的访问能力。</span></p>
<p class="md-end-block md-p"><span class="md-plain">修改已有站点的网站目录配置,指向前端文件根目录:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830245682-e57f7fa8-7175-4eb6-b34d-4bd95015df38.png"><img src="https://pic.yupi.icu/1/1736830245682-e57f7fa8-7175-4eb6-b34d-4bd95015df38.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">然后访问服务器地址(或者自己配置的域名),就能打开前端网站了:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830335779-ab219cd4-bfb8-4048-918f-cfd5b02185c3.png"><img src="https://pic.yupi.icu/1/1736830335779-ab219cd4-bfb8-4048-918f-cfd5b02185c3.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">但是经过验证,目前访问除了主页外的其他页面(比如 /add_picture),如果刷新页面,就会出现 404 错误。</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1706159081942-2f51f135-1218-4fee-b957-08e811a91762.png"><img src="https://pic.yupi.icu/1/1706159081942-2f51f135-1218-4fee-b957-08e811a91762.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">这个问题是由于 Vue 是单页面应用(前端路由),打包后的文件只有 <span class="md-pair-s"><code>index.html</code><span class="md-plain">,服务器上不存在对应的页面文件(比如 /add_picture.html),所以需要在 Nginx 配置转发。如果找不到某个页面文件,就加载主页 index.html 文件。</span></span></span></p>
<p class="md-end-block md-p"><span class="md-plain">修改 Nginx 配置,补充下列代码:</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-variable-2">location&nbsp;/ {<br><span>&nbsp;<span class="cm-string-2">try_files&nbsp;<span class="cm-number">$uri&nbsp;$uri/<span class="cm-keyword">index.<span class="cm-number">html&nbsp;/<span class="cm-keyword">index.html;<br><span>}</span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">如图:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830583864-b9e22db7-a691-4a10-a024-876bcad09d3a.png"><img src="https://pic.yupi.icu/1/1736830583864-b9e22db7-a691-4a10-a024-876bcad09d3a.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">保存配置后,再次刷新页面,可以正常访问。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">六、测试验证</span></h2>
<p class="md-end-block md-p"><span class="md-plain">最后,我们来对上线效果进行验证。</span></p>
<p class="md-end-block md-p"><span class="md-plain">1)用户注册登录</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830672014-427f1d81-a8d2-42a2-97d7-ec3589b6c04b.png"><img src="https://pic.yupi.icu/1/1736830672014-427f1d81-a8d2-42a2-97d7-ec3589b6c04b.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">然后通过修改数据库的方式,将该用户的角色设置为管理员,从而使用更多功能。</span></p>
<p class="md-end-block md-p"><span class="md-plain">2)进入图片管理 =&gt; 批量创建图片页面,抓取一批图片作为网站的初始数据</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830777790-4720829e-c798-4298-bb68-688212645b09.png"><img src="https://pic.yupi.icu/1/1736830777790-4720829e-c798-4298-bb68-688212645b09.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">3)进入主页,查看到了公共图库</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830806797-dac95c7c-cc28-4ec1-a899-c210b5d36f51.png"><img src="https://pic.yupi.icu/1/1736830806797-dac95c7c-cc28-4ec1-a899-c210b5d36f51.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">4)创建一个私有空间</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830826161-32b901eb-64cd-44b9-beaf-5a15f71b3489.png"><img src="https://pic.yupi.icu/1/1736830826161-32b901eb-64cd-44b9-beaf-5a15f71b3489.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">5)通过文件上传和 URL 上传给私有空间上传一些图片:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830860221-0f7760e3-3a87-405d-b2b1-421e773fb983.png"><img src="https://pic.yupi.icu/1/1736830860221-0f7760e3-3a87-405d-b2b1-421e773fb983.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">6)查看私有空间的图片,尝试各种搜索功能(比如按颜色搜索):</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830926145-bd87c0c7-84ff-465b-b813-320ee895f94e.png"><img src="https://pic.yupi.icu/1/1736830926145-bd87c0c7-84ff-465b-b813-320ee895f94e.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">7)使用 AI 扩图功能来编辑图片(基于 <span class="md-meta-i-cmd-link"><span class="md-plain">阿里云百炼 AI</span><span class="md-plain"> 实现)</span></span></span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736831872771-af5680ea-f4fc-4a72-a66a-1bc5a4d8f8d0.png"><img src="https://pic.yupi.icu/1/1736831872771-af5680ea-f4fc-4a72-a66a-1bc5a4d8f8d0.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">8)创建团队空间</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736830970551-3214da34-1e83-48ac-a374-c48ae52f7578.png"><img src="https://pic.yupi.icu/1/1736830970551-3214da34-1e83-48ac-a374-c48ae52f7578.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">9)给团队添加一位成员,设置角色为 “编辑者”</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736831952958-9030ae41-01a7-4bb7-9631-285886fa9595.png"><img src="https://pic.yupi.icu/1/1736831952958-9030ae41-01a7-4bb7-9631-285886fa9595.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">10)给团队空间上传一张图片,然后让 2 名成员同时进入编辑:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736832289546-bc9214e7-8ff6-4e5c-b11a-d3dd40dd07ec.png"><img src="https://pic.yupi.icu/1/1736832289546-bc9214e7-8ff6-4e5c-b11a-d3dd40dd07ec.png"></span></p>
<p class="md-end-block md-p"><span class="md-plain">如果编辑时,图片无法正常加载,可能是因为对象存储没有配置跨域,补充配置即可。</span></p>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">七、扩展知识</span></h2>
<p class="md-end-block md-p"><span class="md-plain">再分享一种更快部署后端的方法,可以利用 Docker + Docker Compose 快速部署后端依赖和后端项目本身。</span></p>
<p class="md-end-block md-p"><span class="md-plain">可以把 Docker 容器技术理解为安装操作系统时的镜像、或者安装 APP 时的安装包,只要定义好 Docker 配置文件,就能快速基于配置启动服务或项目。</span></p>
<p class="md-end-block md-p"><span class="md-plain">而 Docker Compose 可以组合编排多个 Docker 容器,按照顺序快速启动多个服务或项目。</span></p>
<p class="md-end-block md-p"><span class="md-plain">给大家提供一个示例的 Docker Compose 配置文件,定义了 MySQL、Redis 和 Spring Boot 项目的启动,大家可以基于这个文件进行定制修改:</span></p>
<pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-comment"># Docker Compose 文件,用于 Spring Boot 项目,依赖 MySQL 和 Redis<br><span><span>​<br><span><span class="cm-atom">version<span class="cm-meta">:&nbsp;<span class="cm-string">'3.8'<br><span><span>​<br><span><span class="cm-atom">services<span class="cm-meta">:<br><span><span>​<br><span>&nbsp;<span class="cm-comment"># MySQL 数据库服务<br><span><span class="cm-atom">mysql<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; image<span class="cm-meta">:&nbsp;mysql<span class="cm-meta">:<span class="cm-number">8.0<br><span><span class="cm-atom">&nbsp; container_name<span class="cm-meta">:&nbsp;mysql_db<br><span><span class="cm-atom">&nbsp; restart<span class="cm-meta">:&nbsp;always<br><span><span class="cm-atom">&nbsp; environment<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; &nbsp; MYSQL_ROOT_PASSWORD<span class="cm-meta">:&nbsp;root &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="cm-comment"># 设置 MySQL root 用户的密码<br><span><span class="cm-atom">&nbsp; &nbsp; MYSQL_DATABASE<span class="cm-meta">:&nbsp;yu_picture &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 更新为 yu_picture 数据库<br><span><span class="cm-atom">&nbsp; &nbsp; MYSQL_USER<span class="cm-meta">:&nbsp;root &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 更新为 root 用户<br><span><span class="cm-atom">&nbsp; &nbsp; MYSQL_PASSWORD<span class="cm-meta">:&nbsp;123456 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 更新为 123456 密码<br><span><span class="cm-atom">&nbsp; &nbsp; TZ<span class="cm-meta">:&nbsp;Asia/Shanghai &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 设置时区为东八区<br><span><span class="cm-atom">&nbsp; ports<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;<span class="cm-string">"3306:3306"&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="cm-comment"># 映射 MySQL 端口到主机<br><span><span class="cm-atom">&nbsp; volumes<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;mysql_data:/var/lib/mysql &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="cm-comment"># 数据持久化到宿主机(使用 Docker 管理的命名卷)<br><span><span class="cm-atom">&nbsp; command<span class="cm-meta">:&nbsp;--default-authentication-plugin=mysql_native_password<br><span><span>​<br><span>&nbsp;<span class="cm-comment"># Redis 缓存服务<br><span><span class="cm-atom">redis<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; image<span class="cm-meta">:&nbsp;redis<span class="cm-meta">:<span class="cm-number">5.0<br><span><span class="cm-atom">&nbsp; container_name<span class="cm-meta">:&nbsp;redis_cache<br><span><span class="cm-atom">&nbsp; restart<span class="cm-meta">:&nbsp;always<br><span><span class="cm-atom">&nbsp; ports<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;<span class="cm-string">"6379:6379"&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 映射 Redis 端口到主机<br><span><span class="cm-atom">&nbsp; volumes<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;redis_data:/data &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 数据持久化到宿主机(使用 Docker 管理的命名卷)<br><span><span class="cm-atom">&nbsp; environment<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; &nbsp; TZ<span class="cm-meta">:&nbsp;Asia/Shanghai &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 设置时区为东八区<br><span><span>​<br><span>&nbsp;<span class="cm-comment"># Spring Boot 应用服务<br><span><span class="cm-atom">springboot_app<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; image<span class="cm-meta">:&nbsp;openjdk<span class="cm-meta">:11-jre-slim<br><span><span class="cm-atom">&nbsp; container_name<span class="cm-meta">:&nbsp;springboot_app<br><span><span class="cm-atom">&nbsp; working_dir<span class="cm-meta">:&nbsp;/app<br><span><span class="cm-atom">&nbsp; volumes<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;.:/app &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 挂载本地目录到容器中<br><span><span class="cm-atom">&nbsp; ports<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;<span class="cm-string">"8123:8123"&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="cm-comment"># 映射 Spring Boot 端口到主机<br><span><span class="cm-atom">&nbsp; environment<span class="cm-meta">:<br><span><span class="cm-atom">&nbsp; &nbsp; TZ<span class="cm-meta">:&nbsp;Asia/Shanghai &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="cm-comment"># 设置时区为东八区<br><span><span class="cm-atom">&nbsp; command<span class="cm-meta">: [&nbsp;<span class="cm-string">"java"<span class="cm-meta">,&nbsp;<span class="cm-string">"-jar"<span class="cm-meta">,&nbsp;<span class="cm-string">"target/yu-picture-backend-0.0.1-SNAPSHOT.jar"<span class="cm-meta">,&nbsp;<span class="cm-string">"--spring.profiles.active=prod"&nbsp;<span class="cm-meta">]&nbsp;&nbsp;<span class="cm-comment"># 使用 prod 配置文件启动 Spring Boot 应用<br><span><span class="cm-atom">&nbsp; depends_on<span class="cm-meta">:<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;mysql<br><span><span class="cm-meta">&nbsp; &nbsp; -&nbsp;redis<br><span><span>​<br><span><span class="cm-comment"># 使用 Docker 管理的命名卷<br><span><span class="cm-atom">volumes<span class="cm-meta">:<br><span><span class="cm-atom">mysql_data<span class="cm-meta">:<br><span><span class="cm-atom">redis_data<span class="cm-meta">:</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p class="md-end-block md-p"><span class="md-plain">有了配置文件后,就可以利用宝塔面板自带的 Docker 能力,去进行项目的部署了,感兴趣的同学可以尝试一下:</span></p>
<p class="md-end-block md-p"><span class="md-image md-img-loaded" data-src="https://pic.yupi.icu/1/1736832698314-27471300-dadd-4683-9bef-9439fd818dec.png"><img src="https://pic.yupi.icu/1/1736832698314-27471300-dadd-4683-9bef-9439fd818dec.png"></span></p>
<blockquote>
<p class="md-end-block md-p"><span class="md-plain">在鱼皮编程导航的 <span class="md-meta-i-cmd-link"><span class="md-plain">OJ 在线判题项目教程</span><span class="md-plain"> 中,讲解过基于 Docker + Docker Compose 快速部署微服务项目的方法,视频地址:<span class="md-link md-pair-s">https://www.bilibili.com/video/BV1Cp4y1F7eA</span></span></span></span></p>
</blockquote>
<p class="md-end-block md-p">&nbsp;</p>
<h2 class="md-end-block md-heading"><span class="md-plain">最后</span></h2>
<p class="md-end-block md-p"><span class="md-plain">至此,整个项目已经完成上线,希望大家能通过这个项目掌握企业级项目的开发、优化和上线方法,得到全方面编程技能和程序员素养的提升。</span></p>
<h2 class="md-end-block md-heading"><span class="md-plain">更多编程学习资源</span></h2>
<ul class="ul-list" data-mark="-">
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">Java前端程序员必做项目实战教程+毕设网站</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">程序员免费编程学习交流社区(自学必备)</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">程序员保姆级求职写简历指南(找工作必备)</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">程序员免费面试刷题网站工具(找工作必备)</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新Java零基础入门学习路线 + Java教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新Python零基础入门学习路线 + Python教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新前端零基础入门学习路线 + 前端教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新数据结构和算法零基础入门学习路线 + 算法教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新C++零基础入门学习路线、C++教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新数据库零基础入门学习路线 + 数据库教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新Redis零基础入门学习路线 + Redis教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新计算机基础入门学习路线 + 计算机基础教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新小程序入门学习路线 + 小程序开发教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新SQL零基础入门学习路线 + SQL教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新Linux零基础入门学习路线 + Linux教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新Git/GitHub零基础入门学习路线 + Git教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新操作系统零基础入门学习路线 + 操作系统教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新计算机网络零基础入门学习路线 + 计算机网络教程</span></span></p>
</li>
<li class="md-list-item">
<p class="md-end-block md-p"><span class="md-meta-i-cmd-link"><span class="md-plain">最新设计模式零基础入门学习路线 + 设计模式教程</span></span></p>
</li>
<li class="md-list-item md-focus-container">
<p class="md-end-block md-p md-focus"><span class="md-meta-i-c md-link md-expand"><span class="md-plain">最新软件工程零基础入门学习路线 + 软件工程教程</span></span></p>
</li>
</ul><br><br>
来源:https://www.cnblogs.com/yupi/p/18675359
頁: [1]
查看完整版本: 我干了两个月的大项目,开源了!