I was pleasantly surprised by how easy it was to setup and install ASP.NET Core 2.1 on Linux. I did it for the first time in 15 minutes with no previous experience with .NET Core on Linux. I did it the second time, in production, in 5 minutes by following these instructions.
In this article, I show you how to install the .NET Core runtime on CentOS, how to get a sample ASP.NET Core project running on Kestrel as a service for reliability, and how to configure both the code and the firewall to enable remote access. Finally, I discuss what I would do differently for actual production usage.
Step 1 - Install Runtime
To run ASP.NET Core on Linux, you'll need to start by installing the runtime.
On CentOS 7, I had to add an RPM package containing the yum references, update yum, and then install the .NET Core runtime:
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm sudo yum update sudo yum install aspnetcore-runtime-2.1
Microsoft provides similar instructions for different Linux Distributions including RHEL, Ubuntu, Debian, Fedora, CentOS, openSUSE, and SLES.
If you want to compile and do development as well, you'll want to install the SDK instead of the runtime. On CentOS, I would install the SDK using:
sudo yum install dotnet-sdk-2.1
Step 2 - Publish and Deploy
The next step is to publish and deploy your project.
Create a Sample Project
To get started quickly, I created a new demo ASP.NET Core 2.1 project, by running this command:
dotnet new razor -o CoreTest
For this command to work, you'll need to have installed the SDK and not just the runtime. I simply ran this on my local development machine as I only installed the runtime on the Linux server.
Optionally add support for Remote Access
By default, the ASP.NET Core 2.1 project will run on the Kestrel web server on localhost.
If you want to be able to access the website remotely from other computers, you'll need to bind it differently.
To do this, I went into the newly created project files and opened
Program.cs. In here I added a call to the
UseUrls method as follows:
public static IWebHostBuilder CreateWebHostBuilder(string args) => WebHost.CreateDefaultBuilder(args) .UseUrls("http://0.0.0.0:5000") .UseStartup<Startup>();
This binds the ASP.NET Core website to all IPs on the server, instead of just
localhost, which is the default.
Compile and Deploy
To compile the project, I simply ran:
dotnet publish --configuration Release
This builds and puts all the files required for deployment into the
bin/Release/netcoreapp2.1/publish folder by default.
To deploy, I simply copied all the files and directories from the publish folder into
/home/coretest on the Linux server.
I copied the files using SmarTTY, but you could easily use FTP or any other method to move the files.
Step 3 - Run the Web Application
Now that .NET Core is installed, and the project is deployed, we want to run it.
The simplest method is to go into the website directory,
/home/coretest, and execute:
This runs the application immediately but is susceptible to crashes and needs to be manually started after any server restarts.
Run as a Service
It is much better to run the website as a service, so that it is run automatically at start-up after restarts and is restarted automatically if it crashes.
To run the website as a service, you'll need to create a service definition file. I called mine
kestrel-coretest and created it in this location:
In this file, I added the following contents:
[Unit] Description=.NET Core Test App [Service] WorkingDirectory=/home/coretest ExecStart=/usr/bin/dotnet /home/coretest/CoreTest.dll Restart=always RestartSec=10 SyslogIdentifier=dotnet-coretest User=daniel Environment=ASPNETCORE_ENVIRONMENT=Production [Install] WantedBy=multi-user.target
You'll need to change the
User variable to something appropriate for your server and make sure the deployment files have appropriate permissions.
Start the Service
After saving the service definition file, enable the service using:
sudo systemctl enable kestrel-coretest.service
You can then start the service using:
sudo systemctl start kestrel-coretest.service
And check the status of the service using:
sudo systemctl status kestrel-coretest.service
You can also check which web applications are running using:
ps -A all | grep dotnet
This is particularly useful when running multiple websites on different ports as it will list all those that are running.
Step 4 - Test on Localhost
You can now test the website by trying to access it via
localhost. From your SSH connection, use
wget as follows:
This should download the home page and store it in a file named
index.html in the current directory. If you haven't got
wget, you can install it using:
sudo yum install wget
Step 5 - Optionally Open Firewall and Test Remotely
If you enabled remote access in step 2, you can now open port 5000 in the firewall and try connecting from a remote computer.
You can open port 5000 using Firewalld:
sudo firewall-cmd --add-port=5000/tcp --permanent sudo firewall-cmd --reload sudo firewall-cmd --list-all
If this worked, you should see
5000/tcp in the ports section after running the last command. It should look something like this:
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: ssh dhcpv6-client ports: 5000/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
You can now try accessing the website remotely from a browser. If the IP address of your Linux server is
192.168.1.5, go to
http://192.168.1.5:5000 in your browser to access it and you'll see the demo site:
Bonus Tip - Uninstalling the SDK or Runtime
If you install the SDK and then decide you only need the runtime or you simply want to remove .NET Core.
On CentOS, you can remove the SDK using:
sudo yum remove dotnet-sdk-2.1
Similarly, you can remove the Runtime using:
sudo yum remove aspnetcore-runtime-2.1
You may then also want to remove any unused dependencies that came along with the SDK or Runtime using:
sudo yum autoremove
Changes for a Production Setup
This tutorial has shown how to install .NET Core and get an ASP.NET Core website working quickly.
But I wouldn't actually run it like this in production as Kestrel is a rather basic web server.
You'll want to put a more fully-featured web server such as IIS, Nginx, or Apache in front of Kestrel.
My Linux Deployment
On my Linux deployment, I'm going to disable remote access by removing
UseUrls from step 2 and undoing step 5. I'm then going to run Apache in front of Kestrel, which will act as a reverse proxy to Kestrel on localhost.
In my case, this is going to let me slowly migrate some existing websites from PHP to C# and .NET Core. I plan to reverse proxy some URLs to .NET Core, while continuing to serve other URLs using PHP. This will allow me to migrate these websites over time.