Поделиться через


Размещение и развертывание ASP.NET Core Blazor WebAssembly с Nginx

Андрей Анненко

Примечание.

Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.

В этой статье объясняется, как развертывать и размещать Blazor WebAssembly, нацеленные на .NET 8, 9 или 10, используя Nginx.

В этой статье рассматривается развертывание приложения непосредственно на узле или в контейнере Docker, который включает Nginx и файлы опубликованного приложения. В разделе размещения Docker рассматривается публикация приложения, копирование опубликованных выходных данных в корневой каталог веб-сайта Nginx в образе контейнера, настройка Nginx для маршрутизации на стороне клиента и применение общих рабочих параметров.

Минимальная конфигурация Nginx

nginx.conf Следующий файл — это минимальный пример конфигурации Nginx, показывающий, как настроить Nginx для отправки index.html файла всякий раз, когда он не может найти соответствующий файл на диске. Он также конфигурирует Nginx для обслуживания правильных типов MIME с помощью определения блока types или включения файла mime.types.

events { }
http {
    types {
        text/html                    html;
        text/css                     css;
        application/javascript       js mjs;
        application/json             json;
        application/manifest+json    webmanifest;

        application/wasm             wasm;

        application/octet-stream     dll pdb webcil;
    }

    server {
        listen 80;

        location / {
            root /usr/share/nginx/html;
            try_files $uri $uri/ /index.html =404;
        }
    }
}

Завершение настройки Nginx

nginx.conf Следующий пример основан на минимальной конфигурации. Он включает необязательные параметры для кэширования, сжатия, ограничения скорости и заголовков безопасности. Просмотрите комментарии и удалите или измените параметры на основе требований вашего приложения.

events { }
http {
    # Security hardening: Don't reveal the Nginx version in responses.
    server_tokens off;

    # Optional: Rate limiting to prevent a single client from sending too 
    # many requests.
    # Blazor WebAssembly apps can generate many requests during startup.
    limit_req_zone $binary_remote_addr zone=one:10m rate=60r/s;

    # Optional: Cache-Control policy by URI.
    # - index.html and service-worker.js: avoid caching so app updates are picked up.
    # - /_framework/*: fingerprinted assets can be cached long-term.
    map $uri $cache_control {
        default             "max-age=3600";
        /index.html         "no-cache";
        /service-worker.js  "no-cache";

        # IMPORTANT: .NET 8/9 Blazor WASM apps do not fingerprint these files
        # Uncomment if the Blazor WASM app targets .NET 8/9, remove for .NET 10
        # /_framework/blazor.boot.json        "no-cache";
        # /_framework/blazor.webassembly.js   "max-age=3600";
        # /_framework/dotnet.js               "max-age=3600";

        ~^/_framework/      "public, max-age=31536000, immutable";
        ~\.woff2?$          "public, max-age=31536000, immutable";
    }

    # MIME types for Blazor WebAssembly assets.
    types {
        text/html                           html htm;
        text/css                            css;
        application/javascript              js mjs;
        application/json                    json;
        application/manifest+json           webmanifest;
        application/wasm                    wasm;
        text/plain                          txt;
        text/xml                            xml;
        application/octet-stream            bin dll exe pdb blat dat webcil;

        # Images
        image/png                           png;
        image/jpeg                          jpg jpeg;
        image/gif                           gif;
        image/webp                          webp;
        image/avif                          avif;
        image/svg+xml                       svg;
        image/x-icon                        ico;

        # Fonts
        font/woff                           woff;
        font/woff2                          woff2;

        # Fallback for other MIME types
        application/octet-stream            *;
    }

    server {
        listen 80;

        location / {
            # Root path for static site content.
            root      /usr/share/nginx/html;

            # SPA/Blazor routing:
            # - Serve a file if it exists.
            # - Otherwise fall back to index.html.
            try_files $uri $uri/ /index.html =404;

            # Optional: Use the rate limit zone defined above.
            limit_req zone=one burst=60 nodelay;

            # Optional: Serve precompressed *.gz files (when present) instead of 
            # compressing on the fly.
            gzip_static on;

            # Optional: Caching policy based on "map $uri $cache_control" above.
            add_header Cache-Control $cache_control always;

            # Optional: Mitigate MIME sniffing.
            add_header X-Content-Type-Options "nosniff" always;
        }
    }
}

Если средства разработчика браузера или средство сетевого трафика указывает, что запросы получают код состояния 503 — служба недоступна , увеличьте rate значения и burst значения.

Дополнительные сведения о конфигурации веб-сервера Nginx в рабочей среде см. в разделе Создание файлов конфигурации NGINX Plus и NGINX.

Развертывание Docker

Следующий dockerfile развертывает приложение Blazor WebAssembly и обслуживает его статические веб-ресурсы на базе образа Nginx.

В примере предполагается, что:

  • Файл проекта приложения называется BlazorSample.csproj и расположен в корневом каталоге контекста сборки Docker.
  • Файл nginx.conf доступен в корневом каталоге контекста сборки Docker.

Например, Dockerfilenginx.conf и BlazorSample.csproj все находятся в одном каталоге, где находится остальная Blazor часть кода. В этом случае docker build запускается в этом рабочем каталоге.

# Build stage
# IMPORTANT: change the dotnet/sdk version to the one that your Blazor app targets
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0-noble AS build
WORKDIR /source

RUN apt update \
    && apt install -y python3 \
    && dotnet workload install wasm-tools

COPY . .
RUN dotnet publish BlazorSample.csproj --output /app

# Runtime stage
FROM nginx:latest
COPY --from=build /app/wwwroot/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf

Выполните сборку и запустите образ:

docker build -t blazor-wasm-nginx .
docker run --rm -p {PORT}:80 blazor-wasm-nginx

Дополнительные сведения см. в руководстве nginx Docker.

Размещенное развертывание в Linux (Nginx)

Настройте приложение с ForwardedHeadersOptions для перенаправления заголовков X-Forwarded-For и X-Forwarded-Proto, следуя инструкциям в разделе Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Дополнительные сведения о настройке базового пути приложения, включая конфигурацию пути вложенного приложения, см. в разделе ASP.NET Core Blazor базовый путь приложения.

Следуйте указаниям для приложения ASP.NET Core SignalR со следующими изменениями:

  • Удалите конфигурацию для буферизации прокси-сервера (proxy_buffering off;), так как этот параметр применяется только к событиям, отправленным сервером (SSE), которые не относятся к взаимодействию между клиентом и сервером в приложении Blazor.

  • Измените путь location с /hubroute (location /hubroute { ... }) на путь к вложенному приложению /{PATH} (location /{PATH} { ... }), где заполнитель {PATH} является путем к вложенному приложению.

    В следующем примере сервер настраивается для приложения, отвечающего на запросы по корневому пути /:

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

    В следующем примере настраивается путь вложенного приложения /blazor:

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

Дополнительные ресурсы