Running .NET Core 2 MVC Application in NGINX Location

NGINX Configuration

In the following paragraphs, we suppose the ASP.NET MVC application is accessible from the URL:

In the /etc/nginx/sites-available/ configuration file, set the following location.

location /mvcmovie/ {
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection keep-alive;
   proxy_set_header Host $http_host;
   proxy_cache_bypass $http_upgrade;

The slash characters at the end of the location name and “proxy_pass” URL are necessary.


In the Configure method of the Startup class (Startup.cs file), add app.UsePathBase with the name of the location set up in the NGINX configuration file. Do not add a slash character at the end.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
   app .UseForwardedHeaders(newForwardedHeadersOptions
   {  ForwardedHeaders=ForwardedHeaders.XForwardedFor|ForwardedHeaders.XForwardedProto
   if (env.IsDevelopment())
   app.UseMvc(routes =>
         name: "default",
         template: "{controller=Home}/{action=Index}/{id?}");


Deploy .NET Core 2 MVC Application on Linux ARM with NGINX

The following procedure has been used on Linux Mint 18.3 (Ubuntu 16.04 x86) for the development and Ubuntu 16.04.3 armv7l (ODROID HC1 device) for the deployment.

To develop a .NET Core 2 with Visual Studio Code on Linux x86, follow the Microsoft tutorial  here.

Publish your application for Linux ARM:

dotnet publish -c Release -r linux-arm

Copy the content of the “./bin/Release/netcoreapp2.0/linux-arm/publish” folder to your production server (ODROID for example).

Install nginx

sudo apt-get install nginx


If optional nginx modules will be installed, building nginx from source might be required.

Use apt-get to install nginx. The installer creates a System V init script that runs nginx as daemon on system startup. Since nginx was installed for the first time, explicitly start it by running:

sudo service nginx start

Verify a browser displays the default landing page for nginx.

Configure nginx

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

server {
    listen 80;
    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $http_host;
        proxy_cache_bypass $http_upgrade;

This nginx configuration file forwards incoming public traffic from port 80 to port 5000.

Once the nginx configuration is established, run sudo nginx -t to verify the syntax of the configuration files. If the configuration file test is successful, force nginx to pick up the changes by running sudo nginx -s reload.

Monitoring the app

The server is setup to forward requests made to http://<serveraddress>:80 on to the ASP.NET Core app running on Kestrel at However, nginx is not set up to manage the Kestrel process. systemd can be used to create a service file to start and monitor the underlying web app. systemd is an init system that provides many powerful features for starting, stopping, and managing processes.

Create the service file

Create the service definition file:

sudo nano /etc/systemd/system/kestrel-hellomvc.service

The following is an example service file for the app:

Description=Example .NET Web API App running on Ubuntu

ExecStart=/usr/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll
RestartSec=10  # Restart service after 10 seconds if dotnet service crashes


Note: If the user www-data is not used by the configuration, the user defined here must be created first and given proper ownership for files.

Save the file and enable the service.

systemctl enable kestrel-hellomvc.service

Start the service and verify that it is running.

systemctl start kestrel-hellomvc.service
systemctl status kestrel-hellomvc.service

● kestrel-hellomvc.service - Example .NET Web API App running on Ubuntu
    Loaded: loaded (/etc/systemd/system/kestrel-hellomvc.service; enabled)
    Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
    CGroup: /system.slice/kestrel-hellomvc.service
            └─9021 /usr/local/bin/dotnet /var/aspnetcore/hellomvc/hellomvc.dll

With the reverse proxy configured and Kestrel managed through systemd, the web app is fully configured and can be accessed from a browser on the local machine at http://localhost. It is also accessible from a remote machine, barring any firewall that might be blocking. Inspecting the response headers, the Server header shows the ASP.NET Core app being served by Kestrel.

HTTP/1.1 200 OK
Date: Tue, 11 Oct 2016 16:22:23 GMT
Server: Kestrel
Keep-Alive: timeout=5, max=98
Connection: Keep-Alive
Transfer-Encoding: chunked

Viewing logs

Since the web app using Kestrel is managed using systemd, all events and processes are logged to a centralized journal. However, this journal includes all entries for all services and processes managed by systemd. To view the kestrel-hellomvc.service-specific items, use the following command:

sudo journalctl -fu kestrel-hellomvc.service

For further filtering, time options such as --since today--until 1 hour ago or a combination of these can reduce the amount of entries returned.

sudo journalctl -fu kestrel-hellomvc.service --since "2016-10-18" --until "2016-10-18 04:00"