🎛️
nginx 単一サーバで複数の Blazor Web App をホストする
はじめに
- この記事では、ひとつのサイトで、複数の独立したアプリをホストする手法を模索します。
- サーバやアプリの構成については、以下の記事をご参照ください。
複数アプリの構成
ポートで振り分け
- アプリ毎に仮想サイトとサービスのポートを用意し、
https://<domain_name>:<service_port>/
から、アプリのポートに転送します。 - アプリ毎にサイトが分離されたシンプルな構成です。
- 「番号」とサービス内容が結びつかず、利用者には解りづらいです。
nginx の構成
- アプリ毎に個別の仮想サイトを構成します。
/etc/nginx/sites-available/<service_name>.conf
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
# ssl
listen <service_port> ssl;
listen [::]:<service_port> ssl;
server_name <domain_name>;
# Basic Authentication
auth_basic "private area";
auth_basic_user_file /var/www/.htpasswd;
location / {
proxy_pass http://127.0.0.1:<application_port>;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
承認済みのリダイレクト URI
- GCPコンソールで、以下の登録が必要です。
https://<domain_name>:<service_port>/signin-google
http://<domain_name>:<service_port>/signin-google
- 開発時には、以下が必要です。
https://localhost/signin-google
サブディレクトリで振り分け
- アプリ毎にサービス名に関連付けたサブディレクトリを用意し、
https://<domain_name>/<service_name>
から、アプリのポートに転送します。 - アプリに関連付けた名前が使えるので、利用者に分かり易いです。
- サービス・ポートで振り分けた上で、サブディレクトリからサービス・ポートに転送することも可能ですが、この記事では扱いません。
nginx の構成
- アプリに共通の仮想サイト内にサブディレクトリを作ります。
/etc/nginx/sites-available/default
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name <domain_name>;
# ~ ~ ~
# ~ ~ ~
# Basic Authentication
auth_basic "private area";
auth_basic_user_file /var/www/.htpasswd;
# Blazor Apps
location /<service_name>/ {
proxy_pass http://127.0.0.1:<application_port>;
include snippets/blazor_proxy.conf;
}
location /<service_name2>/ {
proxy_pass http://127.0.0.1:<application_port2>;
include snippets/blazor_proxy.conf;
}
# ~ ~ ~
# ~ ~ ~
}
- 共通の設定をスニペットにまとめまておいて、必要箇所に取り込んで使います。
/etc/nginx/snippets/blazor_proxy.conf
# Blazer proxy common settings
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
承認済みのリダイレクト URI
- GCPコンソールで、以下の登録が必要です。
https://<domain_name>/<service_name>/signin-google
http://<domain_name>/<service_name>/signin-google
- 開発時の設定は後述します。
アプリの構成
-
Program.cs
で早期にWebApplication.UsePathBase ("/<service_name>")
を呼ぶことで、指定ディレクトリで稼働するようになります。
Program.cs
// Application Base Path
var basePath = builder.Configuration ["AppBasePath"];
if (!string.IsNullOrEmpty (basePath)) {
app.UsePathBase (basePath);
}
-
App.razor
でも、パスの指定が必要になります。
App.razor
@inject IConfiguration Config
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="@basePath" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="Project.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
<HeadOutlet />
</head>
<body>
@* <Routes @rendermode="new InteractiveServerRenderMode (prerender: false)" /> *@
<Routes @rendermode="RenderMode.InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
</body>
</html>
@code {
/// <summary>ベースパス</summary>
protected string basePath = "/";
/// <summary>初期化</summary>
protected override void OnInitialized () {
base.OnInitialized ();
basePath = Config.GetValue<string> ("AppBasePath") ?? "/";
if (!string.IsNullOrEmpty (basePath) && !basePath.EndsWith ('/')) {
basePath += '/';
}
}
}
- 上記いずれの場合も、
AppBasePath
は、構成プロバイダーを使用して取得されます。 - 開発時は、例えば
appsettings.Development.json
で与えることができます。
appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AppBasePath": "/<service_name>"
}
- さらに、
launchsettings.json
で指定することで、起動時のURLを変更します。
launchsettings.json
"launchBrowser": true,
+ "launchUrl": "<service_name>",
- こうすることで、
https://localhost:<port>/<service_name>
で起動して動作します。
開発用の承認済みのリダイレクト URI
- 開発時にルートで起動する場合は、GCPコンソールで、以下の登録が必要です。
https://localhost/signin-google
- サブディレクトリで起動する場合は、以下が必要です。
https://localhost/<service_name>/signin-google
- 登録が必要なのは起動時のURLで、起動後に切り替える先のURLの登録は不要です。
おわりに
- お読みいただきありがとうございました。
- 執筆者は、Blazor、ASP.NETともに初学者ですので、誤りもあるかと思います。
お気づきの際は、是非コメントや編集リクエストにてご指摘ください。 - あるいは、「それでも解らない」、「自分はこう捉えている」などといった、ご意見、ご感想も歓迎いたします。
Discussion