How to host ASP.NET Core on Linux using Nginx?
In my previous article, I have shared my experience on hosting MongoDB server on AWS EC2 Instance. The EC2 instance is running on Ubuntu Server 16.04 LTS machine. To get some knowledge on how to make EC2 instance up and running, you can check this article.
Today, I will share my experience on how to host ASP.NET Core Web API application in my EC2 instance. So, let’s get started.
Step 1: Installing .NET Core in Linux
You will have to install dependencies needed to develop .NET Core applications on Linux. But, there are different dependencies for different Linux distributions/versions. You can check this article for what dependencies should you install for which Linux distributions/versions.
At first, let’s go to the AWS EC2 dashboard and grab the Public IPV4 address like below:
Let’s open PuTTY and connect to the EC2 instance using the copied IPV4 address and login to the EC2 instance.
Now, before installing the dependencies, you should first check which .net core version you are using in your application. You can check by running below command in the console of machine where you are building your application.
dotnet --version
Our version is 2.1.200. Keep that in mind because you will install this version in the instance.
Step 1.1: Register Microsoft key and feed
Before installing .NET, you’ll need to register the Microsoft key, register the product repository, and install required dependencies. This only needs to be done once per machine.
Open a command prompt and run the following commands:
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.debsudo dpkg -i packages-microsoft-prod.deb
Step 1.2: Install .NET Core SDK
You need to update the products available for installation, then install the .NET SDK. In your command prompt, run the following commands:
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.1.200
You can see that we have installed the same .net core sdk version in our EC2 instance also. To check whether it has been installed properly or not, run below command in the Ubuntu console:
dotnet --version
Step 2: Host ASP.NET Core on Linux with Nginx
Now, we have to copy our application over to the Linux. Before that, to copy our application code, we need to install WinSCP.
WinSCP is a popular SFTP client and FTP client for Microsoft Windows. It is used to copy file between a local computer and remote servers using FTP, FTPS, SCP, SFTP, WebDAV or S3 file transfer protocols.
Now, let’s connet our EC2 instance with WinSCP like below:
We need to paste our EC2 instance IPV4 address in the Host Name section. So, after connecting successfully, we can see below screen:
On the left is my local computer files and on the right is home directory of my remote computer means the files of the EC2 instance. Now, let’s create a directory in my remote computer called CoreRESTServer.
Now, let’s go to our application code and go to the directory where the application main solution .sln file resides. And, let’s open the command prompt here and run the below command to publish:
dotnet publish -o awssite
You will see some files are generated inside the awssite directory. Now, we will copy all the files of awssite directory of our local computer to the CoreRESTServer directory of remote computer like below:
Now, we have to configure a reverse proxy server in our remote machine.
A reverse proxy is a common setup for serving dynamic web apps. A reverse proxy terminates the HTTP request and forwards it to the ASP.NET Core app.
Kestrel is great for serving dynamic content from ASP.NET Core. However, the web serving capabilities aren’t as feature rich as servers such as IIS, Apache, or Nginx. A reverse proxy server can offload work such as serving static content, caching requests, compressing requests, and SSL termination from the HTTP server. A reverse proxy server may reside on a dedicated machine or may be deployed alongside an HTTP server.
Step 2.1: Install Nginx
We will use apt-get
to install Nginx. The installer creates a systemd init script that runs Nginx as daemon on system startup. We will run the below command:
sudo -s
nginx=stable # use nginx=development for latest development version
add-apt-repository ppa:nginx/$nginx
apt-get update
apt-get install nginx
Since Nginx was installed for the first time, we have to explicitly start it by running:
sudo service nginx start
We can verify whether browser displays the default landing page for Nginx. The landing page is reachable at http://<server_IP_address>/index.nginx-debian.html
. As our server_IP_adress is 52.221.213.34, so we can see a landing page at http://52.221.213.34/index.nginx-debian.html
.
Step 2.2: Configue Nginx
To configure Nginx as a reverse proxy to forward requests to our ASP.NET Core app, we need to modify /etc/nginx/sites-available/default. Let’s 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 $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
You can see the server is listening to port 80. We need to enable this port in the security group. You can see this article on how to add rule in the security group. Since we have All traffic enabled, we don’t need to enable TCP at port 80 again. It is already enabled in the security group. But, we can also enable the TCP port 80 only rather than opening all the traffic.
Once the Nginx configuration is established, we have to run sudo nginx -t
to verify the syntax of the configuration files. If the configuration file test is successful, we will force Nginx to pick up the changes by running sudo nginx -s reload
.
Now, to directly run the app on the server:
- We have to navigate to the app’s directory means to CoreRESTServer directory.
- Then, we have to run the app’s executable:
dotnet <app_executable>
like
dotnet CoreRESTServer.dll
If a permissions error occurs, we have to change the permissions of the file:
chmod u+x CoreRESTServer.dll
If the app runs on the server but fails to respond over the Internet, we have to check the server’s firewall and confirm that port 80 is open.
Now, our server is setup to forward requests made to http://52.221.213.34:80
on to the ASP.NET Core app running on Kestrel at http://127.0.0.1:5000.
Step 2.3: Running our application as a service
But, if we close the PuTTY session, our application will stop. But, we don’t want that. We have to use systemd 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.
At first, we will create a service file for our web application.
sudo nano /etc/systemd/system/my-web-api.service
Then, inside that my-web-api.service file, i have included below configurations:
[Unit]
Description=My first .NET Core application on Ubuntu
[Service]
WorkingDirectory=/home/ec2-user/CoreRESTServer
ExecStart=/usr/bin/dotnet /home/ec2-user/CoreRESTServer/CoreRESTServer.dll
Restart=always
RestartSec=10 # Restart service after 10 seconds if dotnet service crashes
SyslogIdentifier=offershare-web-app
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
Then, we need to enable the service and run it.
sudo systemctl enable my-web-api.service
sudo systemctl start my-web-api.service
sudo systemctl status my-web-api.service
Now, the status command should show the service as running if the configuration is correct. So, our web application is running. Kestrel by default listens on port 5000, so our application is available on http://localhost:5000.
Now, if we close the PuTTY session, our web application is still running.
So, we have successfully host our .net core web application Linux using Nginx.
Enough for today. Thanks for reading :).