DEV Community

Irina Scurtu
Irina Scurtu

Posted on • Originally published at on

.NET Core with NGINX on Linux

.NET Core with NGINX on Linux

Having .NET Core with NGINX on Linux is easier that you might imagine. In this article I will talk about my experience related to NGINX and what it takes to configure it for the first time. If you come from an IIS/Windows world like me, where you know everything by heart, the declarative approach in NGINX might be a bit odd.

I already have Kestrel, why do I need something else?

Kestrel is the default server implementation for ASP.NET Core, and it is super fast, cross-platform, customizable and it can run on its own. It looks like it is the perfect server, but it was lacking a lot of features related to security. Another thing about Kestrel is that “used as an edge server without a reverse proxy server doesn’t support sharing the same IP and port among multiple processes”.

Although is not required, it is recommend to have a reverse proxy in front of Kestrel because it will give you an extra layer of configuration and defense and integrates smoothly with the existing infrastructure.

What is NGINX?

NGINX is an open source software for web serving, load balancing, media streaming, that also has reverse proxy capabilities. One of the goals behind NGINX was to create the fastest web server out there. Now, is one of the most popular servers out there.

Installing NGINX on Linux

Depending on your Linux distribution the package manager might differ. I had Red Hat sudo yum install nginx did the trick. After a successful installation you will find the files and folders for NGINX under /etc/nginx path on the server looking pretty much like this( without the highlighted folders)

nginx structure
nginx structure

One of the most important files out there is the nginx.conf file that will contain or reference other configurations for your web apps. Bear in mind that, in order to be able to start NGINX server this configuration will have to be valid.

Configuring NGINX for all your apps

Now, I’ve cleaned up a bit the default nginx.conf and it looks like this:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

Enter fullscreen mode Exit fullscreen mode

For easier formatting, I used Visual Studio Code with 2 extensions: Nginx configuration and Nginx Formatter.

At line 28, I’ve added an include statement because I want to place all my configurations for different website in separate files, in sites_enabled folder.

After that, I’ve created the sites_enabled folder, and the certs folder (that will contain certificates). In the sites_enabled folder, I’ve created a file named myapi.conf and inside it, I’ve added this:

server {
    server_name myserver;
    root /var/opt/myapps/ui;

    index index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ /index.html;
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;

    location /api {
        proxy_pass http://localhost:4906;
        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;
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
Enter fullscreen mode Exit fullscreen mode

In the configuration file I have 2 ‘location’ sections, one for an UI app, and one for the API. The two apps I want to be served from the same ‘domain’ but on a different path:

  • the ui app from the root like /myapp
  • the api from something deeper in the hierarchy like: /myapp/api

Once this is done, you can test the nginx configuration by running nginx -t -c /etc/nginx/nginx.confin the terminal. If that is successful, you can go ahead, start NGINX server

Useful NGINX commands

sudo nginx service start

sudo nginx service restart

sudo nginx service status

In summary

We looked at how to configure .NET Core with NGINX on Linux, but the same configs will work on Windows also. The only thing you need to do besides configure NGINX is torun the API as a Linux Service, and to make sure is up.

In a following post we will add https in front of our API, because we need to care about security. 🙂

The post .NET Core with NGINX on Linux appeared first on, Irina Scurtu's blog

Top comments (3)

andreimoustache profile image
Andrei Mustață

Great summary! One thing I'd note regarding restarting; they recommend using nginx -s reload for that, which is less brutal, because it gracefully shuts down old workers, and brings up new ones with the new config, i.e. no downtime. With -s reload you also get a free config file syntax check; restarting with a bad config would just not start nginx altogether. This being said, I'm sure there's less common cases when it wouldn't work.


irina_scurtu profile image
Irina Scurtu

Thanks for this! I didn't knew all the details :)

nicolasguzca profile image

Just what I was looking for, thanks for the post!