上线项目的3种方式

环境准备

注意:使用哪种方式上线,就准备对应需要的环境

方式一、使用常规方式上线

  • Nginxjdk的安装与配置
    Nginx安装配置的参考链接:https://zhuanlan.zhihu.com/p/425790769
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     # nginx 默认配置
    user nginx;
    worker_processes auto;

    error_log /var/log/nginx/error.log notice;
    pid /var/run/nginx.pid;
    events {
    worker_connections 1024;
    }
    http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    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;
    sendfile on;
    #tcp_nopush on;

    keepalive_timeout 65;

    #gzip on;

    include /etc/nginx/conf.d/*.conf;
    }

    # 使用yum来安装jdk,免配置环境变量
    yum install -y java-1.8.0-openjdk*

方式二、使用宝塔面板上线

方式三、使用Docker容器上线

  • Docker的安装与配置
    参考链接:https://www.51cto.com/article/715012.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 打开配置文件
    vi /etc/docker/daemon.json
    # 原来的配置
    {
    "registry-mirrors": ["https://y5u7p3c7.mirror.aliyuncs.com"]
    }

    # 换用下面的配置,目前2024.08.18可用
    {
    "registry-mirrors": [
    "https://docker.m.daocloud.io"
    ]
    }

常见问题

1、需要更换yum源。参考链接:https://blog.csdn.net/qq_52545155/article/details/137229782

前端部署

普通上线

1、上传前端打包好的dist文件夹到服务器

一般都是直接使用本地的打包好的dist文件夹,如果想在服务器进行打包,可以使用npm run build命令,但是前提是需要在服务器进行安装nodenpm,可以参考这篇文章。专业安装NVM教程(链接待补充)

2、配置Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 首先进入 nginx 的配置文件目录
cd /usr/local/nginx/conf # 默认在/usr/local/nginx/conf, 也可能在 /etc/nginx
# 备份一份默认的配置文件,避免出现配置错误
cp nginx.conf nginx.conf.bak
# 编辑配置文件
vim nginx.conf
# 编写配置
## 需要改动的地方 1:更改启动用户名为root
#user nobody;
user root;
## 需要改动的地方 2:更改项目名以及遍历查找index.html
server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
# 将dist目录重命名为项目名(非必须,出于好进行管理)
root /root/services/smartapi-frontend;
index index.html index.htm;
# 增加一行可以遍历 root 多级目录的配置,如果没有配置只会在根目录中寻找
try_files $uri $uri/ /index.html;
}
}

跨域解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
location ^~ /api/ {
# 代理到后端服务
proxy_pass http://localhost:9000/api/;
add_header 'Access-Control-Allow-origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers '*';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-origin' $http_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-with,If-Modified-since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
}

3、重启Nginx

1
nginx -s reload

4、检查防火墙以及安全组是否开放端口,然后测试访问

宝塔面板

1、打开软件商店安装必须的环境:jdknginxmysql

2、打开网站菜单,添加站点

添加站点
3、进入站点目录,上传打包好的前端dist

4、测试访问(有需要的话,可以手动配置nginx的配置文件)

Docker容器

1、在服务器的根目录下创建一个services文件夹,然后创建对应的项目文件夹

2、使用git拉取后端项目源码,或者直接打包上传

3、在当前前端项目的根目录,创建一个Dockerfile文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
FROM nginx

WORKDIR /usr/share/nginx/html/
USER root

COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf

COPY ./dist /usr/share/nginx/html/

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

4、在前端项目根目录创建一个docker文件夹,然后创建一个nginx.conf配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 80;

# gzip config
gzip on;
gzip_min_length 1k;
gzip_comp_level 9;
gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";

root /usr/share/nginx/html;
include /etc/nginx/mime.types;

location / {
try_files $uri /index.html;
}
}

5、使用docker build命令构建镜像并运行

1
2
3
docker build -t smartapi-frontend .
docker run -d -p 80:80 --name xxx-frontend xxx-frontend
docker ps -a

6、测试访问

后端部署

普通上线

1、在本地使用Mavenjar包,或者在服务器使用git拉取源码,然后使用Maven命令打包

1
mvn clean package -Dmaven.test.skip=true

2、上传打包好的jar包到服务器

3、运行 jar 包,启动命令如下:

1
2
3
4
# 先以直观的模式启动
java -jar xxx-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
# 查看是否启动成功,若启动成功,然后再次运行jar包,以后台模式运行
java -jar xxx-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod > log.out 2>&1 &

宝塔面板

1、打开文件菜单,在www/wwwroot目录下创建一个services目录,再创建一个后端项目名字的文件夹,然后上传打包好的jar包到该目录下

2、打开网站文件夹
添加Java项目

1
2
# 项目的执行命令
/usr/bin/java -jar -Xmx1024M -Xms256M /www/wwwroot/user-center-backend/user-center-backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

3、测试是否启动成功

Docker容器

1、个人习惯在服务器的根目录下创建一个services文件夹,然后创建对应的项目文件夹

2、使用git拉取后端项目源码,或者直接打包上传

3、在当前项目根目录编写DockerFile

1
2
3
4
5
6
7
8
9
10
11
12
FROM maven:3.5-jdk-8-alpine as builder

# Copy local code to the container image.
WORKDIR /app
COPY pom.xml .
COPY src ./src

# Build a release artifact.
RUN mvn package -DskipTests

# Run the web service on container startup.
CMD ["java","-jar","/app/target/user-center-backend-0.0.1-SNAPSHOT.jar","--spring.profiles.active=prod"]

3、使用docker build命令构建镜像并运行

1
2
3
docker build -t user-center-backend:latest .
docker run -d -p 8080:8080 --name user-center-backend user-center-backend:latest
docker ps -a

4、测试是否启动成功

场景模拟

场景一:多war包部署

场景描述

在不影响服务器上正常运行的基础上,将多个war包部署到同一个服务器上,并使用nginx进行负载均衡。

解决方案

1、使用Docker:

  • 使用docker创建多个tomcat容器,分别部署多个war包,并使用nginx进行负载均衡。

2、不使用Docker:

  • 首先,复制一份tomcat

  • 进入到 tomcat 的目录下, 将其中的 webapps 文件夹进行一份拷贝, 用于第二个应用的部署

  • 进入到 tomcat 的服务配置文件下面, 打开 server.xml 配置文件, 填充第二个应用部署时的相关配置信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <!-- 第二个项目配置 -->
    <Service name="Catalina1">

    <!-- 为避免冲突, 修改端口 -->
    <Connector port="8081" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" />

    <!-- Tomcat默认使用8009端口, 避免冲突, 修改 -->
    <Connector port="8010" protocol="AJP/1.3" redirectPort="8443"/>

    <!-- Engine 节点, name 修改为 Catalina1 -->
    <!-- 服务启动后会在 conf 下生成相应的引擎文件夹, 名称保持一致. -->
    <Engine name="Catalina1" defaultHost="localhost">
    <Realm className="org.apache.catalina.realm.LockOutRealm">
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
    resourceName="UserDatabase"/>
    </Realm>

    <!-- 修改Host节点,appBase修改为需要进行发布的文件位置, 也就是第一步复制的 webapps1 -->
    <Host name="localhost" appBase="webapps1"
    unpackWARs="true" autoDeploy="true">

    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
    prefix="localhost_access_log" suffix=".txt"
    pattern="%h %l %u %t &quot;%r&quot; %s %b" />

    </Host>
    </Engine>
    </Service>
  • 配置nginx负载均衡,记得nginx -s reload

  • 脚本启动tomcat,记得start.sh

场景二:域名https访问

  1. 首先前端请求路径的baseurl改为https://hostname.com
  2. 在nginx配置文件中添加如下配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    # 定义 HTTP 服务器,重定向到 HTTPS
    server {
    listen 80;
    server_name hostname.com; # 服务器名称
    return 301 https://$server_name$request_uri; # 永久重定向到 HTTPS
    }
    # 定义 HTTPS 服务器
    server {
    listen 443 ssl; # 监听 443 端口,启用 SSL
    server_name hostname.com; # 服务器名称

    # SSL 证书路径
    ssl_certificate /path/to/cert/*.pem;
    ssl_certificate_key /path/to/cert/*.key;

    # SSL 会话缓存和超时时间
    ssl_session_timeout 5m;

    # SSL 密码套件和协议
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1.2 TLSv1.3; # 推荐使用 TLSv1.2 和 TLSv1.3
    ssl_prefer_server_ciphers on;

    # 静态文件请求处理
    location / {
    root html/frontend; # nginx目录的相对路径
    index index.html index.htm; # 默认索引文件
    try_files $uri $uri/ /index.html; # 尝试按顺序查找文件
    }

    # API 请求反向代理
    location ^~ /api/ {
    proxy_set_header X-Real-IP $remote_addr; # 设置真实的客户端 IP
    proxy_set_header Host $host; # 设置主机头
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 设置转发的客户端 IP
    proxy_set_header X-Forwarded-Proto $scheme; # 设置转发的协议
    proxy_pass http://127.0.0.1:3000/api/; # 反向代理到后端服务
    }

    # 其他请求反向代理
    location @backend {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://127.0.0.1:3000; # 反向代理到后端服务
    }

    # 错误页配置
    error_page 404 /404.html; # 自定义 404 错误页面
    error_page 502 /502.html; # 自定义 502 错误页面

    # 禁止访问的文件或目录
    location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {
    return 404; # 返回 404 错误
    }

    # 禁止在证书验证目录放入敏感文件
    if ($uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$") {
    return 403; # 返回 403 错误
    }

    # 设置静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|ttf|woff|woff2|eot|otf|pdf|mp4|webm|ogg|mp3|wav|flac|swf|xml|txt|csv|json)$ {
    expires 30d; # 设置过期时间为 30 天
    add_header Cache-Control "public, no-transform"; # 设置缓存控制头
    }

    # 设置访问日志和错误日志
    access_log /www/wwwlogs/hostname.com.log; # 访问日志路径
    error_log /www/wwwlogs/hostname.com.error.log; # 错误日志路径
    }

场景三:不用反向代理的兜底方案

pm2是什么:
PM2是一个进程管理工具,用于管理Node.js应用程序,它提供了许多功能,如自动重启、负载均衡、日志记录等。
使用pm2来托管 vue 项目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 安装pm2
npm install pm2 -g
# 启动项目
pm2 start node --name "serve" -- --experimental-modules ./node_modules/@vue/cli-service/bin/vue-cli-service.js serve
# 查看运行状态
pm2 list
# 停止项目
pm2 stop xx
# 重启项目
pm2 restart xx
# 设置开机自动启动
pm2 startup
# 停止开机自动启动
pm2 unstartup