Blazor WebApp配置应用基路径PathBase

Blazor WebApp配置应用基路径PathBase

在一个设备数据管理软件系统中,根据生命周期和应用场景不同,可能会划分几个独立的软件子项目。在部署到的时候,可以采用不同的端口号来访问不同的软件子项目,也可以采用统一的端口号和不同的应用基路径来访问不同的软件子项目。

基本实现方案:

1,软件子项目配置应用基路径PathBase

2,通过nginx反向代理转发请求到软件子项目容器;

 

参考微软官网:https://learn.microsoft.com/zh-cn/aspnet/core/blazor/host-and-deploy/?view=aspnetcore-8.0&tabs=visual-studio#app-base-path

 

软件子项目配置应用基路径PathBase

新建Blazor WebApp项目App1,选择Server端呈现,简单一点。

App.razor设置base href

D:\Software\gitee\PathBaseWeb\App1\Components\App.razor

    @* <base href="/" /> *@

    @* 应用基路径 *@

    <base href="/app1/" />

 

Program调用UsePathBase

D:\Software\gitee\PathBaseWeb\App1\Program.cs

var app = builder.Build();

 

//应用基路径

app.UsePathBase("/app1");

 

launchSettings.json设置启动软件时打开的路由,使得本机调试时应用基路径

D:\Software\gitee\PathBaseWeb\App1\Properties\launchSettings.json

      "https": {

        "commandName": "Project",

        "dotnetRunMessages": true,

        "launchBrowser": true,

        "applicationUrl": "https://localhost:7001;http://localhost:5001",

        //应用基路径

        "launchUrl": "https://localhost:7001/app1",

        "environmentVariables": {

          "ASPNETCORE_ENVIRONMENT": "Development"

        }

      },

 

然后在本机调试运行App1软件,可以看到浏览器地址栏是https://localhost:7001/app1,带有基路径。

 

注意,在软件子项目中,涉及相对路由跳转的代码,要采用相对路由,不能是绝对路由。微软官网提供了很好的示例。

如果软件子项目访问Identity Server 4认证服务器,也要注意同步修改认证服务器的config,比如:

AllowedCorsOrigins = { "https://localhost:7001" },

RedirectUris = { "https://localhost:7001/app1/signin-oidc" },

PostLogoutRedirectUris = { "https://localhost:7001/app1/signout-callback-oidc" },

 

退出登录,返回软件子项目主页相对路径./

var properties = new AuthenticationProperties

{

    RedirectUri = "./"

};

 

搭建nginx反向代理容器

新建docker compose.yml,把各个软件子项目,nginx放在一个容器网桥里,软件子项目只暴露端口,不映射端口到外网,只能通过nginx反向代理访问。软件子项目app1发布后的文件上传到云服务器docker compose.yml当前目录的/pub/app1下面,app2放到/pub/app2。下载IISSSL证书、nginxSSL证书并修改文件名为myweb.*,都放在云服务器docker compose.yml当前目录,再映射到容器内部。

 

version: '3'

services:

  app1:
    container_name: app1
    image: app1image
    build:
      context: ./pub/app1
      dockerfile: Dockerfile
    expose:
      - 7001
    environment:
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/myweb.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password=xxx
      - ASPNETCORE_URLS=https://*:7001
      - ASPNETCORE_ENVIRONMENT=Production
      - TZ=Asia/Shanghai
    volumes:
      - ./:/https #SSL证书myweb.pfx放在宿主机当前目录,映射到容器/https
    security_opt:
      - seccomp=unconfined #取消docker的seccomp调用白名单安全检查
    restart: always

  app2:
    container_name: app2
    image: app2image
    build:
      context: ./pub/app2
      dockerfile: Dockerfile
    expose:
      - 7002
    environment:
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/myweb.pfx
      - ASPNETCORE_Kestrel__Certificates__Default__Password=xxx
      - ASPNETCORE_URLS=https://*:7002
      - ASPNETCORE_ENVIRONMENT=Production
      - TZ=Asia/Shanghai
    volumes:
      - ./:/https #SSL证书myweb.pfx放在宿主机当前目录,映射到容器/https
    security_opt:
      - seccomp=unconfined #取消docker的seccomp调用白名单安全检查
    restart: always

  pathbasenginx:
    container_name: pathbasenginx
    image: nginx:1.17.2
    ports:
      - "8008:8008"
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./myweb.pem:/etc/nginx/myweb.pem
      - ./myweb.key:/etc/nginx/myweb.key
    restart: always
    links:
      - app1
      - app2

 

nginx.conf配置location,把不同的基路径转发到不同的软件子项目容器。

 

#支持http升级到websocket
map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

#cookies太大会报错upstream sent too big header
proxy_buffer_size  128k;
proxy_buffers   32 32k;
proxy_busy_buffers_size 128k;

server {
  listen 8008 ssl;
  ssl_certificate      myweb.pem;
  ssl_certificate_key  myweb.key;

  location /app1/ {
    proxy_pass https://app1:7001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header Host $host:$server_port;
    proxy_cache_bypass $http_upgrade;

    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
  }

  location /app2/ {
    proxy_pass https://app2:7002;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_set_header Host $host:$server_port;
    proxy_cache_bypass $http_upgrade;

    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
  }

}

 

 

测试

在云服务器控制台docker-compose up构建容器并运行,看到app1app2的启动信息,确定侦听协议和端口都正确。

app1             | warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]

app1             |       Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to https://aka.ms/aspnet/dataprotectionwarning

app1             | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]

app1             |       No XML encryptor configured. Key {d2f9ad5f-c488-489a-88b6-d8efc3e2ebbd} may be persisted to storage in unencrypted form.

app1             | warn: Microsoft.AspNetCore.Hosting.Diagnostics[15]

app1             |       Overriding HTTP_PORTS '8080' and HTTPS_PORTS ''. Binding to values defined by URLS instead 'https://*:7001'.

app2             | warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]

app2             |       Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to https://aka.ms/aspnet/dataprotectionwarning

app2             | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]

app2             |       No XML encryptor configured. Key {62dd3c7c-bc41-419f-a72e-9cd0bd8c07f9} may be persisted to storage in unencrypted form.

app2             | warn: Microsoft.AspNetCore.Hosting.Diagnostics[15]

app2             |       Overriding HTTP_PORTS '8080' and HTTPS_PORTS ''. Binding to values defined by URLS instead 'https://*:7002'.

app1             | info: Microsoft.Hosting.Lifetime[14]

app1             |       Now listening on: https://[::]:7001

app1             | info: Microsoft.Hosting.Lifetime[0]

app1             |       Application started. Press Ctrl+C to shut down.

app1             | info: Microsoft.Hosting.Lifetime[0]

app1             |       Hosting environment: Production

app1             | info: Microsoft.Hosting.Lifetime[0]

app1             |       Content root path: /app

app2             | info: Microsoft.Hosting.Lifetime[14]

app2             |       Now listening on: https://[::]:7002

app2             | info: Microsoft.Hosting.Lifetime[0]

app2             |       Application started. Press Ctrl+C to shut down.

app2             | info: Microsoft.Hosting.Lifetime[0]

app2             |       Hosting environment: Production

app2             | info: Microsoft.Hosting.Lifetime[0]

app2             |       Content root path: /app

 

打开浏览器,通过应用基路径访问2个软件子项目容器,正确显示。

https://www.xxx.cn:8008/app1

https://www.xxx.cn:8008/app2

 

问题

.net 8 Asp.Net Coredocker compose脚本参照.net 7编写,在容器运行报错Failed to create CoreCLR, HRESULT: 0x80070008,百度找到答案,取消dockerseccomp调用白名单安全检查,即可解决。参考:

https://www.cnblogs.com/cyq1162/p/17981333

Failed to create CoreCLR, HRESULT_ 0x80070008--.net core 8 run in docker - 路过秋天 - 博客园》

 

DEMO代码地址:https://gitee.com/woodsun/pathbaseweb

 

posted on 2024-02-18 21:38  SunnyTrudeau  阅读(221)  评论(0编辑  收藏  举报