服务器:远程服务器实例 比如某为的服务器
项目:后端是springboot比较复杂的模块结构,管理依赖的模块A,服务模块B,系统模块C,模块C下面又有子模块D,等等。前端是Vue3 + element-plus 的项目。
打包方式:利用docker。远程服务器先安装docker,然后利用docker安装redis,mysql,nginx,利用docker打包后端项目。前端的话交给nginx,不用docker创建前端实例了,因为有了nginx,前端相当于静态资源了。
说明:项目先在本地启动正常,然后可以正常打包成jar包。无论后端多复杂的模块,其实部署的时候只需要用到运行模块下面的jar包就行了。比如我的启动类在B模块,那么就是需要B模块下的target文件里面的jar文件。因为利用docker部署容器,而且我们配置的时候选择容器名而不是ip地址,所以创建的容器需要加入一个相当于docker内部的内网my-network,这样才能被识别,互相通信。还有就是远程实例申请的域名还没有审批下来,只能是先用远程ip来部署。后续申请下来后,会改为域名部署。
1.远程linux服务器安装docker
服务器是自己在某为买了,一年,几十块钱,比较划算。
以下是 Ubuntu 系统安装 Docker 的详细步骤(基于官方仓库,稳定可靠),涵盖环境准备、安装、验证及优化配置
1)前置准备:卸载旧版本(若有,新系统直接跳过)
sudo apt remove docker docker-engine docker.io containerd runc
sudo apt purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
2)更新系统包索引
sudo apt update
sudo apt upgrade -y # 可选,更新系统已安装包(耗时稍长)
3)安装依赖包
sudo apt install -y ca-certificates curl gnupg lsb-release
4)添加 Docker 官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
5)添加 Docker 官方软件源
echo
"deb [arch=(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ (lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
6)再次更新包索引
sudo apt update
7)安装 Docker 引擎(CE 社区版)
安装 Docker 核心组件(docker-ce、containerd 等)
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
8)启动 Docker 服务并设置开机自启
确保 Docker 随系统启动,无需手动干预:
sudo systemctl start docker # 启动服务
sudo systemctl enable docker # 开机自启
sudo systemctl status docker # 检查状态(应显示 active (running))
9)运行 Hello World 镜像
测试 Docker 核心功能是否正常
sudo docker run hello-world
运行如下图:
10)配置国内镜像源(加速拉取)
默认需 sudo 执行 Docker 命令,可将当前用户加入 docker 组
sudo usermod -aG docker $USER # 将当前用户加入 docker 组
newgrp docker # 立即生效(或重新登录终端)
这样命令前不用加sudo了。
docker run hello-world
配置国内镜像加速拉取:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com"]
}
EOF
sudo systemctl daemon-reload # 重载配置
sudo systemctl restart docker # 重启服务生效
11)验证安装:
查看 Docker 版本:
docker --version
列出运行中容器:
docker ps
2.远程linux服务器安装nginx
1)创建挂载目录
先说明NGINX的目录的作用:
/work/nginx/conf.d 用于存放配置文件
/work/nginx/html 用于存放网页文件
/work/nginx/logs 用于存放日志
/work/nginx/cert 用于存放 HTTPS 证书
排查错误日志的时候,可以就到这个work/nginx/logs里面找日志文件排查。
先创建network,方便后续容器启动直接加入。(想要使用容器名字代替ip,必须让docker中的容器实例都加入同一个网络。)
docker network create my-network
创建 /work/nginx 目录,并在该目录下新建 nginx.conf 文件,避免稍后安装 Nginx 报错。内容如下:
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# access_log /var/log/nginx/access.log main;
gzip on;
gzip_min_length 1k; # 设置允许压缩的页面最小字节数
gzip_buffers 4 16k; # 用来存储 gzip 的压缩结果
gzip_http_version 1.1; # 识别 HTTP 协议版本
gzip_comp_level 2; # 设置 gzip 的压缩比 1-9。1 压缩比最小但最快,而 9 相反
gzip_types text/plain application/x-javascript text/css application/xml application/javascript; # 指定压缩类型
gzip_proxied any; # 无论后端服务器的 headers 头返回什么信息,都无条件启用压缩
include /etc/nginx/conf.d/*.conf; ## 加载该目录下的其它 Nginx 配置文件
}
2)启动nginx
docker run -d --name nginx --network my-network --restart always -p 80:80 -p 443:443 -e "TZ=Asia/Shanghai" -v /work/nginx/nginx.conf:/etc/nginx/nginx.conf -v /work/nginx/conf.d:/etc/nginx/conf.d -v /work/nginx/logs:/var/log/nginx -v /work/nginx/cert:/etc/nginx/cert -v /work/projects/yudao-ui-admin:/usr/share/nginx/html
注意上述代码中的 -v /work/projects/yudao-ui-admin:/usr/share/nginx/html 这个的意思是把前者(相当于物理存储地址)映射到后者(运行内存),前者需要是上传的前端的项目的根目录,后者需要是nginx的配置里面前端配置的地址,这样NGINX在加载前端的资源的之后,会先找到/usr/share/nginx/html,然后根据这个映射找到/work/projects/yudao-ui-admin,假如我们就把前端的资源放在这个/work/projects/yudao-ui-admin目录下,那么就会成功找到,加载前端资源了。所以实际地址需要你根据你上传的前端项目地址来配置。后面部署前端的时候我们会再次提到这点。
3)执行 docker ps 命令,查看到 Nginx 容器的状态是 UP 的。
3.远程linux服务器安装redis
redis安装比较简单:
docker run -d --name redis-server --network my-network --restart=always -p 6379:6379 m.daocloud.io/docker.io/redis
注意这个--name 后面的redis-server就是启动的redis容器的名字,所以后端在打包的时候,在yml配置中,redis要写这个redis-server,不是localhost也不是ip地址。如下图所示:
4.远程linux服务器安装mysql
1.先创建sql目录,然后把本地的需要初始化数据库的sql文件上传到远程服务器,可以使用scp。
mkdir /home/sql
scp C:/local/test.sql user@192.1.1.80:/home/sql
注意第一个创建目录是在远程服务器操作。第二个命令是在本地windows系统上面,打开powershell操作。把本地的sql文件上传到服务器,user@ip地址需要换成自己服务器的真实的user(比如root)和远程服务器的ip地址。
2.启动mysql
docker run -v /work/mysql/:/var/lib/mysql -v /home/sql/test.sql:/docker-entrypoint-initdb.d/init.sql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --restart=always --name mysql --network my-network -d m.daocloud.io/docker.io/mysql
注意上面命令/home/sql/test.sql要换成自己的实际的sql文件地址和sql文件名字,--name 后面的mysql是容器启动的名字,这样的话,就需要后端的yml配置中,把mysql的地址ip改为mysql这个名字。如下图:
启动成功后可以参考如下命令查看是否创建数据库成功以及数据是否初始化:
查看mysql的数据
docker exec -it mysql bash
mysql -u root -p
-- 查看所有数据库
SHOW DATABASES;
-- 使用指定数据库(例如 ruoyi-vue-pro)
USE ruoyi-vue-pro;
-- 查看数据库中的表
SHOW TABLES;
-- 查看表结构
DESCRIBE 表名;
-- 查询表中的数据(示例:查询用户表)
SELECT * FROM sys_user LIMIT 10;
退出:
exit;
exit;
5.远程linux服务器部署后端
1.如前面所说,需要项目现在本地运行成功,并且可以正常打包。yml配置中,redis和mysql需要在对应的yml文件(比如dev.yml)改成你在远程docker里面启动时的实例的名称而不是ip地址。
打包命令如下:
mvn clean package '-Dmaven.test.skip=true' -Pdev #如果是打包dev环境
mvn clean package '-Dmaven.test.skip=true' -Pprod #如果是打包prod环境
mvn clean package '-Dmaven.test.skip=true' -Plocal #如果是打包local环境
2.上传打包好的jar包到远程服务器实例
先在linux服务器创建jar包目录
mkdir --parents /work/projects/yudao-server
利用scp上传本地jar包到新建的远程目录
在本地的windows系统打开powershell 运行如下命令
scp D:\softs\ruoyi-vue-pro\yudao-server\target\yudao-server.jar root@13.84.296.124:/work/projects/yudao-server
注意上述命令中,jar包地址为多模块项目中,包含启动类的主模块的jar包的地址。root@ip需要替换成自己的真实的角色和远程服务器实例的ip。
3.在 /work/projects/yudao-server 目录下,新建 Dockerfile 文件
先确保已进入 /work/projects/yudao-server 目录
cd /work/projects/yudao-server
使用 vim 新建并编辑 Dockerfile
vim Dockerfile
按 i 键进入编辑模式,输入 Dockerfile 内容(比如基于 Java 项目的模板,可参考你提供的资料按需修改 ):
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
## 感谢复旦核博士的建议!灰子哥,牛皮!
FROM m.daocloud.io/docker.io/eclipse-temurin:8-jre
## 创建目录,并使用它作为工作目录
RUN mkdir -p /yudao-server
WORKDIR /yudao-server
## 将后端项目的 Jar 文件,复制到镜像中
COPY yudao-server.jar app.jar
## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms512m -Xmx512m"
## 暴露后端项目的 48080 端口
EXPOSE 48080
## 启动后端项目
ENTRYPOINT java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar
按 Esc 键,输入 :wq 并回车,即可保存创建好的 Dockerfile 文件。
4.执行如下命令,构建名字为 yudao-server 的 Docker 镜像
cd /work/projects/yudao-server
docker build -t yudao-server .
注意最后面有个 .
5.在 /work/projects/yudao-server 目录下,新建 Shell 脚本 deploy.sh,使用 Docker 启动后端项目。编写内容如下:
#!/bin/bash
set -e
###### 第一步:删除可能启动的老 yudao-server 容器
echo "开始删除 yudao-server 容器"
docker stop yudao-server || true
docker rm yudao-server || true
echo "完成删除 yudao-server 容器"
## 第二步:启动新的 yudao-server 容器 \
echo "开始启动 yudao-server 容器"
docker run -d \
--name yudao-server \
-p 48080:48080 \
--network my-network \
-e "SPRING_PROFILES_ACTIVE=dev" \
-v /work/projects/yudao-server:/root/logs/ \
yudao-server
echo "正在启动 yudao-server 容器中,需要等待 60 秒左右"
- 用日志文件,挂载到服务器的的
/work/projects/yudao-server
目录下 - 通过
SPRING_PROFILES_ACTIVE
设置为dev
开发环境
6.启动后端项目:
执行 sh deploy.sh 命令,使用 Docker 启动后端项目
chmod +x deploy.sh
sh deploy.sh
执行 docker logs yudao-server,查看启动日志。
注意,因为后端启动需要redis和mysql先启动,所以要按照顺序先把redis和mysql部署好,并且确认好启动命令都包含了加入my-network这个自定义网络中。
6.远程linux服务器部署前端
1.先修改前端的配置地址。假如要部署dev,则在.env.dev里面配置地址如下:
如上图就是把baseUrl改为远程linux服务器实例的真实的ip地址。
2.打包前端:
npm run build:dev
3.把dist文件上传到远程的华为服务器实例
先在远程服务器创建目录/work/projects/yudao-ui-admin
mkdir /work/projects/yudao-ui-admin
把前端打包好的dist文件上传到远程华为服务器实例
格式:scp -r 本地dist目录 用户名@服务器IP:目标目录
scp -r D:\softs\yudao-ui-admin-vue3\dist* root@14.924.20.114:/work/projects/yudao-ui-admin/
注意本地dist路径和远程服务器的角色以及地址需要改为你自己的哈。
4./work/nginx/conf.d 目录下,创建 ruoyi-vue-pro.conf,内容如下:
server {
listen 80;
server_name 13.29.296.47; ## 重要!!!修改成你的远程服务器实例真实ip地址
location / { ## 前端项目
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /admin-api/ { ## 后端项目 - 管理后台
proxy_pass http://yudao-server:48080/admin-api/; ## 重要!!!proxy_pass 需要设置为后端项目所在服务器的 IP
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /app-api/ { ## 后端项目 - 用户 App
proxy_pass http://yudao-server:48080/app-api/; ## 重要!!!proxy_pass 需要设置为后端项目所在服务器的 IP
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
创建命令如下:
sudo nano /work/nginx/conf.d/ruoyi-vue-pro.conf
在里面粘贴上上面的配置信息后,ctrl+o ,回车,ctrl+x,即可。
讲解下配置里的内容。配置nginx监听远程实例ip地址,前端的root配置的是root /usr/share/nginx/html,而结合我们最前面一开始配置的nginx, -v /work/projects/yudao-ui-admin:/usr/share/nginx/html 这个映射,那么有访问前端就会映射到/work/projects/yudao-ui-admin,而我们打包前端的时候,刚好就是把本地的dist文件里面的内容上传到了远程服务器的/work/projects/yudao-ui-admin 这个目录下,那么就会顺利找到了。而如果NGINX监听到了后端的配置规则有约定的admin-api和app-api的话,就会进入后端项目,后端项目中,proxy_pass http://yudao-server:48080/admin-api/ 这个配置的转发地址,其中yudao-server,就是我们在docker里面部署的后端的容器的名字。这样不用写ip,就可以docker内部通信了,因为都已经加入了自定义网络my-network。
5.配置好后,需要nginx重新加载下配置项,命令如下:
sudo nano /work/nginx/conf.d/ruoyi-vue-pro.conf
6.这样,整个项目就部署成功了。(前端、后端、nginx、redis,mysql)
我们登录下系统页面地址(输入远程服务器ip地址即可),如下访问成功:
注意,如果端口访问不通,可能是申请的远程服务器的端口80等没有开放,可以在规则里面配置,比如我买的某云的服务器,就是默认不开放,一开始导致访问不通。
后续如果域名申请下来,会在这里继续说下改动点,重新部署下。(新手小白,仅供参考)