{"id":1764,"date":"2019-09-24T23:56:30","date_gmt":"2019-09-24T15:56:30","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=1764"},"modified":"2020-05-12T13:32:23","modified_gmt":"2020-05-12T05:32:23","slug":"understanding-the-default-nginx-virtual-host-or-server-configuration","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/understanding-the-default-nginx-virtual-host-or-server-configuration\/","title":{"rendered":"Understanding the default Nginx virtual host (or server) configuration"},"content":{"rendered":"<p>After you had installed <a href=\"http:\/\/www.nginx.org\" rel=\"noopener\" target=\"_blank\">Nginx<\/a>, one of the first thing to do is to check whether it is running ok. <\/p>\n<p>One way to do so is to use your browser to send a <a href=\"https:\/\/www.techcoil.com\/glossary\/http-request\/\" rel=\"noopener\" target=\"_blank\">HTTP request<\/a> to test it.<\/p>\n<p>If you had installed Nginx on your local machine, then you may enter <a href=\"http:\/\/localhost\" rel=\"noopener\" target=\"_blank\">http:\/\/localhost<\/a> or <a href=\"http:\/\/localhost\" rel=\"noopener\" target=\"_blank\">http:\/\/127.0.0.1<\/a> into the location bar of your browser.<\/p>\n<p>When you had setup Nginx on a separate machine on your home network, you may also enter http:\/\/&lt;ip_address_of_the_machine&gt; in the location bar of your browser. For example, in <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-host-a-wordpress-website-on-a-raspberry-pi-with-raspbian-buster-lite-and-nginx\/\" rel=\"noopener\" target=\"_blank\">how to host a WordPress website on a Raspberry Pi with Raspbian Buster Lite and Nginx<\/a>, I had entered <a href=\"http:\/\/192.168.1.114\" rel=\"noopener\" target=\"_blank\">http:\/\/192.168.1.114<\/a> as the location to test out the Nginx server running on my Raspberry Pi.<\/p>\n<p>So be it <strong>http:\/\/localhost<\/strong>, <strong>http:\/\/127.0.0.1<\/strong>, <strong>http:\/\/&lt;ip_address_of_the_machine&gt;<\/strong>, you will always see this page on your browser screen:<\/p>\n<p><img decoding=\"async\" width=\"579\" height=\"259\" src=\"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/default-welcome-page-of-Nginx-1.14.2.gif\" alt=\"default welcome page of Nginx 1.14.2\" class=\"aligncenter size-full wp-image-1756\" \/><\/p>\n<p>In case you are wondering why your Nginx behaves this way, this post will explain what the default Nginx Virtual Host configuration does to Nginx.<\/p>\n<h2>Where is your Nginx configuration file located at?<\/h2>\n<p>In order to know what the default Nginx Virtual Host configurations does, we need to find the file that contain them. Since Nginx process configurations from a file named as <code>nginx.conf<\/code>, we can use the <code>find<\/code> command to find it.<\/p>\n<p>Given that, run the following command in your terminal to find <code>nginx.conf<\/code>:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nsudo find \/ -name nginx.conf\r\n<\/pre>\n<p>Typically, you can find the file in either <code>\/usr\/local\/nginx\/conf<\/code>, <code>\/etc\/nginx<\/code>, or <code>\/usr\/local\/etc\/nginx<\/code>.<\/p>\n<h2>Looking for the default configuration file that came with your Nginx installation<\/h2>\n<p>Once you know where <code>nginx.conf<\/code> is, you can open up the configuration file to check its content. For example, on a Debian based operating system, I will run the following command to check the main configuration file:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\"> \r\ncat \/etc\/nginx\/nginx.conf\r\n<\/pre>\n<p>When this command was ran on my <a href=\"https:\/\/www.techcoil.com\/blog\/tag\/raspbian-buster-lite\/\" rel=\"noopener\" target=\"_blank\">Raspbian Buster Lite<\/a>, I got the following content:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nuser www-data;\r\nworker_processes auto;\r\npid \/run\/nginx.pid;\r\ninclude \/etc\/nginx\/modules-enabled\/*.conf;\r\n\r\nevents {\r\n\tworker_connections 768;\r\n\t# multi_accept on;\r\n}\r\n\r\nhttp {\r\n\r\n\t##\r\n\t# Basic Settings\r\n\t##\r\n\r\n\tsendfile on;\r\n\ttcp_nopush on;\r\n\ttcp_nodelay on;\r\n\tkeepalive_timeout 65;\r\n\ttypes_hash_max_size 2048;\r\n\t# server_tokens off;\r\n\r\n\t# server_names_hash_bucket_size 32;\r\n\t# server_name_in_redirect off;\r\n\r\n\tinclude \/etc\/nginx\/mime.types;\r\n\tdefault_type application\/octet-stream;\r\n\r\n\t##\r\n\t# SSL Settings\r\n\t##\r\n\r\n\tssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE\r\n\tssl_prefer_server_ciphers on;\r\n\r\n\t##\r\n\t# Logging Settings\r\n\t##\r\n\r\n\taccess_log \/var\/log\/nginx\/access.log;\r\n\terror_log \/var\/log\/nginx\/error.log;\r\n\r\n\t##\r\n\t# Gzip Settings\r\n\t##\r\n\r\n\tgzip on;\r\n\r\n\t# gzip_vary on;\r\n\t# gzip_proxied any;\r\n\t# gzip_comp_level 6;\r\n\t# gzip_buffers 16 8k;\r\n\t# gzip_http_version 1.1;\r\n\t# gzip_types text\/plain text\/css application\/json application\/javascript text\/xml application\/xml application\/xml+rss text\/javascript;\r\n\r\n\t##\r\n\t# Virtual Host Configs\r\n\t##\r\n\r\n\tinclude \/etc\/nginx\/conf.d\/*.conf;\r\n\tinclude \/etc\/nginx\/sites-enabled\/*;\r\n}\r\n\r\n\r\n#mail {\r\n#\t# See sample authentication script at:\r\n#\t# http:\/\/wiki.nginx.org\/ImapAuthenticateWithApachePhpScript\r\n# \r\n#\t# auth_http localhost\/auth.php;\r\n#\t# pop3_capabilities &quot;TOP&quot; &quot;USER&quot;;\r\n#\t# imap_capabilities &quot;IMAP4rev1&quot; &quot;UIDPLUS&quot;;\r\n# \r\n#\tserver {\r\n#\t\tlisten     localhost:110;\r\n#\t\tprotocol   pop3;\r\n#\t\tproxy      on;\r\n#\t}\r\n# \r\n#\tserver {\r\n#\t\tlisten     localhost:143;\r\n#\t\tprotocol   imap;\r\n#\t\tproxy      on;\r\n#\t}\r\n#}\r\n<\/pre>\n<p>Since we are investigating the default Nginx Virtual Host configurations, check the section commented with <strong>Virtual Host Configs<\/strong> to see what is going on. In case you are wondering, comments in Nginx configurations start with a <strong>#<\/strong> character. <\/p>\n<p>Given that, we can see that the main configuration file will include:<\/p>\n<ul>\n<li>any configuration file ending with <code>.conf<\/code> inside the <code>\/etc\/nginx\/conf.d\/<\/code> directory.<\/li>\n<li>all configuration files inside the <code>\/etc\/nginx\/sites-enabled\/<\/code> directory.<\/li>\n<\/ul>\n<p>Given these points, we can then look inside the <code>\/etc\/nginx\/conf.d\/<\/code> and <code>\/etc\/nginx\/sites-enabled\/<\/code> directories for the default configuration file.<\/p>\n<h2>Understanding the Nginx default configuration file<\/h2>\n<p>Within those two directories, you should be able to find a file that contain the default Virtual Host configurations. In the case of my Raspbian Buster Lite operating system, I found a symbolic link <code>\/etc\/nginx\/sites-enabled\/default<\/code> that points to <code>\/etc\/nginx\/sites-available\/default<\/code>. When we have such a file organization, we can remove the default Nginx configurations without deleting the actual file.<\/p>\n<p>Let's run the following command to see what is in the default Nginx configuration file:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\ncat \/etc\/nginx\/sites-available\/default\r\n<\/pre>\n<p>After running the above command, you should get something similar to the following:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n##\r\n# You should look at the following URL's in order to grasp a solid understanding\r\n# of Nginx configuration files in order to fully unleash the power of Nginx.\r\n# https:\/\/www.nginx.com\/resources\/wiki\/start\/\r\n# https:\/\/www.nginx.com\/resources\/wiki\/start\/topics\/tutorials\/config_pitfalls\/\r\n# https:\/\/wiki.debian.org\/Nginx\/DirectoryStructure\r\n#\r\n# In most cases, administrators will remove this file from sites-enabled\/ and\r\n# leave it as reference inside of sites-available where it will continue to be\r\n# updated by the nginx packaging team.\r\n#\r\n# This file will automatically load configuration files provided by other\r\n# applications, such as Drupal or WordPress. These applications will be made\r\n# available underneath a path with that package name, such as \/drupal8.\r\n#\r\n# Please see \/usr\/share\/doc\/nginx-doc\/examples\/ for more detailed examples.\r\n##\r\n\r\n# Default server configuration\r\n#\r\nserver {\r\n\tlisten 80 default_server;\r\n\tlisten &#x5B;::]:80 default_server;\r\n\r\n\t# SSL configuration\r\n\t#\r\n\t# listen 443 ssl default_server;\r\n\t# listen &#x5B;::]:443 ssl default_server;\r\n\t#\r\n\t# Note: You should disable gzip for SSL traffic.\r\n\t# See: https:\/\/bugs.debian.org\/773332\r\n\t#\r\n\t# Read up on ssl_ciphers to ensure a secure configuration.\r\n\t# See: https:\/\/bugs.debian.org\/765782\r\n\t#\r\n\t# Self signed certs generated by the ssl-cert package\r\n\t# Don't use them in a production server!\r\n\t#\r\n\t# include snippets\/snakeoil.conf;\r\n\r\n\troot \/var\/www\/html;\r\n\r\n\t# Add index.php to the list if you are using PHP\r\n\tindex index.html index.htm index.nginx-debian.html;\r\n\r\n\tserver_name _;\r\n\r\n\tlocation \/ {\r\n\t\t# First attempt to serve request as file, then\r\n\t\t# as directory, then fall back to displaying a 404.\r\n\t\ttry_files $uri $uri\/ =404;\r\n\t}\r\n\r\n\t# pass PHP scripts to FastCGI server\r\n\t#\r\n\t#location ~ \\.php$ {\r\n\t#\tinclude snippets\/fastcgi-php.conf;\r\n\t#\r\n\t#\t# With php-fpm (or other unix sockets):\r\n\t#\tfastcgi_pass unix:\/run\/php\/php7.3-fpm.sock;\r\n\t#\t# With php-cgi (or other tcp sockets):\r\n\t#\tfastcgi_pass 127.0.0.1:9000;\r\n\t#}\r\n\r\n\t# deny access to .htaccess files, if Apache's document root\r\n\t# concurs with nginx's one\r\n\t#\r\n\t#location ~ \/\\.ht {\r\n\t#\tdeny all;\r\n\t#}\r\n}\r\n\r\n\r\n# Virtual Host configuration for example.com\r\n#\r\n# You can move that to a different file under sites-available\/ and symlink that\r\n# to sites-enabled\/ to enable it.\r\n#\r\n#server {\r\n#\tlisten 80;\r\n#\tlisten &#x5B;::]:80;\r\n#\r\n#\tserver_name example.com;\r\n#\r\n#\troot \/var\/www\/example.com;\r\n#\tindex index.html;\r\n#\r\n#\tlocation \/ {\r\n#\t\ttry_files $uri $uri\/ =404;\r\n#\t}\r\n#}\r\n<\/pre>\n<p>Indeed, by looking at the information provided in this file, we can learn a lot about the Nginx server. If you want to be more proficient with Nginx, then you will want to access the resources provided in the comments.<\/p>\n<p>However, the goal of this post is to understand what the default Nginx virtual host (or server) configuration does to our server. So let us focus on that for the moment.<\/p>\n<p>From the configuration file, we can see that there is only one <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_core_module.html#server\" rel=\"noopener\" target=\"_blank\">server block<\/a> that is not commented out. Therefore, this is the configuration block that Nginx will take in.<\/p>\n<p>The first two uncommented statements tell Nginx to listen to network packets at port 80 of the computer that it is running on:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n\tlisten 80 default_server;\r\n\tlisten &#x5B;::]:80 default_server;\r\n<\/pre>\n<p>The first statement is for the case of a network interface holding an IPv4 address and the second one is for the case of a network interface holding an IPv6 address. In addition to that, the <code>default_server<\/code> parameter states that this server block will be used as the default configuration for Nginx. <\/p>\n<p>Next,<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nroot \/var\/www\/html;\r\n<\/pre>\n<p>tells Nginx to look inside the <strong>\/var\/www\/html<\/strong> directory on the server to look for files to serve HTTP requests directed at this server block. <\/p>\n<p>After that,<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nserver_name _;\r\n<\/pre>\n<p>marks the server block as a \"catch all\" block. Whenever Nginx cannot find any server block to match an incoming HTTP request, this server block will be used for deciding how to serve that request.<\/p>\n<p>Finally,<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n    location \/ {\r\n        # First attempt to serve request as file, then\r\n        # as directory, then fall back to displaying a 404.\r\n        try_files $uri $uri\/ =404;\r\n    }\r\n<\/pre>\n<p>will get Nginx to look for a file inside \/var\/www\/html directory to return as the <a href=\"https:\/\/www.techcoil.com\/glossary\/http-response\/\" rel=\"noopener\" target=\"_blank\">HTTP response<\/a> for the incoming HTTP request. In case there is nothing to return, Nginx will return a HTTP response with a 404 status.<\/p>\n<p>But how does the Nginx welcome page gets returned when we try to access the root url? If you trace the configurations from the main file, then you will see the following configuration:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nindex index.html index.htm index.nginx-debian.html;\r\n<\/pre>\n<p>This will cause Nginx to return one of the following files inside the root directory, if available:<\/p>\n<ul>\n<li><strong>index.html<\/strong><\/li>\n<li><strong>index.htm<\/strong><\/li>\n<li><strong>index.nginx-debian.html<\/strong><\/li>\n<\/ul>\n<p>Since there is a file named as <strong>index.nginx-debian.html<\/strong> inside <strong>\/var\/www\/html<\/strong>, the contents of the file will be returned when we try to access the root url.<\/p>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-ss\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-ss&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-ss&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1764&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>After you had installed <a href=\"http:\/\/www.nginx.org\" rel=\"noopener\" target=\"_blank\">Nginx<\/a>, one of the first thing to do is to check whether it is running ok. <\/p>\n<p>One way to do so is to use your browser to send a <a href=\"https:\/\/www.techcoil.com\/glossary\/http-request\/\" rel=\"noopener noreferrer\" target=\"_blank\">HTTP request<\/a> to test it.<\/p>\n<p>If you had installed Nginx on your local machine, then you may enter <a href=\"http:\/\/localhost\" rel=\"noopener\" target=\"_blank\">http:\/\/localhost<\/a> or <a href=\"http:\/\/localhost\" rel=\"noopener\" target=\"_blank\">http:\/\/127.0.0.1<\/a> into the location bar of your browser.<\/p>\n<p>When you had setup Nginx on a separate machine on your home network, you may also enter http:\/\/&lt;ip_address_of_the_machine&gt; in the location bar of your browser. For example, in <a href=\"https:\/\/www.techcoil.com\/blog\/how-to-host-a-wordpress-website-on-a-raspberry-pi-with-raspbian-buster-lite-and-nginx\/\" rel=\"noopener\" target=\"_blank\">how to host a WordPress website on a Raspberry Pi with Raspbian Buster Lite and Nginx<\/a>, I had entered <a href=\"http:\/\/192.168.1.114\" rel=\"noopener\" target=\"_blank\">http:\/\/192.168.1.114<\/a> as the location to test out the Nginx server running on my Raspberry Pi.<\/p>\n<p>So be it <strong>http:\/\/localhost<\/strong>, <strong>http:\/\/127.0.0.1<\/strong>, <strong>http:\/\/&lt;ip_address_of_the_machine&gt;<\/strong>, you will always see this page on your browser screen:<\/p>\n<p><img decoding=\"async\" width=\"579\" height=\"259\" src=\"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/default-welcome-page-of-Nginx-1.14.2.gif\" alt=\"default welcome page of Nginx 1.14.2\" class=\"aligncenter size-full wp-image-1756\" \/><\/p>\n<p>In case you are wondering why your Nginx behaves this way, this post will explain what the default Nginx Virtual Host configuration does to Nginx.<\/p>\n","protected":false},"author":1,"featured_media":1756,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[4],"tags":[23,511,225,195,438,57],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/default-welcome-page-of-Nginx-1.14.2.gif","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-ss","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/1764"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=1764"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/1764\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1756"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=1764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=1764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=1764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}