I. Preface

This article mainly wants to try to deploy ASP.NET Core to Linux Server in advance.

 Second, preparation work


1. A computer with a Linux operating system. Well, the Tencent Cloud Student Package is used here. The server version is CnetOS 7.5.

2, the terminal software, here I use putty, to help us remotely connect to our server.

Download link:


3, file upload software, here I use WinSC, upload files, at the same time, how you and I are not used to editing files using the command line, you can also edit the configuration file on the server that needs to be changed, escape ~ ~~.

Download link:


 Third, Step by Step


1. Install .NET Core Runtime

Because there is no need to do development work on a Linux server, you only need to install the dotnet core runtime. If you need to develop on Linux, you need to install the .NET Core SDK. Of course, if you have installed the SDK. There is no need to install Runtime.

We open Microsoft’s official website and use putty to connect to our server.
Official website address:


a) Register the Microsoft key on the server, here I am using Centos, here you need to choose to download according to your own server version.

Sudo rpm -Uvh https: // packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm

b) Update the version available for installation. When the console appears Complete, it will complete the update on our behalf.

Sudo  yum update

c) Install .NET Core. Similarly, when the console appears Complete, it means that our installation is complete.

Sudo  yum  install aspnetcore-runtime- 2.1   ##Here, if you want to develop on Linux, install dotnet-sdk- 2.1 here.

At this time, how can we judge that our .NET Core installation is successful?
We can enter the following command on the console. If the installation is successful, we can display the dotnet version information we installed. Otherwise, you need to re-execute it.

Dotnet -- info


Here we can see that we just installed the .NET Core Runtime and did not install the SDK. Our Host version is 2.1.5.

2, install MySQL

a) Add MySQL source

First open the official website of MySQL, you need to choose the appropriate source information according to your own server information, my server operating system is CentOS, here I choose the yum source (yum source address:

https://dev.mysql.com/downloads/ Repo/yum/


When we clicked the Download button, we found that we were logged in.
If you don’t want to register another account with me, we can get the download address below and install it via rpm -Ivh.
I installed the latest version of MySQL 8.0, of course, you can also download different MySQL versions by modifying the version number.

Wget https: // dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm 
rpm -ivh mysql80-community-release-el7- 1 .noarch.rpm

b) Verify that md5 is consistent with the official website

Md5sum mysql80-community-release-el7- 1 .noarch.rpm

c) Install MySQL Server

Sudo  yum  install mysql-server


d) Start MySQL Server

Once we have finished installing, we can start the MySQL Server service.
We can start the MySQL daemon with the following command.

Sudo systemctl start mysqld

However, after the above command is executed, there will be no reaction. We may question whether our execution is successful?
So to ensure that our execution is successful, we can use the following command to see if the MySQL service is enabled.
At this point, if our MySQL service has been started, we will output our execution information.

Sudo systemctl status mysqld


When we start, we may have questions. We have not set an administrator password.
Originally, during the installation process, we will automatically generate a temporary password for the MySQL root user. We can find this default password by the following command.

Sudo  grep  ' temporary password ' /var/log/mysqld.log

We can use the following command to modify our root password. We will prompt you to enter the default password. After the default password is entered correctly, you can set your own password.

Sudo mysql_secure_installation

Note: The reset password contains at least one uppercase letter, one lowercase letter, one number and 12 characters of a special character!!!
In the process of setting the password, there are five steps in total: setting the root password; whether to prohibit the remote login of the root account; whether to prohibit the anonymous account (anonymous) login; whether to delete the test library; whether to confirm the modification.
After your own needs, you can do it after the setup is complete.


e) set to allow remote login,

After the above settings are completed, we use our local Workbench to connect to the database on the server and find that the connection cannot be made. If you have used remote connection to MySQL Server before, you should know that we need to set the root user to allow access in the user table. address.

Mysql -h localhost -u root - p ##Login the database, enter the password to complete the login
 use mysql; ##Select mysql table
 select user, host from user; ##Query the current user
 update user set host= ' % ' where user = ' root ' ; ##Allow remote login to the root account using the root account
 ; ##Refresh settings


At this point, we can connect to our MySQL Server remotely.

3, release the deployment program

When we drop the project onto the server, we go inside the placed path and execute the dotnet command to run our project.
It is important to note here that in Linux, the case is distinguished. The path entered here and the name of the project must be the same as the actual one.

Cd /usr/local/wwwroot/psu/ ##Note: Finally, you must add this / !!!!!
Dotnet PSU.Site.dll

There will be a problem here, no matter if you are using a virtual machine or a cloud server, because the 5000 port is not open for external access, the external machine adopts the ip:port method, which is inaccessible, so we need to install it next. Reverse proxy server to achieve access.

When deploying a .NET Core project, we should keep the .NET Core version of our program consistent with the environment version on the server so that we can avoid certain problems caused by environmental factors, so I deploy .NET here. The Core 2.0 version of the program is actually not a good choice.

4, install Nginx server

On Windows servers, if we are deploying a .NET project, we will definitely choose to deploy to IIS. Similarly, while .NET Core can be self-hosted, the built-in Kestrel is also great for providing dynamic content from ASP.NET Core.
However, Kestrel’s Web services capabilities are not as feature-rich as specialized servers such as IIS, Apache, or Nginx.
The reverse proxy server can offload service static content, cache requests, compression requests, and SSL endpoints from the HTTP server.
The reverse proxy server may reside on a dedicated computer or it may be deployed with an HTTP server, but in order to use more functions, we will still use it with a reverse proxy server. Here, I am using Nginx. .

a) Install Nginx

Download the nginx package from the official website and extract it. Here is the form of compiling and installing using source code.

Wget -c http: // nginx.org/download/nginx-1.9.9.tar.gz 
tar -zxvf nginx- 1.9 . 9 . tar .gz

Once the extraction is complete, we can go to the nginx directory, where we create the default configuration file.
Before we can create the configuration file, we need to install the gcc environment.

Cd nginx- 1.9 . 9 
yum  install  gcc  gcc -c++

After the above steps are completed, we need to add a few plugins to improve the functionality of Nginx.

Nginx’s http module uses pcre to parse regular expressions. PCRE (Perl Compatible Regular Expressions) is a Perl library that includes a perl-compatible regular expression library.

Yum  install -y pcre pcre-devel

The zlib library provides a variety of ways to compress and decompress. Nginx uses zlib to gzip the contents of the http package, so we also need to install the zlib library on the server.

Yum  install -y zlib zlib-devel

Nginx supports not only the http protocol, but also the https protocol, which is a powerful Secure Sockets Layer cryptography library that includes major cryptographic algorithms, common key and certificate encapsulation management functions, and SSL protocols, and provides a rich set of applications. Used for testing or other purposes, so we will also add it to Nginx.

Yum  install -y openssl openssl-devel

At this point, our installation of the Nginx plugin is complete, and now we can re-execute the configuration command and then compile and install.

./ configure
 make  install

After the compilation and installation is complete, Nginx is installed on our server, but where is the installation?
Here we can use the following command to find the Nginx we installed.
Once you know the installation path, we can go into the Nginx directory to perform further operations.
At this point, the installation of Nginx is complete (here is my path address, yours may be different from me, subject to your actual).

Whereis nginx
 cd /usr/local/nginx/sbin/

After the installation is complete, we will generally set Nginx to boot self-start and auto-restart, thus preventing the website from hanging due to special circumstances.
Let’s first create a soft connection to point to the Nginx installation directory.

Ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

Now create a self-starting script.

Vim /etc/init.d/nginx

In the script, enter the following.


#!/bin/ sh
# nginx - this script starts and stops the nginx daemon
# chkconfig:    - 85  15
# description: NGINX is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP / POP3 proxy server
# processname: nginx
# config:       /usr/local/nginx/conf/ nginx.conf
# config:       /etc/sysconfig/ nginx
# pidfile:      /usr/local/nginx/logs/ nginx.pid
# Source function library.
. /etc/rc.d/init.d/ functions
# Source networking configuration.
. /etc/sysconfig/ network
# Check that networking is up.
[ " $NETWORKING " = " no " ] && exit 0 
nginx = " /usr/local/nginx/sbin/nginx " 
prog =$( basename $nginx)
NGINX_CONF_FILE = " /usr/local/nginx/conf/nginx.conf " 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/ nginx
 lockfile =/var/lock/subsys/ nginx
Make_dirs() {
   # make required directories
   User =`$nginx -V 2 >& 1 | grep  " configure arguments: " | sed  ' s/[^*]*--user=\([^ ]*\).*/\1/g ' - `
    If [ -z " `grep $user /etc/passwd` " ]; then 
       useradd -M -s /bin/ nologin $user
   options =`$nginx -V 2 >& 1 | grep  ' configure arguments: ' `
    for Opt in $options; do 
       if[ ` echo $opt | grep  ' .*-temp-path ' ` ]; then 
           value =` echo $opt | cut -d " = " -f 2 `
            if [ ! -d " $value " ]; then 
               # echo  " creating " $value
                mkdir -p $value && chown - R $user $value
Start() {
    [ -x $nginx ] || exit 5 
    [ -f $NGINX_CONF_FILE ] || exit 6
    Echo -n $ " Starting $prog: " 
    daemon $nginx - c $NGINX_CONF_FILE
    Retval =$?
    [ $retval -eq 0 ] && touch $ lockfile
    Return $retval
Stop() {
    Echo -n $ " Stopping $prog: " 
    killproc $prog - QUIT
    Retval =$?
    [ $retval -eq 0 ] && rm -f $ lockfile
    Return $retval
Restart() {
    Configtest || return $?
    Sleep  1
Reload() {
    Configtest || return $?
     echo -n $ " Reloading $prog: " 
    killproc $nginx - HUP
    RETVAL =$?
Force_reload() {
Configtest() {
  $nginx -t - c $NGINX_CONF_FILE
Rh_status() {
    Status $prog
Rh_status_q() {
    Rh_status >/dev/ null  2 >& 1
Case  " $1 "  in
        Rh_status_q && exit 0 
        $ 1
        Rh_status_q || exit 0 
        $ 1
    Restart | configtest)
        $ 1
        Rh_status_q || exit 7 
        $ 1
    Force - reload)
    Condrestart |try- restart)
        Rh_status_q || exit 0
    * )
         echo $ " Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest} " 
        exit 2 


Now we will give the script executable permission to the script from the startup and add the Nginx service to the chkconfig management list.

Chmod a+x /etc/init.d/ nginx
chkconfig --add /etc/init.d/ nginx
 chkconfig nginx on

Once the above settings are complete, start our Nginx daemon service.

Systemctl start nginx

Similarly, we can use the following command to view the status of the Nginx service.

Systemctl status nginx

Some commonly used commands (when you need to be in the Nginx installation directory, for example, my Nginx installation directory is /usr/local/nginx/sbin/, if you do not need to use the full path in the installation directory)

Start the Nginx service


Stop the Nginx service

./nginx - s stop
 ./nginx -s quit

There are two ways to stop the Nginx service. The first one: -s stop: first find the process id of nginx, then use the kill command to force the process to be killed. The second type: -s quit: wait for the process of Nginx to complete processing. stop.

Reload Nginx configuration

./nginx -s reload

5, the configuration daemon and self-start

In the above we have used the dotnet command to run our project on the server, and we are currently unable to access it in the form of ip:port, then the Nginx server we installed can help us.

We created a configuration file when we installed Nginx, and now we can use our Nginx proxy by editing this configuration file.
First we enter the path where the Nginx configuration file is located and open the configuration file.

Cd /usr/local/nginx/conf/
Vim nginx.conf

After opening the conf file, we find the Server node and you will see the following configuration items.


Server {
   listen         80 ;
   server_name localhost;
  location / {
         root html;
         index index.html index.htm;


When using Nginx, the server will be matched according to server_name. For example, when we run Nginx successfully, when browsing the ip of the machine through the browser, the default page of Nginx will be displayed by default.
When there is no matching server_name, Nginx will use the default server.
If no default server is defined, the first server in the configuration file becomes the default server.

Modify the configuration information here and forward the 80-port request to the application on port 5000 that we are listening to using Kestrel.


Server {
   listen         80 ;
  server_name localhost;
   location / {
     # Kestrel
    proxy_pass http: // localhost:5000; 
    proxy_http_version     1.1 ;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Host $http_host;
     proxy_cache_bypass $http_upgrade;


We can use the command to verify that the modified configuration format is correct. After the configuration is correct, you can execute the reload command to make the configuration take effect.

./nginx - t ##Test format is correct. /
 nginx -s reload ##Reload configuration

When we completed the above steps, we opened our page through the browser, and no surprise Nginx error page appeared in front of us.
Carefully combing our process, the user requests ip through the browser, Nginx forwards the default 80-port request reverse proxy to the 5000 port of our application, and now we are not using the dotnet command to run our program. There is no program listening on the 5000 port on the server.
So when we use Nginx to reverse proxy our .NET Core program, we also need to use the dotnet command to run our program.

Now, run our program back to the dotnet command, open our browser and we will see that our website has been deployed successfully.
And the browser’s plugin has also identified the Web server we are using as the 1.9.9 version of Nginx.


So here will lead to a problem, in case the dotnet process is unexpectedly hung up, the entire site is not completely hung up, do we still need to manually connect to the server to create again?
So we need to be able to make the dotnet process automatically restart, thus avoiding this situation.

Microsoft officials have suggested that we use the supervisor daemon to implement our .NET Core program to ensure that the application service will automatically restart even if it flashes back.
At the same time, Supervisor also includes a web management page to manage our aspects.

In linux or unix operating systems, the daemon is a special process running in the background that is independent of the controlling terminal and periodically performs certain tasks or waits for certain events to occur.
Since in Linux, the interface between each system and the user is called a terminal, every process that starts from this terminal will be attached to this terminal «, this terminal is called the control terminal of these processes, when the control terminal is closed. The corresponding process will be automatically closed.
But the daemon can break through this limitation, it is out of the terminal and runs in the background, and it is out of the terminal in order to avoid the information in the process of the process being displayed in any terminal and the process will not be used by any terminal. The generated terminal information is interrupted.
It runs from the time it is executed until the entire system is shut down.

Enter the following command to install the Supervisor program.

Sudo  yum  install supervisor

Once the installation is complete we can configure our Supervisor program.

First, we create a directory that stores our configuration files in the etc directory.

Mkdir -m 700 -p /etc/supervisor

After the directory is created, we create the configuration file for the supervisor. Here we copy the default configuration file to our directory.

Echo_supervisord_conf > /etc/supervisor/supervisord.conf

In the /etc/supervisor directory we create a storage directory conf.d that holds our dotnet core process files.

Mkdir -m 700 /etc/supervisor/conf.d

Modify our configuration file, at the end of the configuration file, point the path to the conf.d folder we created.
Note that this must be removed from the front; otherwise, the include node is still not commentable!

 files=/etc/supervisor/conf.d /* .conf

Now let’s create a PSU.conf configuration file to manage the dotnet process for our project.
Well, here I still use WinSCP to edit, and we need to delete the comment information.

Cd /etc/supervisor/conf.d/
 touch PSU.conf


Command = dotnet PSU.Site.dll #Command to be executed
Directory =/usr/local/wwwroot/psu/ #Command Execution Directory
Environment = ASPNETCORE__ENVIRONMENT = Production's environment variables #
User = root # User identity of the process execution
Stopsignal = INTAutostart = true 
#Do you want to start automatically?
Autorestart = true #Do you want to restart automatically?
Startsecs = 3 #automatic restart interval
Stderr_logfile =/usr/local/wwwroot/logs/ psu.err.log #standard error log
Stdout_logfile =/usr/local/wwwroot/logs/psu.log #Standard output log


Here we specify the log output file that we need to create in advance.

Once the configuration is complete, we can create a self-starting service for the Supervisor.

Vim /etc/systemd/system/supervisor.service

Edit our self-starting script.


 Description= supervisor
 Type= forking
 ExecStart=/usr/bin/supervisord -c /etc/supervisor/ supervisord.conf
 ExecStop=/usr/bin/ Supervisorctl shutdown
 ExecReload=/usr/bin/ Supervisorctl reload
 KillMode= Process
 Restart=on- failure
 RestartSec= 42s


Reload our settings.

Systemctl daemon-reload

Set the supervisor.service service to boot.

Systemctl enable supervisor.service

Start our service

Systemctl start supervisor.service

Now let’s use the command to see if our program is running. The last PSU.Site is the program name in the configuration file you set.

[root@VM_0_3_centos ~]# ps -ef | grep PSU.Site
 root       1382    545   4  19 : 45 ?         00 : 00 : 05 dotnet PSU.Site.dll
 root       1648   1606   0  19 : 47 pts/ 0     00 : 00 : 00  grep --color=auto PSU.Site

If you can’t see two processes here, then your program has not started successfully. You can go to the error log file of the previously set program to see why the program can’t be started.
Also, when you make any changes to the configuration file, you will need to restart the Supervisor.

 Fourth, summary


There are a lot of articles on the web that deploy .NET Core programs to Linux servers. However, many times, when you try, there are still many problems, if you have plans to deploy .NET Core programs to Linux servers. At the time, I hope that you can actually try it. After all, if you step on the pit, you can avoid a little pit, hahaha.

 Five, reference



How to install MySQL on CentOS 7


Nginx installation and configuration under CentOS 7


CentOS 7 source code to compile and install Nginx


ASP.NET Core Linux to create a daemon for dotnet (required knowledge)


Centos 7 .Net core background daemon Supervisor configuration