User Tools

Site Tools


web_servers:migrate_apache_to_nginx_by_converting_virtualhosts_to_server_blocks

Web Servers - Migrate Apache to Nginx by converting VirtualHosts to Server Blocks

Both Apache and Nginx have the ability to serve multiple websites.

  • On Apache the various sites to be served are configured using VirtualHosts;
  • On Nginx Server Blocks are used instead.

Install NginX

sudo apt update && sudo apt install nginx

Start and Enable NginX

Stat the nginx service and set it to be automatically launched at boot:

sudo systemctl enable --now nginx

NOTE: The server listens on port 80 by default, so to verify that it is reachable we can simply navigate to http://localhost with a web browser.


Convert Apache VirtualHost to NginX Server Block

Apache VirtualHost Directives

<VirtualHost *:80>
    ServerName   site1
    DocumentRoot /var/www/site1.com
</VirtualHost>

NOTE: This configuration is usually in /apache2/sites-available and have a .conf extention.

  • For this site to be activated, a symlink needs to be created in /etc/apache2/sites-enabled.
  • The a2ensite command is used for this:
    sudo a2ensite site1.com.conf
  • *:80: The IP address to listen on.
  • ServerName: The hostname that the server uses to identify itself.
  • DocumentRoot: The root directory which hosts the site document tree.
    • In this case, the directory is /var/www/site1.com.

NginX Server Block

server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
}

NOTE: This configuration is usually in /etc/nginx/sites-available and have a .conf extention.

  • For this site to be activated, a symlink needs to be created in /etc/enginex/sites-enabled.
    sudo ln -s /etc/nginx/sites-available/site1.com.conf /etc/nginx/sites-enabled/
  • listen: The listen directive is used to set to what address and IP the Server Block will respond to and serve the request.
    • In this case we only set *:80, which means that the Server Block will respond to request on all IPs on port 80.
  • *:80: The IP address to listen on. The * is a catch-all for all.
  • server_name: The hostname that the server uses to identify itself.
  • root: The root directory which hosts the site document tree.
    • In this case, the directory is /var/www/site1.com.

Applying configuration to a specific directory of the website

With Apache, the <Directory> directive is used:

<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    <Directory /var/www/site1.com/>
      # Directives here
    </Directory>
</VirtualHost>

The corresponding directive for an Nginx server block is location:

server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
 
        location / {
            # Directives here
        }
}

NOTE: For both Apache and NginX, the directives can be repeated in order to fine-tune the configuration.


Specifying what files should be used as index

In Apache use DirectoryIndex:

<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    <Directory /var/www/site1.com/>
      DirectoryIndex index.html index.php
    </Directory>
</VirtualHost>

In NginX use index:

server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
 
        location / {
            index index.html index.php
        }
}

NOTE: The index.html and index.php files are configured as the index.


Enabling directory listing output

If a site directory is navigated to, but none of the set index files exists in it, the default behavior is to deny access to that directory.

  • However, the web server can be configured to allow it to generate and display a list of the files existing in that directory.

In Apache, the Indexes option is enabled by using the + sign.

<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    <Directory /var/www/site1.com/>
      Options +Indexes
    </Directory>
</VirtualHost>

In NginX, the the autoindex directive is set to on.

server {
        listen 80;
        server_name site1.com;
        root /var/www/site1.com;
 
        location / {
                autoindex on;
        }
}

Restricting access to a resource

In Apache:

<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    <Directory /var/www/site1.com/>
        Require 192.168.0.0/24
    </Directory>
</VirtualHost>

NOTE: The Require directive inside a Directory stanza, allows access only from a specific subnet, for example 192.168.0.0/24.

In NginX:

<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    <Directory /var/www/site1.com/>
    <RequireAll>
        Require all granted
        Require not 192.168.0.0/24
    </RequireAll>
    </Directory>
</VirtualHost>

NOTE: Those Require directives are used to group multiple access rules and they work this way:

DirectiveTo be successful
RequireAllNo directive must fail and at least one must succeed (directive can also be neutral).
RequireAnyAt least one directive must succeed.
RequireNoneNo directive must succeed.

Why did we use the <RequireAll> directive?

  • This is because when a require directive is negated (we used not), it can only fail or return a neutral result, therefore a request cannot be authorized on the base of a negated require alone.
  • What we had to do is to put the negated Require inside a RequireAll directive, which in this case will fail since, as we stated above, for it to succeed, no directive inside of it must fail;
    • that is why we also put the Require all granted inside of it: to give it a change to succeed.
    • If we do not do this, the following error would be seen on server restart:
      AH01624:  directive contains only negative authorization directives

The equivalent configuration for an Nginx Server Block can be obtained via the allow and deny directives.

To allow access only from the subnet we used in the example above, we would write:

server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
 
        location / {
            deny all;
            allow 192.168.0.0/24;
        }
}

To deny access to requests coming from the 192.168.0.0/24 subnet, instead:

server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
 
        location / {
            deny 192.168.0.0/24;
        }
}

Specifying dedicated error and access log files

In Apache, configure error logs for the specific resource are written into a dedicated file.

<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    ErrorLog "/var/log/httpd/site1.com-error.log"
</VirtualHost>

Where the requests received by the server are logged, instead, is managed by the CustomLog directive.

  • This directive accepts two mandatory arguments:
    1. The path of the file in which the logs will be written,
    2. What will be written into the file, defined using a format string.
<VirtualHost *:80>
    ServerName   site1.com
    DocumentRoot /var/www/site1.com
    ErrorLog "/var/log/httpd/site1.com-error.log"
    CustomLog "/var/log/httpd/site1.com-access.log" "%t %h %>s"
</VirtualHost>

NOTE: The format string defines:

NotationMeaning
%tThe time the request was received.
%hThe IP address of the request.
%>sThe final status of the request.

SEE https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#formats for additional formats.

A line in the access log file, in this case, would look like this:

[01/Oct/2021:23:49:56 +0200] 127.0.0.1 200

In NginX, errors are logged using:

server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
        error_log "/var/log/nginx/site1.com-error.log";
}

Access is logged, using the access_log directive.

  • By default the messages are stored in the default combined format, but this can be changed via the log_format directive:
server {
        listen *:80;
        server_name site1.com;
        root /var/www/site1.com;
        error_log "/var/log/nginx/site1.com-error.log";
        access_log "/var/log/nginx/site1.com-access.log";
}

NOTE: Using the default log format, an access log line will look like this:

127.0.0.1 - - [01/Oct/2021:23:58:32 +0200] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0"
web_servers/migrate_apache_to_nginx_by_converting_virtualhosts_to_server_blocks.txt · Last modified: 2021/10/13 17:24 by peter

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki