跳转至

Vue3 + ASP.NET Web API 前后端部署

前言

服务器系统:Ubuntu 18.04

前端:Vue3 + Vite

后端:ASP.NET Web API

数据库:Oracle

前端

前端主要是要安装 node.js,用来执行前端代码,当然,也可以先使用 npm run build 打包后以后再上传到服务器上,即指上传打包后的 dist 文件,这样就不用再安装 node.js

安装 Node.js (可选)

首先,需要安装 Node.js。Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它允许在服务器上运行 JavaScript 代码。这是 Vue3 + Vite 项目所需的运行环境

检测是否安装成功:

npm -v
# 输出版本信息类似:9.5.0
node -v
# 输出版本信息类似:v18.15.0

如果上述命令未返回版本信息,说明需要安装 Node.js。可以在 Node.js 官方网站 下载适合的版本并安装

安装 nginx

Nginx 是一个高性能的 Web 服务器

更新软件包列表:

sudo apt update

安装 Nginx:

sudo apt install nginx

安装完成后,Nginx 服务会自动启动

验证 Nginx 是否已经安装成功:在浏览器地址栏中输入服务器的 IP 地址。如果一切正常,应该会看到 Nginx 的默认欢迎页面。

如果没有自动启动,你可以使用以下命令手动启动:

sudo systemctl start nginx

以下是是一些其他的关于 nginx 的命令

停止 Nginx 服务,完全停止 Nginx 服务,中断所有连接并释放端口:

sudo systemctl stop nginx

重启 Nginx 服务,重新启动 Nginx 服务:

sudo systemctl restart nginx 

查看 Nginx 服务状态,显示 Nginx 服务的状态、进程 ID 等信息:

sudo systemctl status nginx

重新加载 Nginx 配置,重新加载 Nginx 配置(常用于修改配置后重新加载):

sudo systemctl reload nginx

restart 是一个较为彻底的操作,会中断现有连接并重新启动整个 Nginx 服务实例。而 reload 则更轻量级,仅重新加载配置文件,使新配置生效,同时保持现有连接不受影响

上传文件到服务器

现在,我们将使用两种方式,本质上都是为了得到最终的 dist 文件

方式一:上传全部前端代码文件(要求安装 Node.js

这种方式的优点在于,如果需要对前端文件进行小幅更改,可以直接在服务器上修改,然后重新打包部署,而不必重新上传文件

首先,使用 scp 命令将所有前端代码文件上传到服务器。假设前端代码位于名为 front 的文件夹中,服务器 IP 地址为 124.220.110.93

scp -r front ubuntu@124.220.110.93:/home/ubuntu

接着,进入前端文件夹并进行打包操作:

cd /home/ubuntu/front
npm run build

执行完毕后,将在 front 目录下生成 dist 文件夹

方式二:仅上传打包后的 dist 文件

这种方式更加简便,只需上传经过打包的 dist 文件夹即可:

scp -r dist ubuntu@124.220.110.93:/home/ubuntu

无论你选择哪种方式,最终都会在服务器上获得一个包含 index.html 文件的 dist 文件夹,它将作为应用的入口。

修改 nginx 配置

现在,我们需要对 Nginx 配置文件进行一些修改,以确保应用能够正确访问。

首先,修改 Nginx 的用户权限。进入 Nginx 配置文件夹并编辑 nginx.conf 文件:

cd /etc/nginx
vim nginx.conf

在配置文件中找到 user 部分,将其修改为:

截屏2023-08-08 17.54.41

user ubuntu;  # 使用 root 也可以
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

接下来,进入 Nginx 的默认配置文件夹:

cd /etc/nginx/sites-available
vim default

在配置文件中,将服务器的根目录修改为 dist 文件夹的路径,并设置默认的 index.html 作为入口:

截屏2023-08-08 17.46.14

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /home/ubuntu/dist;

        index index.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
}

完成上述修改后,可以使用以下命令检查 Nginx 配置文件是否存在语法错误:

sudo nginx -t

如果语法正确,将会显示 "syntax is okay" 和 "test is successful"

最后,使用以下命令重新加载配置(请注意使用 restart 而不是 reload):

sudo systemctl restart nginx

现在,在浏览器中输入服务器的 IP 地址,即可查看到应用的内容!

如果遇到问题,可以使用以下命令查看 Nginx 报错日志:

sudo tail -n 50 /var/log/nginx/error.log

后端

后端部署时遇到的四个关键问题

  • 访问 swagger 是否开发模型 (取消)

  • docker 连接 oracle 时区问题

  • 服务器内可以使用 localhost 访问,而外网通过 IP+端口 无法访问

  • 可以通过 IP+端口访问 swageer,前端接口也正确,但仍然无法访问

以上四个问题将在下面逐一解决!

跨域问题

在前后端分离的应用中,由于前端和后端通常运行在不同的域名或端口下,会涉及到跨域访问的问题。为了解决跨域问题,需要在后端进行一些配置,以允许来自前端域的请求

后端配置的好处:方便

首先,安装 Microsoft.AspNet.WebApi.Cors 包:

dotnet add package Microsoft.AspNet.WebApi.Cors

然后,打开 Program.cs 文件,添加以下内容来配置跨域支持:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAllOrigins", builder =>
    {
        builder.AllowAnyOrigin() // 允许所有来源
               .AllowAnyHeader()
               .AllowAnyMethod();
    });
});

app.UseCors("AllowAllOrigins"); // 使用刚刚配置的跨域策略

截屏2023-08-10 11.54.33

开发模式和生产模式

ASP.NET 是一个跨平台的开发框架,用于构建 Web 应用程序、Web API 和其他类型的应用。在 ASP.NET 中,有两种常见的运行模式:开发模式(Development Mode)和生产模式(Production Mode),它们分别用于开发阶段和部署到生产环境中。

为了在生产模式下能够访问 swagger(这意味着通过 IP 能够访问 swagger,看到项目所有 API),需要修改 Program.cs 文件里的一处代码

原内容:

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

修改为:

// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI();

参考:https://www.cnblogs.com/cxxtreasure/p/14332484.html

安装 Docker

更新系统软件包列表:

sudo apt update

安装所需的软件包,以便允许使用 HTTPS 来通过 APT 下载软件包:

sudo apt install apt-transport-https ca-certificates curl software-properties-common

添加 Docker 官方 GPG 密钥:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

添加 Docker 的稳定版存储库:

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

安装 Docker Engine:

sudo apt install docker-ce docker-ce-cli containerd.io

启动 Docker 服务:

sudo systemctl start docker

验证 Docker 是否正确安装:

docker --version

如果显示了 Docker 的版本信息,说明 Docker 安装成功。

具体部署流程

后端我是使用 Docker 来进行部署,下面是正式的部署流程

首先在后端文件夹下创建一个 Dockerfile 文件,将以下内容复制到 Dockerfile 文件中,根据项目情况修改,可能需要修改的地方包括 xxx.csproj,用项目中对应的名称来替换 xxx,其他地方不用修改

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build


WORKDIR /src
COPY ["auth.csproj", "."]
RUN dotnet restore "./auth.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "auth.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "auth.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "auth.dll"]

# 设置容器时区
# 救命恩人:https://www.cnblogs.com/deali/p/15620364.html
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base: 这个语句从 Microsoft 的容器注册表中拉取一个名为 dotnet/aspnet 的镜像版本为 7.0,作为基础镜像。这个基础镜像预装了 ASP.NET Core 运行时环境。

WORKDIR /app: 这个语句设置容器内的当前工作目录为 /app,在该目录下进行后续的操作。

EXPOSE 80 和 EXPOSE 443: 这两个语句指定容器将会监听的网络端口,分别是 80 和 443。这是为了在容器内运行 ASP.NET Core 应用并暴露相应的 HTTP 和 HTTPS 端口。

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build: 这个语句从 Microsoft 的容器注册表中拉取一个名为 dotnet/sdk 的镜像版本为 7.0,作为用于构建应用的中间镜像。这个镜像预装了 .NET Core SDK,用于编译和构建应用程序。

WORKDIR /src: 这个语句设置容器内的当前工作目录为 /src,在该目录下进行后续的操作。

COPY ["auth.csproj", "."]: 这个语句将主机上的 auth.csproj 文件复制到容器内的当前工作目录。

RUN dotnet restore "./auth.csproj": 这个语句运行 dotnet restore 命令,以安装应用程序的依赖项。

COPY . .: 这个语句将主机上的所有文件和文件夹复制到容器内的当前工作目录。

WORKDIR "/src/.": 这个语句重新设置容器内的当前工作目录为 /src。

RUN dotnet build "auth.csproj" -c Release -o /app/build: 这个语句运行 dotnet build 命令,以在 Release 配置下编译应用程序,并将输出放置在 /app/build 目录中。

FROM build AS publish: 这个语句创建一个名为 publish 的阶段,从之前的 build 阶段构建而来。

RUN dotnet publish "auth.csproj" -c Release -o /app/publish /p:UseAppHost=false: 在 publish 阶段中,这个语句运行 dotnet publish 命令,以将应用程序发布到 /app/publish 目录中。/p:UseAppHost=false 参数用于禁用应用主机的生成。

FROM base AS final: 这个语句创建一个名为 final 的阶段,从之前的 base 阶段构建而来。

WORKDIR /app: 这个语句重新设置容器内的当前工作目录为 /app。

COPY --from=publish /app/publish .: 这个语句从之前的 publish 阶段复制已发布的应用程序文件到容器内的当前工作目录。

ENTRYPOINT ["dotnet", "auth.dll"]: 这个语句指定容器启动时执行的默认命令,即运行 auth.dll,这是 ASP.NET Core 应用程序的入口点。

ENV TZ=Asia/Shanghai 和 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone: 这两个语句设置容器的时区为亚洲/上海,并通过软链接将容器的时区设置为主机的时区,以确保容器内部时间与主机时间一致。

这个 Dockerfile 定义了一个多阶段构建过程,从基础镜像开始,经过编译和发布阶段,最终构建出一个运行 ASP.NET Core 应用的容器,并设置了容器的时区。

Dockerfile 中设置容器时区命令是为了解决访问 oracle 数据库时出现以下报错:

ORA-01882:timezone region not found

接下来,在后端文件夹下执行以下命令,创建一个名为 dbp-image 的镜像,版本号为1.0:

docker build -t dbp-image:v1.0 -f Dockerfile .

注意,docker 镜像的名称只能小写

在终端中,切换到后端应用文件夹,并执行以下命令,构建一个名为dbp-image的Docker镜像,版本号为1.0:

cd back
docker save dbp-image:v1.0 > dbp-image.tar

将构建好的Docker镜像保存为一个 .tar 文件,以备后续在服务器上加载使用:

docker save dbp-image:v1.0 > dbp-image.tar

这个命令将会根据 Dockerfile 的配置,从头开始构建一个包含我们应用程序的镜像

使用 scp 命令将保存的 Docker 镜像上传到服务器的指定目录 /home/ubuntu

scp -r dbp-image.tar ubuntu@124.220.110.93:/home/ubuntu

在服务器上,通过以下命令加载之前保存的Docker镜像:

cd /home/ubuntu
docker load < dbp-image.tar

最后,通过以下命令在服务器上运行我们的应用Docker镜像,并将容器的 80 端口映射到主机的 5045 端口:

docker run -p 5045:80 dbp-image:v1.0

如果通过 http://你的IP地址:5045/swagger/index.html 无法访问,检查服务器端口是否开放:

云服务器供应商端口是否开放:

5045 端口

截屏2023-08-10 11.49.53

服务器内部防火墙是否关闭:

1911691385328_.pic

部署

前端地址:http://124.220.110.93/

后端地址:http://124.220.110.93:5045/swagger/index.html

数据库

SQLDeveloper 连接 oracle 数据库

截屏2023-06-30 20.14.53

补充知识

静态服务:主要提供静态资源,不同用户访问到的资源相同

动态服务:提供动态服务,不同用户访问到的资源不同

服务器的几个叫法:

web服务器:广义上来说,就是响应用户的需求,提供服务,当下所有的服务器软件都可以称之为web服务器软件

HTTP服务器(静态服务):使用HTTP协议传输资源,提供服务

应用服务器(动态服务):一个特定应用的承载容器

常见的轻量级服务器软件:

1、Nginx:典型的静态服务器,可做反向代理、负载均衡,一般放在最前面直面用户,和后端Tomcat打配合;纯C写的,性能贼高、内存消耗极少、稳定性也相当好,互联网公司重度使用

2、Tengine:阿里出品,基于Nginx服务器做的改造(加强和封装),对大流量场景做了很多高级功能,性能、稳定性优秀

3、Apache http server:也是静态服务器,但是不如Nginx

3、IIS:微软开发,只能用在Windows下,具有应用服务器能力的http服务器

4、Tomcat:Apache出品,典型的应用服务器软件,符合Servlet标准的应用容器,也可以提供http服务,但一般不会作为http服务器;是Spring Boot框架默认的内置服务器

5、Jetty:跟Tomcat是一个性质的东西,符合Servlet标准的应用容器,也是Spring Boot框架支持的服务器,但不是默认的

6、Undertow:红帽子出品,跟Tomcat、Jetty一样也是Spring Boot框架支持的服务器,但不是默认的;高并发时性能优于Tomcat、Jetty

几款商用重量级的服务器软件:

1、JBoss(从8版开始更名为WildFly):不仅是Servlet应用容器,更是EJB的应用容器,整套JavaEE框架部署的解决方案

2、WebLogic:Oracle公司出品,用于部署企业级JavaEE应用,全能型,几乎支持JavaEE所有的应用规范

3、WebSphere:IBM公司出品,支持更多JavaEE的应用规范的综合应用服务器