本文是为初入前端、后端的小伙伴们准备的保姆级教程,也是我在学习中慢慢摸索出的一套基本流程,内容可能会有不正确的地方,欢迎在评论区指正,作者会持续关注错误之处,并完善这份文档。
目录
前言
本文给出的是基于Linux服务器
、SpringBoot后端技术栈
和Java运行环境
的Docker
部署方案,这样的部署方案在第一次的配置之后,可以做到非常方便的重新部署,只需要将新的jar
包上传到文件夹,并在终端执行四段运行代码即可,相较于传统的Java
或Tomcat
部署方案,其运行环境相对独立
,不会干扰服务器本身的运行环境,并且理论上可以在同一台服务器上部署非常多的后端系统,而不会相互干扰。
服务器准备
1.准备一个云服务器或者本地Linux服务器
这是一些云服务器厂商的官网:腾讯云官网 阿里云官网 华为云官网,各位自行按需选择,并且给服务器安装好Linux系统,建议Linux系统版本选择Centos7.x,对宝塔面板的兼容性更好,如果自己在本地配置Linux服务器,则需要自行配置好各项硬件和软件。
2.为服务器安装宝塔面板
进入宝塔面板官网,按照其中的教程给服务器安装宝塔面板,建议使用在线安装
,输入服务器的IP、账号和密码,直接一键安装,安装时建议勾选安装MySQL
和Nginx
,其余的可以自行选择安装与否。安装好宝塔面板后,需要确认各端口是否已开启,例如宝塔面板的默认端口、MySQL的默认端口等,并且别忘了把要部署的后端接口
也打开,如果没有开启,需要先在服务器的控制台中开启,再在宝塔面板的安全
中开启,也就是说服务器本身有一道防火墙,宝塔面板也提供了一道防火墙,两道防火墙都开启,才可以正常访问对应的服务。
3.在服务器中安装Docker并下载镜像
在宝塔面板中点击Docker
菜单,如果没有安装过Docker,则会显示安装提示,可以直接点击一键安装(比较省心),也可以在Docker官网中使用脚本方法进行安装(更复杂)。Docker安装完成之后,点开Docker菜单可以看到类似下面这样的页面:
在镜像
页面中,点击搜索镜像
,输入java8
,点击搜索,选择图中框选的镜像进行拉取
,这个镜像是用来构建必要的Java环境。
4.安装Redis
由于RuoYi后端系统需要使用Redis,所以需要在软件商店
菜单中搜索下载Redis,一般选择最新版本直接安装即可。安装好后的页面类似下面这样:
5.配置数据库
首先,配置MySQL数据库,点击数据库
菜单,在MySQL
面板中点击添加数据库
,按照要求创建好数据库,再点击权限
,将权限修改为所有人
。之后使用数据库管理软件,例如Navicat
等,分别运行RuoYi源代码中的sql
文件夹下的两个数据库文件,向数据库中添加RuoYi系统运行时需要的表。
注意,这一步会
增加服务器被攻击的风险
,但是这样是为了在使用Docker部署RuoYi后端时,Docker中的后端系统可以正常访问到MySQL数据库,如果不这样设置,由于Docker类似于虚拟机,是独立运行在服务器中的,二者的网络环境是不直接相通的,Docker内的SpringBoot项目无法直接连接到宿主机上运行的MySQL数据库,最终导致项目无法启动。
虽然可以使用其他方式将Docker的网络环境直接与宿主机相通,但是这样会导致Docker的可移植性变差,且仍然会带来安全风险。
具体其他配置方式,可以在附录
中参考由GPT4生成的其他方式
。
接下来,配置Redis,点击软件商店
,在Redis
一行点击设置
,在配置文件
面板中对Redis配置进行修改,首先将第69
行的bind 127.0.0.1
改为:bind 0.0.0.0
,之后将第508
行的requirepass
后面的单词删掉,改为自己的密码,一定要设置的复杂一些
。
注意,这里同样会带来
安全风险
,这一步操作和MySQL一样,将Redis暴露在公网
上了,但是不这样做,Docker中的项目就无法使用宿主机的Redis,所以密码一定要设置的足够复杂,尽量减少服务器被攻击的风险。
6.修改项目文件
由于要部署的项目为RuoYi
后端系统,使用了MySQL
和Redis
,必须还要对后端程序做修改,修改Redis的连接地址和MySQL数据库的连接地址,找到ruoyi-admin\src\main\resources\application.yml
这个文件,修改其中的Redis地址和密码:
# redis 配置
redis:
# Redis地址
host: 服务器IP地址
# 端口,默认为6379
port: 6379
# 密码
password: 刚刚设置的密码
找到ruoyi-admin\src\main\resources\application-druid.yml
这个文件,修改其中的MySQL地址和密码
# 主库数据源
master:
url: 服务器数据库地址
username: 用户名
password: 密码
即便Redis、MySQL、RuoYi都运行在同一个服务器中,也不能使用localhost,而是完整写出服务器的地址,这样才可以让容器中运行的RuoYi连接到容器外的Redis和MySQL,原因请看
第5点
的提示。
开始部署
1.创建docker_files文件夹
在部署后端时,因为部署思路是以Java镜像为底,制作一个SpringBoot项目镜像,也就是Docker容器中运行Java,Java中运行jar
包,所以首先在根目录中创建一个docker_files
文件夹,用于放置jar
包和镜像创建文件
:
2.上传jar包和创建镜像文件
文件夹中上传打包好的jar
包,即图中的ruoyi-admin.jar
:
创建一个txt
文件,文件中粘贴如下代码:
FROM openwhisk/java8action
MAINTAINER psr <13404802234@163.com>
ADD ruoyi-admim.jar app.jar
CMD java -jar app.jar
代码含义:
第一行,以openwhisk/java8action
镜像为底创建新镜像;
第二行,定义镜像的作者和联系方式(可不写);
第三行,添加jar
包,并把jar
包名字改为app.jar
,注意要匹配上传的jar
包的文件名
;
第四行,使用CMD指令运行jar
包。
3.创建Docker镜像
在服务器终端
中分步
运行如下命令:
cd ../
cd docker_files
docker build -f ./springboot_dockerfile.txt -t bdosr-backend-ruoyi .
代码含义:
第一行,到根目录
;
第三行,到docker_files
文件夹;
第五行,创建镜像,镜像配置文件为此目录下的springboot_dockerfile文件
,并且创建的镜像名字为bdosr-backend-ruoyi
,版本为latest
(注意最后面别忘了那个.
)。
运行完成后即可在Docker页面中看到刚刚创建的镜像:
4.运行Docker容器
在服务器终端中运行如下命令:
docker run -d --name bdosr-backend-ruoyi -p 10000:8080 bdosr-backend-ruoyi
代码含义:
运行一个Docker容器,容器的名为bdosr-backend-ruoyi
,之后将容器的8080
端口映射到10000
端口,使用的镜像名为bdosr-backend-ruoyi
5.部署完成
如图方式点击日志
后,可以查看容器的运行日志,可以看到,容器日志和控制台输出是一样的,至此后端的Docker部署就完成了。
重新部署
当修改SpringBoot项目程序后,就需要重新部署服务,而经过第一遍的配置之后,重新部署变得非常容易,熟练之后,操作会非常迅速。
1.删除容器和镜像
在Docker页面,点击容器
,删除旧的容器,再点击镜像
,删除旧的镜像(先删容器,后删镜像):
2.重新上传jar包并运行指令
将docker_files
文件夹内的旧jar
包删除,之后上传新的jar
包,再到终端中重新运行这四条命令即可:
cd ../
cd docker_files
docker build -f ./springboot_dockerfile.txt -t bdosr-backend-ruoyi .
docker run -d --name bdosr-backend-ruoyi -p 10000:8080 bdosr-backend-ruoyi
附录
Docker容器设计为轻量级的、可移植的执行环境,它们与宿主机
(即运行Docker的服务器)之间相对隔离。但Docker提供了几种方式来允许容器与宿主机或外部世界通信,包括访问宿主机端口。
如果你的Java程序运行在Docker容器中,并且你希望它能够访问运行它的服务器(宿主机)上的MySQL服务,通常有以下几种方法:
1. 使用特殊的DNS名host.docker.internal
Docker为容器提供了一个特殊的DNS名host.docker.internal
,这个DNS名解析为宿主机的IP地址。所以,如果你的MySQL服务运行在宿主机的3306端口上,你可以在容器中的Java程序配置数据库连接为host.docker.internal:3306
。
这种方法主要适用于Docker for Windows和Docker for Mac环境。在Linux环境下,这个特性可能不是默认可用的,取决于你的Docker版本和配置。
要在Linux服务器上使用host.docker.internal
,你可能需要确保Docker的版本至少为20.04或更高,并且在启动Docker容器时,通过添加特定的DNS选项来显式启用对host.docker.internal
的支持。这通常通过使用--add-host
标志来实现。
以下是一个示例命令,它在运行Docker容器时添加了host.docker.internal
:
docker run --add-host=host.docker.internal:host-gateway <其他选项> <镜像名>
这里,
host-gateway
是一个特殊的Docker内部标识,用于自动解析到宿主机的IP地址。
同时,你还应注意以下问题:
- Docker版本:确保你的Docker版本至少为20.04。你可以通过运行
docker --version
来检查当前安装的版本。- 配置:使用
--add-host=host.docker.internal:host-gateway
标志运行你的容器。这将确保host.docker.internal
可以在容器内部解析到宿主机的IP地址。- 网络模式:当使用自定义网络模式(非默认bridge模式)时,确保理解如何影响容器内部和宿主机之间的通信。
- 安全性和隔离:尽管这种方法提供了一个方便的方式来让容器访问宿主机的服务,但它也可能引入安全风险。确保评估使用此方法的潜在安全影响。
- 环境差异:由于Linux和Docker Desktop(Windows和Mac)之间的行为差异,开发和部署时请考虑环境的一致性和可移植性。
通过遵循上述步骤和考虑,你应该能够在Linux环境中成功使用host.docker.internal
来让Docker容器访问宿主机上的服务。
2. 使用宿主机的网络
通过让容器使用宿主机的网络命名空间,容器可以直接访问宿主机上的网络接口和端口。这可以通过在运行容器时添加--network="host"
参数来实现。例如:
docker run --network="host" my-java-app
使用这种方法时,容器将不会有自己的IP地址,而是直接使用宿主机的网络。这意味着你可以像在宿主机上运行程序一样直接使用localhost:3306
来访问MySQL服务。
3. 端口映射
虽然这种方法主要用于将容器内部的端口暴露给宿主机或外部网络,但如果你的服务同时监听宿主机的网络接口(不仅仅是localhost
),你也可以通过宿主机的IP地址或者0.0.0.0:3306
(意味着所有可用接口)来从容器内部访问服务。
确保你的MySQL服务配置为监听所有网络接口(或者宿主机的特定外部IP),然后你可以使用宿主机的IP地址从容器内部进行连接。
注意事项:
- 安全性:使用
--network="host"
模式或配置服务监听所有网络接口会增加安全风险,因为它减少了隔离并可能使服务面对更广泛的网络攻击。确保了解这些变更带来的潜在安全影响。- 可移植性:直接依赖宿主机的网络配置可能会减少容器的可移植性。尽量使用Docker内建的网络抽象和服务发现机制来保持容器的独立性和可移植性。
在Linux环境中,使用host.docker.internal
来指向宿主机的功能并不总是默认可用,这与Docker Desktop for Mac和Windows版本的行为不同。然而,从Docker 20.04版本开始,Docker引入了更多的网络特性和改进,包括对host.docker.internal
在Linux环境中的支持,但这可能需要额外的配置步骤。