RehanSaeed / rehansaeed.github.io

Muhammad Rehan Saeed's Blog
https://rehansaeed.com
30 stars 6 forks source link

[Comment] NGINX for ASP.NET Core In-Depth #97

Open RehanSaeed opened 4 years ago

RehanSaeed commented 4 years ago

https://rehansaeed.com/nginx-asp-net-core-depth/

RehanSaeed commented 4 years ago

Johan Johan commented on 2016-09-13 16:40:45

Not often that I comment on a post like this but this is good. I'm sold on Nginx and trying to figure out .Net Core. The only missing part here, is Charting, with live data (SignalR + DependencyCache, OnChange).

By the way, thanks for sharing.

RehanSaeed commented 4 years ago

Os1r1s110 Os1r1s110 commented on 2016-11-18 16:43:44

Really nice article with in-depth details about nginx configuration. Gives much better configuration than default files found in ASP.NET Core tutorials.

What would you think about adding pagespeed module in the pipeline, would it be a good idea/worth it? I know some of the features are redundant but I wonder if it could get an even further performance boost. What do you think?

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2016-11-27 07:49:49

Really nice article with in-depth details about nginx configuration. Gives much better configuration than default files found in ASP.NET Core tutorials.

What would you think about adding pagespeed module in the pipeline, would it be a good idea/worth it? I know some of the features are redundant but I wonder if it could get an even further performance boost. What do you think?

Ideally you should build your site so it is optimized in the first place, so you shouldn't need to run a tool like this which adds it's own performance penalty. You can see what this tool is doing and replicate that in your app. That said, I'm not very familiar with this tool. Best thing to do is try it and see when it comes to performance.

RehanSaeed commented 4 years ago

Tim Tim commented on 2017-05-05 09:08:08

Great article thanks - very helpful. Do you separate the server blocks into the sites-available folder? And do you know if this configuration works with Fail2Ban? I know I need to make sure the log file locations match - but I wasn't sure how custom log_format might affect Fail2Ban - any idea? Regards Tim

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2017-05-05 14:41:03

Great article thanks - very helpful. Do you separate the server blocks into the sites-available folder? And do you know if this configuration works with Fail2Ban? I know I need to make sure the log file locations match - but I wasn't sure how custom log_format might affect Fail2Ban - any idea? Regards Tim

Not sure what you mean about separating the server blocks. I've never used Fail2Ban either (I'd recommend using Cloudflare as well or perhaps instead if you worry about bad traffic).

RehanSaeed commented 4 years ago

Tim Tim commented on 2017-05-06 01:39:59

Not sure what you mean about separating the server blocks. I've never used Fail2Ban either (I'd recommend using Cloudflare as well or perhaps instead if you worry about bad traffic).

Thanks Rehan

FYI - regarding splitting out the content of nginx.conf into site-specifc and other config-specific files take a look here. "...several NGINX distributions (as well as NGINX Plus) follow the convention that you do not place much actual configuration in the main file, but instead create smaller, function specific files in a subdirectory of /etc/nginx:

For open source NGINX builds provided by nginx.org, and for NGINX Plus, the directory is /etc/nginx/conf.d, and the default file for HTTP virtual servers is default.conf. For open source NGINX builds distributed with Ubuntu, the directory is /etc/nginx/sites-enabled, and the default file for HTTP virtual servers is default. The content of the function specific files in these directories is then read into the main (nginx.conf) file with an include directive, for example:

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

After a fresh install of Nginx on Ubuntu it has these include's within the http block. So using your config, I would split out the server blocks into a site-specific file within the sites-available directory, then create a symbolic link to it within the sites-enabled directory (sites-available and sites-enabled directories are created as part of the Nginx install). The net effect at run time is the same as your config, except you can more easily manage multiple websites this way. Unfortunately this is not documented well in the Nginx docs - but mentioned in plenty of other articles around the web.

RehanSaeed commented 4 years ago

Vasko Mihailov Vasko Mihailov commented on 2017-05-29 12:56:39

Thanks for sharing ur knowledge!

Is it possible to host multiple asp.net core web apps on a single nginx server? If so can you please provide some tips and tricks.

Thanks a lot.

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2017-05-29 13:26:20

Thanks for sharing ur knowledge!

Is it possible to host multiple asp.net core web apps on a single nginx server? If so can you please provide some tips and tricks.

Thanks a lot.

Yes that's possible. You just need a server element in your config for each app.

RehanSaeed commented 4 years ago

Vasko Mihailov Vasko Mihailov commented on 2017-05-30 18:22:00

Yes that's possible. You just need a server element in your config for each app.

Thank you for your advice.

My confusion comes from this article.

Somewhere before the end of the article the author claims this:

First and foremost, if you want to have multiple applications running on a single server that all share port 80 and port 443 you can't run Kestrel directly. Kestrel doesn't support host header routing which is required to allow multiple port 80 bindings on a single IP address. Without IIS (or http.sys actually) you currently can't do this using Kestrel alone (and I think this is not planned either).

I am sorry if it is not allowed to quote other authors in your posts. If so it is OK with me to delete it.

Thanks again.

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2017-05-31 09:18:50

Thank you for your advice.

My confusion comes from this article.

Somewhere before the end of the article the author claims this:

First and foremost, if you want to have multiple applications running on a single server that all share port 80 and port 443 you can't run Kestrel directly. Kestrel doesn't support host header routing which is required to allow multiple port 80 bindings on a single IP address. Without IIS (or http.sys actually) you currently can't do this using Kestrel alone (and I think this is not planned either).

I am sorry if it is not allowed to quote other authors in your posts. If so it is OK with me to delete it.

Thanks again.

The Kestrel web server does not support SNI which lets you run multiple sites on the same port (usually port 80 and/or 443 on a production site). If you want SNI, use the WebListener (Now renamed HttpSysServer) web server instead.

RehanSaeed commented 4 years ago

Vasko Mihailov Vasko Mihailov commented on 2017-06-01 20:16:31

The Kestrel web server does not support SNI which lets you run multiple sites on the same port (usually port 80 and/or 443 on a production site). If you want SNI, use the WebListener (Now renamed HttpSysServer) web server instead.

Thanks. That will do the trick I hope. By the way, do you have any clues about performance comparison between IIS and Linux+Nginx? There are a lot talks on the net that can be found but it will be great to have your personal opinion.

Thanks.

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2017-06-02 12:04:56

Thanks. That will do the trick I hope. By the way, do you have any clues about performance comparison between IIS and Linux+Nginx? There are a lot talks on the net that can be found but it will be great to have your personal opinion.

Thanks.

NGINX is faster than IIS.

RehanSaeed commented 4 years ago

Karnesh Kumar Karnesh Kumar commented on 2017-07-12 10:46:06

Hi, Is it possible to host asp.net website at NGINX server with below requirement. Developed in

Please help me.

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2017-07-23 12:32:13

Hi, Is it possible to host asp.net website at NGINX server with below requirement. Developed in

  • ASP.NET Website (not a MVC)
  • Targeted framework 4.5.6
  • SQL Server 2014

Please help me.

Not unless you use IIS too.

RehanSaeed commented 4 years ago

elbarto elbarto commented on 2017-09-18 23:59:59

Hello,

could you also explain how to use a subdirectory instead of /? For example:

http://localhost/test

I don't get that running, it just happens nothing at all when you browse.

Thanks!

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2017-09-19 09:12:07

Hello,

could you also explain how to use a subdirectory instead of /? For example:

http://localhost/test

I don't get that running, it just happens nothing at all when you browse.

Thanks!

You can just use the sub-directory name i.e. /test.

RehanSaeed commented 4 years ago

Nathan Nathan commented on 2018-01-13 10:20:01

Hi, wonderful post.I am just starting out using Nginx and .NET Core.I have set it up on a Linux Ubuntu server.However I am facing problems with loading the images, js and css files, it gives me a 404.And also whilst I can see the home page, other paths like http://somewhere.com/About gives a 404 as well.Do I need to configure any forwarding rules in Nginx for this to work?

RehanSaeed commented 4 years ago

Joe Castro Joe Castro commented on 2018-02-11 22:05:45

Thanks for the article!!!! Good stuff !!! I modified it using nginx-rtmp-module sample code below on CentoOS :)

For Compiling Nginx

./configure --prefix=/etc/nginx             --sbin-path=/usr/sbin/nginx             --modules-path=/usr/lib64/nginx/modules             --conf-path=/etc/nginx/nginx.conf             --error-log-path=/var/log/nginx/error.log             --pid-path=/var/run/nginx.pid             --lock-path=/var/run/nginx.lock             --user=nginx             --group=nginx             --build=CentOS             --builddir=nginx-1.13.3             --with-select_module             --with-poll_module             --with-threads             --with-file-aio             --with-http_ssl_module             --with-http_v2_module             --with-http_realip_module             --with-http_addition_module             --with-http_xslt_module=dynamic             --with-http_image_filter_module=dynamic             --with-http_geoip_module=dynamic             --with-http_sub_module             --with-http_dav_module             --with-http_flv_module             --with-http_mp4_module             --with-http_gunzip_module             --with-http_gzip_static_module             --with-http_auth_request_module             --with-http_random_index_module             --with-http_secure_link_module             --with-http_degradation_module             --with-http_slice_module             --with-http_stub_status_module             --http-log-path=/var/log/nginx/access.log             --http-client-body-temp-path=/var/cache/nginx/client_temp             --http-proxy-temp-path=/var/cache/nginx/proxy_temp             --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp             --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp             --http-scgi-temp-path=/var/cache/nginx/scgi_temp             --with-mail=dynamic             --with-mail_ssl_module             --with-stream=dynamic             --with-stream_ssl_module             --with-stream_realip_module             --with-stream_geoip_module=dynamic             --with-stream_ssl_preread_module             --with-compat             --with-pcre=../pcre-8.40             --with-pcre-jit             --with-zlib=../zlib-1.2.11             --with-openssl=../openssl-1.1.0f             --with-openssl-opt=../no-nextprotoneg         --add-module=../nginx-rtmp-module             --with-debug

Mime Types

types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    application/javascript                js;
    application/atom+xml                  atom;
    application/rss+xml                   rss;

    text/mathml                           mml;
    text/plain                            txt;
    text/vnd.sun.j2me.app-descriptor      jad;
    text/vnd.wap.wml                      wml;
    text/x-component                      htc;

    image/png                             png;
    image/tiff                            tif tiff;
    image/vnd.wap.wbmp                    wbmp;
    image/x-icon                          ico;
    image/x-jng                           jng;
    image/x-ms-bmp                        bmp;
    image/svg+xml                         svg svgz;
    image/webp                            webp;

    application/font-woff                 woff;
    application/java-archive              jar war ear;
    application/json                      json;
    application/mac-binhex40              hqx;
    application/msword                    doc;
    application/pdf                       pdf;
    application/postscript                ps eps ai;
    application/rtf                       rtf;
    application/vnd.apple.mpegurl         m3u8;
    application/vnd.ms-excel              xls;
    application/vnd.ms-fontobject         eot;
    application/vnd.ms-powerpoint         ppt;
    application/vnd.wap.wmlc              wmlc;
    application/vnd.google-earth.kml+xml  kml;
    application/vnd.google-earth.kmz      kmz;
    application/x-7z-compressed           7z;
    application/x-cocoa                   cco;
    application/x-java-archive-diff       jardiff;
    application/x-java-jnlp-file          jnlp;
    application/x-makeself                run;
    application/x-perl                    pl pm;
    application/x-pilot                   prc pdb;
    application/x-rar-compressed          rar;
    application/x-redhat-package-manager  rpm;
    application/x-sea                     sea;
    application/x-shockwave-flash         swf;
    application/x-stuffit                 sit;
    application/x-tcl                     tcl tk;
    application/x-x509-ca-cert            der pem crt;
    application/x-xpinstall               xpi;
    application/xhtml+xml                 xhtml;
    application/xspf+xml                  xspf;
    application/zip                       zip;

    application/octet-stream              bin exe dll;
    application/octet-stream              deb;
    application/octet-stream              dmg;
    application/octet-stream              iso img;
    application/octet-stream              msi msp msm;

    application/vnd.openxmlformats-officedocument.wordprocessingml.document    docx;
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet          xlsx;
    application/vnd.openxmlformats-officedocument.presentationml.presentation  pptx;

    audio/midi                            mid midi kar;
    audio/mpeg                            mp3;
    audio/ogg                             ogg;
    audio/x-m4a                           m4a;
    audio/x-realaudio                     ra;

    video/3gpp                            3gpp 3gp;
    video/mp2t                            ts;
    video/mp4                             mp4;
    video/mpeg                            mpeg mpg;
    video/quicktime                       mov;
    video/webm                            webm;
    video/x-flv                           flv;
    video/x-m4v                           m4v;
    video/x-mng                           mng;
    video/x-ms-asf                        asx asf;
    video/x-ms-wmv                        wmv;
    video/x-msvideo                       avi;
}

Update nginx.conf

Configure the Nginx web server to run your ASP.NET Core site efficiently.

See https://docs.asp.net/en/latest/publishing/linuxproduction.html

See http://nginx.org/en/docs/ and https://www.nginx.com/resources/wiki/

Set another default user than root for security reasons.

user nginx;

The maximum number of connections for Nginx is calculated by:

max_clients = worker_processes * worker_c

worker_processes 1;

Maximum file descriptors that can be opened per process

This should be > worker_connections

worker_rlimit_nofile 8192;

Log errors to the following location. Feel free to change these.

error_log logs/error.log;

Log NXingx process errors to the following location. Feel free to change these.

pid logs/nginx.pid;
events {
    # When you need > 8000 * cpu_cores connections, you start optimizing
    # your OS, and this is probably the point at where you hire people
    # who are smarter than you, this is *a lot* of requests.
    worker_connections 8000;

    # This sets up some smart queueing for accept(2)'ing requests
    # Set it to "on" if you have > worker_processes
    accept_mutex off;

    # These settings are OS specific, by defualt Nginx uses select(2),
    # however, for a large number of requests epoll(2) and kqueue(2)
    # are generally faster than the default (select(2))
    # use epoll; # enable for Linux 2.6+
    # use kqueue; # enable for *BSD (FreeBSD, OS X, ..)
}

http {
# Include MIME type to file extension mappings list.
include                 mime.types;
# The default fallback MIME type.
default_type            application/octet-stream;

# Format for our log files.
log_format              main '$remote_addr - $remote_user [$time_local]  $status '
                             '"$request" $body_bytes_sent "$http_referer" '
                             '"$http_user_agent" "$http_x_forwarded_for"';

# Log requests to the following location. Feel free to change this.
access_log              logs/access.log  main;

# The number of seconds to keep a connection open.
keepalive_timeout       29;
# Defines a timeout for reading client request body.
client_body_timeout     10;
# Defines a timeout for reading client request header.
client_header_timeout   10;
# Sets a timeout for transmitting a response to the client.
send_timeout            10;
# Limit requests from an IP address to five requests per second.
# See http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone
limit_req_zone          $binary_remote_addr zone=one:10m rate=5r/s;

# Disables emitting Nginx version in error messages and in the 'Server' HTTP response header.
server_tokens           off;

# To serve static files using Nginx efficiently.
sendfile                on;
tcp_nopush              on;
tcp_nodelay             off;

# Enable GZIP compression.
gzip                    on;
# Enable GZIP maximum compression level. Ranges from 1 to 9.
gzip_comp_level         9;
# Enable GZIP over HTTP 1.0 (The default is HTTP 1.1).
gzip_http_version       1.0;
# Disable GZIP compression for IE 1 to 6.
gzip_disable            "MSIE [1-6]\."
# Enable GZIP compression for the following MIME types (text/html is included by default).
gzip_types              # Plain Text
                        text/plain
                        text/css
                        text/mathml
                        application/rtf
                        # JSON
                        application/javascript
                        application/json
                        application/manifest+json
                        application/x-web-app-manifest+json
                        text/cache-manifest
                        # XML
                        application/atom+xml
                        application/rss+xml
                        application/xslt+xml
                        application/xml
                        # Fonts
                        font/opentype
                        font/otf
                        font/truetype
                        application/font-woff
                        application/vnd.ms-fontobject
                        application/x-font-ttf
                        # Images
                        image/svg+xml
                        image/x-icon;
            # Video
            application/vnd.apple.mpegurl;
            video/mp2t;
            video/3gpp;                            
                video/mp2t;                           
            video/mp4;                             
            video/mpeg;                            
                video/quicktime;                       
                video/webm;                            
                video/x-flv;                          
                video/x-m4v;                           
                video/x-mng;                          
                video/x-ms-asf;                       
                video/x-ms-wmv;                        
                video/x-msvideo;                      

# Enables inserting the 'Vary: Accept-Encoding' response header.
gzip_vary               on;

# Configuration Use for Virtual Sites
# mkdir -p /etc/nginx/sites-available/
# mkdir -p /etc/nginx/sites-enabled/
# mkdir -p /var/www/example.com/logs/
# Create Symbolic Link
# ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf
include /etc/nginx/sites-enabled/*.conf;
server_names_hash_bucket_size 64;

# Sets configuration for a virtual server. You can have multiple virtual servers.
# See http://nginx.org/en/docs/http/ngx_http_core_module.html#server
server {

    # Listen for requests on specified port including support for HTTP 2.0.
    # See http://nginx.org/en/docs/http/ngx_http_core_module.html#listen
    listen                      80 http2 default;
    # Or, if using HTTPS, use this:
    listen                      443 http2 ssl default;
    # Configure SSL/TLS
    # See http://nginx.org/en/docs/http/configuring_https_servers.html
    ssl_certificate             /etc/ssl/certs/*.crt;
    ssl_certificate_key         /etc/ssl/certs/*.key;
    ssl_protocols               TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers   on;
    ssl_ciphers                 "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_ecdh_curve              secp384r1;
    ssl_session_cache           shared:SSL:10m;
    ssl_session_tickets         off;
    # Ensure your cert is capable before turning on SSL Stapling.
    ssl_stapling                on;
    ssl_stapling_verify         on;

    # The name of the virtual server where you can specify one or more domains that you own.
    server_name localhost;
    # server_name    example.com www.example.com *.example.com www.example.*;

    # Match incoming requests with the following path and forward them to the specified location.
    # See http://nginx.org/en/docs/http/ngx_http_core_module.html#location
    location / {
        proxy_pass              http://localhost:1025;
        proxy_pass              https://localhost:1025;

        # The default minimum configuration required for ASP.NET Core
        # See https://docs.asp.net/en/latest/publishing/linuxproduction.html?highlight=nginx#configure-a-reverse-proxy-server
        proxy_cache_bypass      $http_upgrade;
        # Turn off changing the URL's in headers like the 'Location' HTTP header.
        proxy_redirect          off;
        # Forwards the Host HTTP header.
        proxy_set_header        Host $host;
        # The Kestrel web server we are forwarding requests to only speaks HTTP 1.1.
        proxy_http_version      1.1;
        proxy_set_header        Upgrade $http_upgrade;
        # Adds the 'Connection: keep-alive' HTTP header.
        proxy_set_header        Connection keep-alive;

        # Sets the maximum allowed size of the client request body.
        client_max_body_size    10m;
        # Sets buffer size for reading client request body.
        client_body_buffer_size 128k;
        # Defines a timeout for establishing a connection with a proxied server.
        proxy_connect_timeout   90;
        # Sets a timeout for transmitting a request to the proxied server.
        proxy_send_timeout      90;
        # Defines a timeout for reading a response from the proxied server.
        proxy_read_timeout      90;
        # Sets the number and size of the buffers used for reading a response from the proxied server.
        proxy_buffers           32 4k;
        }
    }
}
RehanSaeed commented 4 years ago

Swapnil Swapnil commented on 2018-04-06 06:45:13

Hi Friend.

i need to host my ASP.NET Core 2.1 with angular5 app in nginx. i am using MongoDB database.

Please help.

RehanSaeed commented 4 years ago

Muhammad Rehan Saeed Muhammad Rehan Saeed commented on 2018-04-16 09:14:05

Hi Friend.

i need to host my ASP.NET Core 2.1 with angular5 app in nginx. i am using MongoDB database.

Please help.

Please learn to use StackOverflow like everybody else.

RehanSaeed commented 4 years ago

Andrew Simpson Andrew Simpson commented on 2019-08-06 12:03:20

Hi, I have been trying to configure this to use websockets. I have searched for quite some time, Plenty of examples using node.js but I just want to use Javascript as the client and asp.net c# as the 'other-end'. I believe it is NGINX that is stopping things working as it works under IIS

RehanSaeed commented 4 years ago

Anuj Garg Anuj Garg commented on 2019-10-21 06:28:04

Hi Rehan, Nice article! I am trying to use nginx with ASP.NET Core and it works fine except OIDC path. When it goes to signin-oidc path, it give me 504 gateway timeout. I am wondering if it is due to header length or i need to specify port to open in asp.net specifically. I have it running it in docker and it works in my Machine but not on Fargate. Any clue would help. Thanks!

BainMcKay commented 2 years ago

How do you allow nginx 'localhost' CORS access from a remote browser to web page ajax call via http://localhost or https://localhost:5001. It works in curl, but browser (Firefox, Chrome, Safari) all block localhost, even when listed as trusted by aspnetcore 6 middleware.

RehanSaeed commented 2 years ago

How do you allow nginx 'localhost' CORS access from a remote browser to web page ajax call via http://localhost or https://localhost:5001. It works in curl, but browser (Firefox, Chrome, Safari) all block localhost, even when listed as trusted by aspnetcore 6 middleware.

This sounds like a good question to ask on StackOverflow.