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)
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/nginx.pid;
# 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 http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
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;
}
}
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.conf
in 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 https://irina.codes, Irina Scurtu's blog
Top comments (3)
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 startnginx
altogether. This being said, I'm sure there's less common cases when it wouldn't work.👍
Thanks for this! I didn't knew all the details :)
Just what I was looking for, thanks for the post!