How to setup ASP.NET Core run on Debian Linux with Nginx
Hosting and running ASP.NET Core project on linux
In two previous articles (How to setup .NET Core 2 on Debian or Ubuntu Linux distro the easy way & Setting up .NET Core service/daemon on Debian Linux OS) I explained how to setup and run .NET Core based applications and how to run them as a Linux daemon. In this article we are going to take it one step further. We are going to repeat most of the stuff from the previous two articles, which is setting up .NET Core on the Linux host, setting up our application to run as a daemon and in the need we are going to use Nginx as a proxy server to route requests to our ASP.NET Core application which will be running as a daemon in the background.
So first thing first, we need to setup our sample ASP.NET Core application.
ASP.NET Core Demo application
For sample demo application i used ASP.NET Core Web API Application generated by Visual Studio. All you need to to is to start Visual Studio, got to File/New/Project.
Choose ASP.NET Core Web Application project template and in the next window make sure you select API option.
Default Web API project generates ValuesController with Get method that returns JSON content ["value1","value2"]
Since we are not going to implement any functionality, just to setup the Web Application on Linux and see it work, we are going to use this endpoint /api/values and expect mentioned value. ASP.NET Core has built in lightweight web server called kestrel which uses port 5000 by default, so if you run your project from Visual Studio (self-hosted, not IIS Express), it will start at http://localhost:5000/api/values
Default port 5000 can be changed by setting calling UserUrls method in the Program entry point class
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; namespace Sample.Core.Web.Api { public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls("http://localhost:5050") .Build(); } }
This is useful in case you are running more that one web applications on the same Linux machine although it is not best practice to run more services on the same host, but these scenarios are possible.
Next step is the environment setup to make our code work.
Setting up .NET Core on Linux
For the host I used Debian 9.4.0 Linux and .NET Core 2.0.3 but you can download any .NET Core release binaries for x64 Linux from https://www.microsoft.com/net/download/linux and follow the same steps below (just replace the download URL depending on the release binaries you decide to release)
mkdir $HOME/dotnet cd $HOME/dotnet wget https://download.microsoft.com/download/D/7/2/D725E47F-A4F1-4285-8935-A91AE2FCC06A/dotnet-sdk-2.0.3-linux-x64.tar.gz tar zxf dotnet-sdk-2.0.3-linux-x64.tar.gz sudo cp -r ./dotnet /bin sudo apt-get install -y libunwind-dev
Check the dotnet runtime setup by running the following command
/bin/dotnet/dotnet --version
Setting up ASP.NET project to run as a Linux daemon
All steps for setting up .NET Core application to run as a daemon on Linux you can find in Setting up .NET Core service/daemon on Debian Linux OS article. I will just paste the service file content and systemd commands to enable the service.
Open nano for editing the new service file
sudo nano /lib/systemd/system/dotnet-webapi-service.service
Paste the following code in nano and save the file
[Unit] Description=Dotnet Core WebApi Demo service [Service] ExecStart=/bin/dotnet/dotnet Sample.Core.Web.Api.dll WorkingDirectory=/etc/SampleWebApi/ User=dotnetuser Group=dotnetuser Restart=on-failure SyslogIdentifier=dotnet-webapi-service PrivateTemp=true [Install] WantedBy=multi-user.target
Now just refresh systemd services list, enable and start the service
systemctl daemon-reload systemctl enable dotnet-webapi-service.service systemctl start dotnet-webapi-service.service systemctl status dotnet-webapi-service.service
This is it regarding setting up your application to run as a daemon. Your application should be available now at http://localhost:5000. You can check this by fetching your api response
wget http://localhost:500/api/values
This will generate values file in your current folder with web api response JSON.
Setting up Nginx to work as a reversed proxy
Now to setup the Nginx which will act as a reversed proxy to our application and wil expose it on port 80 so we can access it from outside.
Installing Nginx on Debian is easy and it takes just few lines. First make sure you packages are updated and install the Nginx package with apt
sudo apt-get update sudo apt-get install nginx -y
Once Nginx is installed you need to set it up to route traffic from port 80 to port 5000 on which you application is listening. Open Nginx configuration for editing
sudo nano /etc/nginx/sites-available/default
Look for the following snippet in config file
location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; }
Once you locate the snippet from above replace it with the following snippet
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 $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
Save the file and run the following commands which will check the config for errors and reload it
sudo nginx -t sudo nginx -s reload
Now just make sure that Nginx daemon is running
sudo systemctl status nginx
You should get the following message
Now it is all ready to go and you can try to access you api on the port 80 on your Linux host machine.
References
- https://www.microsoft.com/net/download/linux
- https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-8
Disclaimer
Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
Comments for this article