Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 206 additions & 73 deletions aspnetcore/blazor/host-and-deploy/index.md

Large diffs are not rendered by default.

92 changes: 51 additions & 41 deletions aspnetcore/blazor/host-and-deploy/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Learn how to host and deploy a Blazor Server app using ASP.NET Core
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
ms.date: 11/09/2021
ms.date: 01/13/2022
no-loc: [Home, Privacy, Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
uid: blazor/host-and-deploy/server
---
Expand Down Expand Up @@ -42,7 +42,7 @@ Blazor works best when using [WebSockets](xref:fundamentals/websockets) as the S

Blazor Server emits a console warning if it detects Long Polling is utilized:

> Failed to connect via WebSockets, using the Long Polling fallback transport. This may be due to a VPN or proxy blocking the connection. To troubleshoot this, visit https://aka.ms/blazor-server-using-fallback-long-polling.
> Failed to connect via WebSockets, using the Long Polling fallback transport. This may be due to a VPN or proxy blocking the connection.

## Azure SignalR Service

Expand Down Expand Up @@ -134,40 +134,22 @@ metadata:

## Linux with Nginx

For SignalR WebSockets to function properly, confirm that the proxy's `Upgrade` and `Connection` headers are set to the following values and that `$connection_upgrade` is mapped to either:

* The Upgrade header value by default.
* `close` when the Upgrade header is missing or empty.

```
http {
map $http_upgrade $connection_upgrade {
default Upgrade;
'' close;
}
Follow the guidance for an [ASP.NET Core SignalR app](xref:signalr/scale#linux-with-nginx) with the following changes:

server {
listen 80;
server_name example.com *.example.com
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
```
* Change the `location` path from `/hubroute` (`location /hubroute { ... }`) to the root path `/` (`location / { ... }`).
* Remove the configuration for proxy buffering (`proxy_buffering off;`) because the setting only applies to [Server-Sent Events (SSE)](https://developer.mozilla.org/docs/Web/API/Server-sent_events), which aren't relevant to Blazor app client-server interactions.

For more information, see the following articles:
For more information and configuration guidance, consult the following resources:

* <xref:signalr/scale>
* <xref:host-and-deploy/linux-nginx>
* <xref:host-and-deploy/proxy-load-balancer>
* [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx/)
* [WebSocket proxying](http://nginx.org/docs/http/websocket.html)
* <xref:host-and-deploy/linux-nginx>
* Consult developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

## Linux with Apache

Expand Down Expand Up @@ -196,13 +178,21 @@ a2enmod proxy_wstunnel

Check the browser console for WebSockets errors. Example errors:

* Firefox can't establish a connection to the server at ws://the-domain-name.tld/_blazor?id=XXX.
* Firefox can't establish a connection to the server at :::no-loc text="ws://the-domain-name.tld/_blazor?id=XXX":::
* Error: Failed to start the transport 'WebSockets': Error: There was an error with the transport.
* Error: Failed to start the transport 'LongPolling': TypeError: this.transport is undefined
* Error: Unable to connect to the server with any of the available transports. WebSockets failed
* Error: Cannot send data if the connection is not in the 'Connected' State.

For more information, see the [Apache documentation](https://httpd.apache.org/docs/current/mod/mod_proxy.html).
For more information and configuration guidance, consult the following resources:

* <xref:host-and-deploy/linux-apache>
* <xref:host-and-deploy/proxy-load-balancer>
* [Apache documentation](https://httpd.apache.org/docs/current/mod/mod_proxy.html)
* Consult developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

## Measure network latency

Expand Down Expand Up @@ -333,12 +323,20 @@ metadata:
nginx.ingress.kubernetes.io/session-cookie-max-age: "14400"
```

For additional Kubernetes host support, consult the following resources:

* [Kubernetes documentation](https://kubernetes.io/docs/home/)
* Developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

## Linux with Nginx

For SignalR WebSockets to function properly, confirm that the proxy's `Upgrade` and `Connection` headers are set to the following values and that `$connection_upgrade` is mapped to either:

* The Upgrade header value by default.
* `close` when the Upgrade header is missing or empty.
* The `Upgrade` header value by default.
* `close` when the `Upgrade` header is missing or empty.

```
http {
Expand All @@ -364,11 +362,16 @@ http {
}
```

For more information, see the following articles:
For additional Nginx host support, consult the following resources:

* [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx/)
* [WebSocket proxying](http://nginx.org/docs/http/websocket.html)
* <xref:host-and-deploy/linux-nginx>
* Nginx documentation:
* [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx/)
* [WebSocket proxying](http://nginx.org/docs/http/websocket.html)
* Developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

## Linux with Apache

Expand Down Expand Up @@ -403,7 +406,14 @@ Check the browser console for WebSockets errors. Example errors:
* Error: Unable to connect to the server with any of the available transports. WebSockets failed
* Error: Cannot send data if the connection is not in the 'Connected' State.

For more information, see the [Apache documentation](https://httpd.apache.org/docs/current/mod/mod_proxy.html).
For additional Apache host support, consult the following resources:

* <xref:host-and-deploy/linux-apache>
* [Apache documentation](https://httpd.apache.org/docs/current/mod/mod_proxy.html)
* Developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

## Measure network latency

Expand Down Expand Up @@ -563,8 +573,8 @@ metadata:

For SignalR WebSockets to function properly, confirm that the proxy's `Upgrade` and `Connection` headers are set to the following values and that `$connection_upgrade` is mapped to either:

* The Upgrade header value by default.
* `close` when the Upgrade header is missing or empty.
* The `Upgrade` header value by default.
* `close` when the `Upgrade` header is missing or empty.

```
http {
Expand Down
132 changes: 131 additions & 1 deletion aspnetcore/blazor/host-and-deploy/webassembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Learn how to host and deploy a Blazor app using ASP.NET Core, Conte
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
ms.date: 11/09/2021
ms.date: 01/13/2022
no-loc: [Home, Privacy, Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
uid: blazor/host-and-deploy/webassembly
---
Expand Down Expand Up @@ -662,6 +662,136 @@ The `--urls` argument sets the IP addresses or host addresses with ports and pro
--urls=http://127.0.0.1:0
```

## Hosted deployment on Linux (Nginx)

Configure the app with <xref:Microsoft.AspNetCore.Builder.ForwardedHeadersOptions> to forward the `X-Forwarded-For` and `X-Forwarded-Proto` headers by following the guidance in <xref:host-and-deploy/proxy-load-balancer>.

For more information on setting the app's base path, including sub-app path configuration, see <xref:blazor/host-and-deploy/index#app-base-path>.

Follow the guidance for an [ASP.NET Core SignalR app](xref:signalr/scale#linux-with-nginx) with the following changes:

* Remove the configuration for proxy buffering (`proxy_buffering off;`) because the setting only applies to [Server-Sent Events (SSE)](https://developer.mozilla.org/docs/Web/API/Server-sent_events), which aren't relevant to Blazor app client-server interactions.
* Change the `location` path from `/hubroute` (`location /hubroute { ... }`) to the sub-app path `/{PATH}` (`location /{PATH} { ... }`), where the `{PATH}` placeholder is the sub-app path.

The following example configures the server for an app that responds to requests at the root path `/`:

```
http {
server {
...
location / {
...
}
}
}
```

The following example configures the sub-app path of `/blazor`:

```
http {
server {
...
location /blazor {
...
}
}
}
```

For more information and configuration guidance, consult the following resources:

* <xref:host-and-deploy/linux-nginx>
* Nginx documentation:
* [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx/)
* [WebSocket proxying](http://nginx.org/docs/http/websocket.html)
* Developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

<!-- HOLD FOR FUTURE WORK

## Hosted deployment on Linux (Apache)

Configure the app with <xref:Microsoft.AspNetCore.Builder.ForwardedHeadersOptions> to forward the `X-Forwarded-For` and `X-Forwarded-Proto` headers by following the guidance in <xref:host-and-deploy/proxy-load-balancer>.

For more information on setting the app's base path, including sub-app path configuration, see <xref:blazor/host-and-deploy/index#app-base-path>.

The following example hosts the app at a root URL (no sub-app path):

```
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
ProxyRequests On
ProxyPreserveHost On
ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/
ProxyPassMatch ^/_blazor/(.*) http://localhost:5000/_blazor/$1
ProxyPass /_blazor ws://localhost:5000/_blazor
ServerName www.example.com
ServerAlias *.example.com
ErrorLog ${APACHE_LOG_DIR}helloapp-error.log
CustomLog ${APACHE_LOG_DIR}helloapp-access.log common
</VirtualHost>
```

To configure the server to host the app at a sub-app path, the `{PATH}` placeholder in the following entires is the sub-app path:

```
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
ProxyRequests On
ProxyPreserveHost On
ProxyPass / http://localhost:5000/{PATH}
ProxyPassReverse / http://localhost:5000/{PATH}
ProxyPassMatch ^/_blazor/(.*) http://localhost:5000/{PATH}/_blazor/$1
ProxyPass /_blazor ws://localhost:5000/{PATH}/_blazor
ServerName www.example.com
ServerAlias *.example.com
ErrorLog ${APACHE_LOG_DIR}helloapp-error.log
CustomLog ${APACHE_LOG_DIR}helloapp-access.log common
</VirtualHost>
```

For an app that responds to requests at `/blazor`:

```
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>

<VirtualHost *:80>
ProxyRequests On
ProxyPreserveHost On
ProxyPass / http://localhost:5000/blazor
ProxyPassReverse / http://localhost:5000/blazor
ProxyPassMatch ^/_blazor/(.*) http://localhost:5000/blazor/_blazor/$1
ProxyPass /_blazor ws://localhost:5000/blazor/_blazor
ServerName www.example.com
ServerAlias *.example.com
ErrorLog ${APACHE_LOG_DIR}helloapp-error.log
CustomLog ${APACHE_LOG_DIR}helloapp-access.log common
</VirtualHost>
```

For more information and configuration guidance, consult the following resources:

* <xref:host-and-deploy/linux-apache>
* [Apache documentation](https://httpd.apache.org/docs/current/mod/mod_proxy.html)
* Developers on non-Microsoft support forums:
* [Stack Overflow (tag: `blazor`)](https://stackoverflow.com/questions/tagged/blazor)
* [ASP.NET Core Slack Team](http://tattoocoder.com/aspnet-slack-sign-up/)
* [Blazor Gitter](https://gitter.im/aspnet/Blazor)

-->

## Configure the Trimmer

Blazor performs Intermediate Language (IL) trimming on each Release build to remove unnecessary IL from the output assemblies. For more information, see <xref:blazor/host-and-deploy/configure-trimmer>.
Expand Down
8 changes: 4 additions & 4 deletions aspnetcore/host-and-deploy/linux-nginx.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Verify a browser displays the default landing page for Nginx. The landing page i

To configure Nginx as a reverse proxy to forward HTTP requests to your ASP.NET Core app, modify `/etc/nginx/sites-available/default`. Open it in a text editor, and replace the contents with the following snippet:

```nginx
```
server {
listen 80;
server_name example.com *.example.com;
Expand All @@ -149,7 +149,7 @@ If the app is a SignalR or Blazor Server app, see <xref:signalr/scale#linux-with

When no `server_name` matches, Nginx uses the default server. If no default server is defined, the first server in the configuration file is the default server. As a best practice, add a specific default server that returns a status code of 444 in your configuration file. A default server configuration example is:

```nginx
```
server {
listen 80 default_server;
# listen [::]:80 default_server deferred;
Expand Down Expand Up @@ -185,9 +185,9 @@ Create the service definition file:
sudo nano /etc/systemd/system/kestrel-helloapp.service
```

The following example is a service file for the app:
The following example is an `.ini` service file for the app:

```ini
```
[Unit]
Description=Example .NET Web API App running on Ubuntu

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/signalr/scale.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ http {
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
}

server {
listen 80;
Expand Down
20 changes: 10 additions & 10 deletions aspnetcore/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,14 @@ items:
items:
- name: Overview
uid: blazor/security/index
- name: Blazor Server
items:
- name: Overview
uid: blazor/security/server/index
- name: Threat mitigation
uid: blazor/security/server/threat-mitigation
- name: Additional scenarios
uid: blazor/security/server/additional-scenarios
- name: Blazor WebAssembly
items:
- name: Overview
Expand All @@ -430,14 +438,6 @@ items:
uid: blazor/security/webassembly/additional-scenarios
- name: Graph API
uid: blazor/security/webassembly/graph-api
- name: Blazor Server
items:
- name: Overview
uid: blazor/security/server/index
- name: Threat mitigation
uid: blazor/security/server/threat-mitigation
- name: Additional scenarios
uid: blazor/security/server/additional-scenarios
- name: Content Security Policy
uid: blazor/security/content-security-policy
- name: State management
Expand All @@ -458,10 +458,10 @@ items:
items:
- name: Overview
uid: blazor/host-and-deploy/index
- name: Blazor WebAssembly
uid: blazor/host-and-deploy/webassembly
- name: Blazor Server
uid: blazor/host-and-deploy/server
- name: Blazor WebAssembly
uid: blazor/host-and-deploy/webassembly
- name: Configure the Linker
uid: blazor/host-and-deploy/configure-linker
- name: Configure the Trimmer
Expand Down