相关推荐recommended
【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署
作者:mmseoamin日期:2024-04-27

本文是为初入前端、后端的小伙伴们准备的保姆级教程,也是我在学习中慢慢摸索出的一套基本流程,内容可能会有不正确的地方,欢迎在评论区指正,作者会持续关注错误之处,并完善这份文档。

目录

  • 前言
  • 服务器准备
    • 1.准备一个云服务器或者本地Linux服务器
    • 2.为服务器安装宝塔面板
    • 3.在服务器中安装Docker并下载镜像
    • 4.安装Redis
    • 5.配置数据库
    • 6.修改项目文件
    • 开始部署
      • 1.创建docker_files文件夹
      • 2.上传jar包和创建镜像文件
      • 3.创建Docker镜像
      • 4.运行Docker容器
      • 5.部署完成
      • 重新部署
        • 1.删除容器和镜像
        • 2.重新上传jar包并运行指令
        • 附录
          • 1. 使用特殊的DNS名host.docker.internal
          • 2. 使用宿主机的网络
          • 3. 端口映射

            前言

            本文给出的是基于Linux服务器、SpringBoot后端技术栈和Java运行环境的Docker部署方案,这样的部署方案在第一次的配置之后,可以做到非常方便的重新部署,只需要将新的jar包上传到文件夹,并在终端执行四段运行代码即可,相较于传统的Java或Tomcat部署方案,其运行环境相对独立,不会干扰服务器本身的运行环境,并且理论上可以在同一台服务器上部署非常多的后端系统,而不会相互干扰。


            服务器准备

            1.准备一个云服务器或者本地Linux服务器

            这是一些云服务器厂商的官网:腾讯云官网 阿里云官网 华为云官网,各位自行按需选择,并且给服务器安装好Linux系统,建议Linux系统版本选择Centos7.x,对宝塔面板的兼容性更好,如果自己在本地配置Linux服务器,则需要自行配置好各项硬件和软件。

            2.为服务器安装宝塔面板

            进入宝塔面板官网,按照其中的教程给服务器安装宝塔面板,建议使用在线安装,输入服务器的IP、账号和密码,直接一键安装,安装时建议勾选安装MySQL和Nginx,其余的可以自行选择安装与否。安装好宝塔面板后,需要确认各端口是否已开启,例如宝塔面板的默认端口、MySQL的默认端口等,并且别忘了把要部署的后端接口也打开,如果没有开启,需要先在服务器的控制台中开启,再在宝塔面板的安全中开启,也就是说服务器本身有一道防火墙,宝塔面板也提供了一道防火墙,两道防火墙都开启,才可以正常访问对应的服务。

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,服务器安装宝塔面板,第1张

            3.在服务器中安装Docker并下载镜像

            在宝塔面板中点击Docker菜单,如果没有安装过Docker,则会显示安装提示,可以直接点击一键安装(比较省心),也可以在Docker官网中使用脚本方法进行安装(更复杂)。Docker安装完成之后,点开Docker菜单可以看到类似下面这样的页面:

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,Docker安装完成,第2张

            镜像页面中,点击搜索镜像,输入java8,点击搜索,选择图中框选的镜像进行拉取,这个镜像是用来构建必要的Java环境。

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,下载镜像,第3张

            4.安装Redis

            由于RuoYi后端系统需要使用Redis,所以需要在软件商店菜单中搜索下载Redis,一般选择最新版本直接安装即可。安装好后的页面类似下面这样:

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,Redis安装完成,第4张

            5.配置数据库

            首先,配置MySQL数据库,点击数据库菜单,在MySQL面板中点击添加数据库,按照要求创建好数据库,再点击权限,将权限修改为所有人。之后使用数据库管理软件,例如Navicat等,分别运行RuoYi源代码中的sql文件夹下的两个数据库文件,向数据库中添加RuoYi系统运行时需要的表。

            注意,这一步会增加服务器被攻击的风险,但是这样是为了在使用Docker部署RuoYi后端时,Docker中的后端系统可以正常访问到MySQL数据库,如果不这样设置,由于Docker类似于虚拟机,是独立运行在服务器中的,二者的网络环境是不直接相通的,Docker内的SpringBoot项目无法直接连接到宿主机上运行的MySQL数据库,最终导致项目无法启动。

            虽然可以使用其他方式将Docker的网络环境直接与宿主机相通,但是这样会导致Docker的可移植性变差,且仍然会带来安全风险。

            具体其他配置方式,可以在附录中参考由GPT4生成的其他方式。

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,配置MySQL数据库,第5张

            接下来,配置Redis,点击软件商店,在Redis一行点击设置,在配置文件面板中对Redis配置进行修改,首先将第69行的bind 127.0.0.1改为:bind 0.0.0.0,之后将第508行的requirepass后面的单词删掉,改为自己的密码,一定要设置的复杂一些。

            注意,这里同样会带来安全风险,这一步操作和MySQL一样,将Redis暴露在公网上了,但是不这样做,Docker中的项目就无法使用宿主机的Redis,所以密码一定要设置的足够复杂,尽量减少服务器被攻击的风险。

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,配置Redis,第6张

            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包和镜像创建文件:

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,创建文件夹,第7张

            2.上传jar包和创建镜像文件

            文件夹中上传打包好的jar包,即图中的ruoyi-admin.jar:

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,放置jar包和创建文件,第8张

            创建一个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页面中看到刚刚创建的镜像:

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,镜像创建完成,第9张

            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后端项目在Linux服务器中使用宝塔面板进行Docker部署,在这里插入图片描述,第10张


            重新部署

            当修改SpringBoot项目程序后,就需要重新部署服务,而经过第一遍的配置之后,重新部署变得非常容易,熟练之后,操作会非常迅速。

            1.删除容器和镜像

            在Docker页面,点击容器,删除旧的容器,再点击镜像,删除旧的镜像(先删容器,后删镜像):

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,删除容器,第11张

            【保姆级教程】SpringBoot后端项目在Linux服务器中使用宝塔面板进行Docker部署,删除镜像,第12张

            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环境中的支持,但这可能需要额外的配置步骤。