Configuring NGINX - RopleyIT/GLRParser GitHub Wiki

Configuring NGINX for hosting the parser examples

  1. If you have not done so already, for non-localhost users configure a reverse proxy web server to host the Blazor server-side applications. We shall install NGINX to do this.

  2. Make sure your Ubuntu system is up to date using:

    sudo apt update && sudo apt upgrade

  3. Assuming you do not already have a Web server installed, such as Apache for example, install nginx using sudo apt install nginx

  4. You should see a placeholder Web page displayed from nginx if you browse to http://localhost/, welcoming you to NGINX.

  5. If you are allowing external traffic onto your nginx server, update the firewall for the http and https ports using:

    sudo ufw allow 'Nginx Full'

  6. Configure nginx so that it starts automatically after reboots:

    sudo systemctl enable nginx

  7. We wish to publish the application so that it can be accessed across the network, using NGINX as a reverse proxy. Before you do this, you also need to modify the app source code so that it uses the Forwarded Headers Middleware. This allows redirects and security policies to work correctly.

    In the three examples added to the GitHub repository, this has already been done. However, for new projects using Blazor server hosting behind an NGINX reverse proxy, you will want to make the edits to Startup.cs described here.

    Edit your application's Startup.Configure method to include the following at the top of the function (Note the comment telling you to add a using directive at the top of the source file.):

    // using Microsoft.AspNetCore.HttpOverrides;
    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor 
            | ForwardedHeaders.XForwardedProto
    });
    // app.UseAuthentication(); // If authenticating
  1. If you are running NGINX on the same machine as the blazor applications, skip this step. If however your NGINX proxy server is on a different machine to the application you want to be hosted, you will also need to tell your application about the trusted proxy server machine. Add to you Startup.Configure method the following extra lines of code:
    // using System.Net;
    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.KnownProxies.Add(IPAddress.Parse("10.0.0.2"));
    });
Obviously replace the `10.0.0.2` with the IP address of
the actual proxy server. Also note the need for a using
directive at the top of the source file.

For more details on configuring the middleware, see the
Microsoft article at `https://docs.microsoft.com/en-us/`
    `aspnet/core/host-and-deploy/proxy-load-balancer`
    `?view=aspnetcore-3.1`
  1. Build and publish the content of your application (for example, any of the three examples in the folders CalculaterExample/CalculatorDemoApp, SentenceParserExample/SentenceParserDemo, or TrafficLightControllerExample/PedXDemo) by changing to its project folder, and typing the command:

    dotnet publish -c Release

    This will place the set of files to be published to the web server in a subfolder of your project folder called bin/Release/netcoreapp3.1/publish.

  2. Now configure NGINX as a reverse proxy to forward requests to your ASP.NET Core app, and to enable the SignalR WebSocket protocols used by Blazor server technology to work correctly.

    Open the NGINX primary configuration file for editing using:

    sudo nano /etc/nginx/nginx.conf

  3. Scroll down into the http {} section and find the two lines that include the conf.d configuration files and the files from the sites-enabled folders. Above these two lines add the following two lines that enable SignalR tunnelling:

    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }
Save the file using `^O` and `^X`.
  1. Replace the contents of file /etc/nginx/sites-available/default with the following:
    server {
        listen      80;
        server_name whatever.com *.whatever.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;
        }
    }
where `whatever.com` should be replaced with the URL
at which users have been told the application is hosted.
DNS services should route these requests from the client
machines to the machine containing your NGINX server.

Note that if there is only one set of `server { }` tags
accessible to the whole NGINX configuration, this becomes
the default server for everything, and the `whatever.com`
will be ignored anyway.

Note there are one or two other security concerns to address
here if you are intending to host your application out there
in the hostile internet. See the Microsoft article at:

`https://docs.microsoft.com/en-us/aspnet/core/`
    `host-and-deploy/linux-nginx?view=aspnetcore-3.1`
  1. Run sudo nginx -t to check you typed the file contents correctly. If so, reload the nginx server using:

    sudo nginx -s reload

  2. To try out your application behind NGINX, change directory to the bin/Release/netcoreapp3.1/publish folder under your project folder, and launch the application by typing the name of the project. For example, if the project you built was called CalculatorDemoApp, once you get to its publish folder, just type the command: ./CalculatorDemoApp

  3. From a different machine on the network, type the url or IP address of your machine into the browser's address bar. NGINX should route your request to the application.

If you are putting your application into production, you probably want to arrange that Linux starts up your hosted application automatically rather than you navigating to its publish folder and typing its name. instructions on how to do this come next.