With the growth of many cheap Linux VPS providers and the new releas of .NET core, we have a possibility to host our applications with a low cost. In this post, I would like to write down the steps how I published a ASP.NET core application to a Linux VPS. The application is just a simple “Hello World!” ASP.NET core. The code will be compiled and deployed manually on the Linux VPS. In praxis, you can automatically deploy your app over FTP or use Git to check out the release branch, build and deploy.
1. Prerequisites
– I use a fresh Linux VPS Ubuntu 16.04 LTS for this demo. You can use any Linux distribution but the syntax maybe different.
2. Steps
2.1 Add user
Don’t be root. Let’s create a user with sudo priviledge
adduser dotnetcore usermod -aG sudo dotnetcore
usermod is used to modify or change any attributes of an already existed user. The commands above create a user dotnetcore and add him to group sudo as supplementary as well as secondary group.
-G = To add a supplementary groups. -a = To add anyone of the group to a secondary group.
2.2 Install .Net Core
An updated full instruction for installing .NET Core is available at https://www.microsoft.com/net/core#linuxubuntu. I suggest you to following the instructions on Microsoft’s site. Just select your OS and follow step-by-step instructions there.
In my case, for a fresh Ubuntu 16.04 LTS, I have to install apt-transport-https first on my server.
sudo apt-get install apt-transport-https
Then execute these commands to set up the apt-get feed that hosts the package .NET core.
sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list' sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893 sudo apt-get update
Now I can install .NET core
sudo apt-get install dotnet-dev-1.0.0-preview2.1-003177
Test if it’s installed successfully. In terminal, execute
dotnet --version
2.3 Create app
We create our app folder and an ASP.NET core application
mkdir hwapp cd hwapp dotnet new -t web
2.4 Install development dependencies
The ASP.NET core uses npm, gulp and bower to manage Javascript and CSS packages and enhance the build process. We have to install them so that ASP.NET core application can be built.
sudo apt-get install npm sudo npm install -g gulp sudo npm install -g bower
2.5 Read settings from command line
As default, the ASP.NET core application will run on port 5000. If we let all settings default, we can only host only one app at the same tim because the port 5000 is reserved for the first running app. Therefore we’ll modify the code a little so that we can configure the port at starting.
Open project.json file, add Microsoft.Extensions.Configuration.CommandLine to dependencies section.
"Microsoft.Extensions.Configuration.CommandLine": "1.1.0"
Open Program.cs file, extend the code by using the config from CommandLine.
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; namespace WebApplication { public class Program { public static void Main(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddCommandLine(args) .Build(); var host = new WebHostBuilder() .UseKestrel() .UseConfiguration(config) .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); } } }
Then in terminal run
dotnet restore
To restore all dependencies and then
dotnet build
to be sure if the app is able to be compiled and then
dotnet run --server.urls=http://*:5123
to start hosting our app at local.
If there’s no error, the app has run smoothly within code directory. Just make a curl to test if you get a response.
curl http://localhost:5123
However the app shouldn’t run from code folder, we have to publish it to deploy folder and host it to internet from there
dotnet publish sudo cp -a /home/dotnetcore/hwapp/bin/Debug/netcoreapp1.1/publish/ /var/hwapp
2.6 Expose our app to the outside
Our app can now run on any port (given over command line) and accessible at local (if we start it manually with dotnet run command), but we need to expose it to the outside so that we can access it over internet. If we try to access our Linux VPS now, there’s nothing happen even if we start our app manually. We could tell Kestrel (.NET web server) to run directly on port 80 but then we can host only one app with our server. Therefore I use nginx to make a reverse proxy to forward all requests to correct internal running app.
sudo apt-get install nginx sudo service nginx start
Edit nginx config at /etc/nginx/sites-available/default to forward all requests to our app
server { listen 80; location / { proxy_pass http://localhost:5123; 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; } }
Then test our changes with
sudo nginx -t -t Don’t run, just test the configuration file. NGINX checks configuration for correct syntax and then try to open files referred in configuration.
If no error happens then nginx should reload the new config
sudo nginx -s reload -s signal Send signal to a master process: stop, quit, reopen, reload. (version >= 0.7.53)
2.7 Start website
We have set up our app to be ready. The website is still not running because we’ve started it yet. You can manually start it by running command dotnet run, I’ll use supervisor to start and watch our app.
sudo apt-get install supervisor
Create a config for our hwapp
sudo nano /etc/supervisor/conf.d/hwapp.conf
[program:hwapp] command=/usr/bin/dotnet /var/hwapp/hwapp.dll --server.urls "http://*:5123" directory=/var/hwapp/ autostart=true autorestart=true stderr_logfile=/var/log/hwapp.err.log stdout_logfile=/var/log/hwapp.out.log environment=ASPNETCORE_ENVIRONMENT=Production user=www-data stopsignal=INT
Save the config file, and start our app with following commands
sudo service supervisor stop sudo service supervisor start sudo tail -f /var/log/supervisor/supervisord.log
Then in the browser, browse to your vps. You’ll see your website running.
If our app somehow crashes, supervisor will try to restart our app automatically.
3. Conclusions
It’s pretty simple to deploy ASP.NET core application to Linux VPS. Because of security reasons the setup above is not secure enough. However, for testing purpose or for individual developers, this easy setup can speed up the deployment process. We can also use a single VPS with Nginx to host multiple apps. If I can find a free domain, I’ll make another demo to show how we can host multiple apps on a single Linux VPS.