Troubleshooting NGINX and Customizing NGINX

This guide gives a basic introduction to nginx and describes some simple tasks that can be done with it. It is supposed that nginx is already installed on the reader’s machine. If it is not, see the Installing nginx page. This guide describes how to start and stop nginx, and reload its configuration, explains the structure of the configuration file and describes how to set up nginx to serve out static content, how to configure nginx as a proxy server, and how to connect it with a FastCGI application.

nginx has one master process and several worker processes. The main purpose of the master process is to read and evaluate configuration, and maintain worker processes. Worker processes do actual processing of requests. nginx employs event-based model and OS-dependent mechanisms to efficiently distribute requests among worker processes. The number of worker processes is defined in the configuration file and may be fixed for a given configuration or automatically adjusted to the number of available CPU cores

The way nginx and its modules work is determined in the configuration file. By default, the configuration file is named nginx.conf and placed in the directory /usr/local/nginx/conf/etc/nginx, or /usr/local/etc/nginx.

Starting, Stopping, and Reloading Configuration

To start nginx, run the executable file. Once nginx is started, it can be controlled by invoking the executable with the -s parameter. Use the following syntax:

nginx -s signal

Where signal may be one of the following:

  • stop — fast shutdown
  • quit — graceful shutdown
  • reload — reloading the configuration file
  • reopen — reopening the log files

For example, to stop nginx processes with waiting for the worker processes to finish serving current requests, the following command can be executed:

nginx -s quit

This command should be executed under the same user that started nginx.

Changes made in the configuration file will not be applied until the command to reload configuration is sent to nginx or it is restarted. To reload configuration, execute:

nginx -s reload

Once the master process receives the signal to reload configuration, it checks the syntax validity of the new configuration file and tries to apply the configuration provided in it. If this is a success, the master process starts new worker processes and sends messages to old worker processes, requesting them to shut down. Otherwise, the master process rolls back the changes and continues to work with the old configuration. Old worker processes, receiving a command to shut down, stop accepting new connections and continue to service current requests until all such requests are serviced. After that, the old worker processes exit.

A signal may also be sent to nginx processes with the help of Unix tools such as the kill utility. In this case a signal is sent directly to a process with a given process ID. The process ID of the nginx master process is written, by default, to the nginx.pid in the directory /usr/local/nginx/logs or /var/run. For example, if the master process ID is 1628, to send the QUIT signal resulting in nginx’s graceful shutdown, execute:

kill -s QUIT 1628

For getting the list of all running nginx processes, the ps utility may be used, for example, in the following way:

ps -ax | grep nginx

Configuration File’s Structure

nginx consists of modules which are controlled by directives specified in the configuration file. Directives are divided into simple directives and block directives. A simple directive consists of the name and parameters separated by spaces and ends with a semicolon (;). A block directive has the same structure as a simple directive, but instead of the semicolon it ends with a set of additional instructions surrounded by braces ({ and }). If a block directive can have other directives inside braces, it is called a context (examples: events, http, server, and location).

Directives placed in the configuration file outside of any contexts are considered to be in the main context. The events and http directives reside in the main context, server in http, and location in server.

The rest of a line after the # sign is considered a comment.

Serving Static Content

An important web server task is serving out files (such as images or static HTML pages). You will implement an example where, depending on the request, files will be served from different local directories: /data/www (which may contain HTML files) and /data/images (containing images). This will require editing of the configuration file and setting up of a server block inside the http block with two location blocks.

First, create the /data/www directory and put an index.html file with any text content into it and create the /data/images directory and place some images in it.

Next, open the configuration file. The default configuration file already includes several examples of the server block, mostly commented out. For now comment out all such blocks and start a new server block:

http {
    server {
    }
}

Generally, the configuration file may include several server blocks distinguished by ports on which they listen to and by server names. Once nginx decides which server processes a request, it tests the URI specified in the request’s header against the parameters of the location directives defined inside the server block.

Add the following location block to the server block:

location / {
    root /data/www;
}

This location block specifies the “/” prefix compared with the URI from the request. For matching requests, the URI will be added to the path specified in the root directive, that is, to /data/www, to form the path to the requested file on the local file system. If there are several matching location blocks nginx selects the one with the longest prefix. The location block above provides the shortest prefix, of length one, and so only if all other location blocks fail to provide a match, this block will be used.

Next, add the second location block:

location /images/ {
    root /data;
}

It will be a match for requests starting with /images/ (location / also matches such requests, but has shorter prefix).

The resulting configuration of the server block should look like this:

server {
    location / {
        root /data/www;
    }

    location /images/ {
        root /data;
    }
}

This is already a working configuration of a server that listens on the standard port 80 and is accessible on the local machine at http://localhost/. In response to requests with URIs starting with /images/, the server will send files from the /data/images directory. For example, in response to the http://localhost/images/example.png request nginx will send the /data/images/example.png file. If such file does not exist, nginx will send a response indicating the 404 error. Requests with URIs not starting with /images/ will be mapped onto the /data/www directory. For example, in response to the http://localhost/some/example.html request nginx will send the /data/www/some/example.html file.

To apply the new configuration, start nginx if it is not yet started or send the reload signal to the nginx’s master process, by executing:

nginx -s reload

In case something does not work as expected, you may try to find out the reason in access.log and error.log files in the directory /usr/local/nginx/logs or /var/log/nginx.

Setting Up a Simple Proxy Server

One of the frequent uses of nginx is setting it up as a proxy server, which means a server that receives requests, passes them to the proxied servers, retrieves responses from them, and sends them to the clients.

We will configure a basic proxy server, which serves requests of images with files from the local directory and sends all other requests to a proxied server. In this example, both servers will be defined on a single nginx instance.

First, define the proxied server by adding one more server block to the nginx’s configuration file with the following contents:

server {
    listen 8080;
    root /data/up1;

    location / {
    }
}

This will be a simple server that listens on the port 8080 (previously, the listen directive has not been specified since the standard port 80 was used) and maps all requests to the /data/up1 directory on the local file system. Create this directory and put the index.html file into it. Note that the root directive is placed in the server context. Such root directive is used when the location block selected for serving a request does not include its own root directive.

Next, use the server configuration from the previous section and modify it to make it a proxy server configuration. In the first location block, put the proxy_pass directive with the protocol, name and port of the proxied server specified in the parameter (in our case, it is http://localhost:8080):

server {
    location / {
        proxy_pass http://localhost:8080;
    }

    location /images/ {
        root /data;
    }
}

 

We will modify the second location block, which currently maps requests with the /images/ prefix to the files under the /data/images directory, to make it match the requests of images with typical file extensions. The modified location block looks like this:

location ~ \.(gif|jpg|png)$ {
    root /data/images;
}

The parameter is a regular expression matching all URIs ending with .gif.jpg, or .png. A regular expression should be preceded with ~. The corresponding requests will be mapped to the /data/images directory.

When nginx selects a location block to serve a request it first checks location directives that specify prefixes, remembering location with the longest prefix, and then checks regular expressions. If there is a match with a regular expression, nginx picks this location or, otherwise, it picks the one remembered earlier.

The resulting configuration of a proxy server will look like this:

server {
    location / {
        proxy_pass http://localhost:8080/;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

This server will filter requests ending with .gif.jpg, or .png and map them to the /data/images directory (by adding URI to the root directive’s parameter) and pass all other requests to the proxied server configured above.

To apply new configuration, send the reload signal to nginx as described in the previous sections.

There are many more directives that may be used to further configure a proxy connection.

Setting Up FastCGI Proxying

nginx can be used to route requests to FastCGI servers which run applications built with various frameworks and programming languages such as PHP.

The most basic nginx configuration to work with a FastCGI server includes using the fastcgi_pass directive instead of the proxy_pass directive, and fastcgi_param directives to set parameters passed to a FastCGI server. Suppose the FastCGI server is accessible on localhost:9000. Taking the proxy configuration from the previous section as a basis, replace the proxy_pass directive with the fastcgi_pass directive and change the parameter to localhost:9000. In PHP, the SCRIPT_FILENAME parameter is used for determining the script name, and the QUERY_STRING parameter is used to pass request parameters. The resulting configuration would be:

server {
    location / {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING    $query_string;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

This will set up a server that will route all requests except for requests for static images to the proxied server operating on localhost:9000 through the FastCGI protocol.

Starting nginx: [emerg] bind() to 1.2.3.4:80 failed (99: Cannot assign requested address)

If you’re trying to start Nginx, but it throws this error:

Starting nginx: nginx: [emerg] bind() to 1.2.3.4:80 failed (99: Cannot assign requested address)    [FAILED]

it would likely mean that the IP in question does not exist in your device. Type the following to see which IPs are in your device:

ip a

If your network was restarted, the additional IPs should be started with:

service startips start

If, for whatever reason, the IPs cannot be loaded into the device but you must still have that IP in the Nginx config, then you can set:

net.ipv4.ip_nonlocal_bind = 1

into your /etc/sysctl.conf file, and reboot.

How to find which site is using the Nginx processes

If you’re running Nginx with CustomBuild 2.0, then it’s already in the file /etc/nginx/nginx-info.conf.

Change the “allow” lines to include your IP (eg: 1.2.3.4), OR remove the line completely to allow from all.

location /nginx_status {
   # Enable nginx status page
   stub_status on;

   # Disable status page logging in access_log
   access_log off;

   # Allow access from 127.0.0.1
   allow 1.2.3.4;

   # Deny all the other connections
   deny all;
}

OR

location /secret_nginx_status {
   # Enable nginx status page
   stub_status on;

   # Disable status page logging in access_log
   access_log off;
}

Change the /secret_server-status to something hard-to guess if you use the 2nd method, since we don’t want just anyone viewing this page.

Note that the stats shown on this page are not terribly useful. They only show the number of connections, and a small handful of numbers.open in new window

The default Nginx installation does not show information on each connection like Apache does.

If needed, PHP-FPM has it’s own status pageopen in new window, which is better than nothing if you’re running Nginx.

502 bad gateway error when using Nginx with PHP-FPM

If you’re getting an error similar to “502 bad gateway”, try raising the maximum number of queued connections on a socket from the kernel side.

By default it is set to 128, so try increasing to 4096:

sysctl -w net.core.somaxconn=4096

The new value will not survive a reboot. If it worked well, make the change constant by editing the file /etc/sysctl.conf accordingly per the OS in use:

For Debian/CentOS:

net.core.somaxconn=4096

504 Gateway Time-Out error

If you’re receiving the message “504 Gateway Time-Out”, this often implies a PHP timeout.

This can usually be resolved by increasing the values for:

max_execution_time

in the php.ini, and

fastcgi_read_timeout

in /etc/nginx/nginx_limits.conf.

Restart PHP-FPM and Nginx after the change.

The default for fastcgi_read_timeout is 240 seconds (4 minutes).

Nginx is a high performance webserver used as a replacement for Apache, which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.

Nginx uses an asynchronous event-driven approach, rather than threads, to handle requests. Nginx’s modular event-driven architecture can provide more predictable performance under high loads.

HTTP proxy and Web server features (adopted to DirectAdmin’s implementation)

  • Ability to handle more than 10,000 simultaneous connections with a low memory footprint (~2.5 MB per 10k inactive HTTP keep-alive connections)
  • Handling of static files, index files and auto-indexing
  • Reverse proxy with caching
  • TLS/SSL with SNI and OCSP stapling support, via OpenSSL
  • FastCGI support with caching
  • Name- and IP address-based virtual servers
  • IPv6-compatible
  • WebSockets, which can act as a reverse proxy and perform load balancing of WebSocket applications
  • HTTP/1.1 Upgrade (101 Switching Protocols), HTTP/2 protocol support
  • URL rewriting and redirection via custom configuration

per-domain nginx=1 for Nginx-only processing with Nginx reverse proxy

If you’re running with the custombuild options.conf setting webserver=nginx_apache, where apache is behind an nginx proxy, then by default, all domains are listed in both the User nginx.conf and httpd.conf. All connections run through the nginx.conf, and some requests are passed through to apache as needed while static files are processed by nginx.

This feature lets you shut off the proxy part, just for 1 domain, such that the domain is processed 100% by nginx, without using apache at all. PHP is still enabled for the nginx-only domain, which must use php-fpm just like stand-alone nginx.

To enable this for a given domain, add:

nginx=1

to the domain’s config in:

/usr/local/directadmin/data/users/FRED/domains/DOMAIN.COM.conf

and issue a rewrite:

/usr/local/directadmin/custombuild/build rewrite_confs

JSON and Relative CMD_* calls

CMD_NGINX_TEMPLATES

View the state of a domain
CMD_ADDITIONAL_DOMAINS?action=view&domain=testdomain%2Ecom&ipp=50&json=yes&redirect=yes

is a dump of the domain.com.conf file, and will include this if enabled:

nginx=1

Also:

HAS_PER_DOMAIN_NGINX=yes

will be shown if this value is allowed to be controlled.

Saving the nginx=1 setting
CMD_DOMAIN
method: POST
action=modify
domain=testdomain.com
form_version=1.1
...
nginx=1

Save along with all other settings (php, cgi, etc), OR you can save just this item:

method: POST
action=modify
domain=testdomain.com
only_affect=nginx
nginx=1

Disabling per-domain Nginx-only processing

To disable per-domain Nginx-only processing, use either:

nginx=0

or simply omit the nginx variable entirely, as it is a checkbox, in which the absence of a value equates to ‘off’.

Within the following file:

/usr/local/directadmin/data/skins/enhanced/user/modify_domain.html

the following has been added after php:

|*if HAS_PER_DOMAIN_NGINX="yes"|
        <tr>
            <td>|LANG_NGINX_ONLY|</td>
            <td align=center><input type="checkbox" name="nginx" value="1" |NGINX_CHECKED|></td>
            <td>|LANG_NGINX_ONLY_DESC|</td>
        </tr>
|*endif|

Language tokens have been added as well to the file:

/usr/local/directadmin/data/skins/enhanced/lang/en/user/modify_domain.html

which includes:

LANG_NGINX_ONLY=Nginx-Only
LANG_NGINX_ONLY_DESC=Use only Nginx. Proxy to apache is disabled.

User selectable Nginx templates

This feature allows Users to select from pre-made templates to be inserted into the nginx server entries for common scripts like WordPress. The list of templates can be managed through DA.

This is a JSON-only feature, so Enhanced will not have it, though Evolution will.
It will apply only to domains and not to subdomains (similar to E-Mail accounts). Should you need an nginx template on a subdomain, create it as a full domain instead.

JSON and Relative CMD_* calls

CMD_NGINX_TEMPLATES

View the list of Nginx templates

To view the list of nginx templates, and to view the current locations for the domain:

CMD_NGINX_TEMPLATES
method: GET
domain=domain.com

Output will resemble the following:

{
	"locations": 
	{
		"/wordpress": 
		{
			"nginx_template": "wordpress_with_fastcgi_cache"
		}
	},
	"settings": 
	{
		"domain_nginx": "0",
		"nginx": "1",
		"nginx_proxy": "0"
	},
	"templates": 
	{
		"wordpress_with_fastcgi_cache": 
		{
			"name": "WordPress",
			"path": "/etc/nginx/templates/wordpress_with_fastcgi_cache.conf"
		}
	}
}

The domain_nginx setting will be set to 1 when:

  1. directadmin.conf has:
  • nginx=0
  • nginx_proxy=1

And…

  1. /usr/local/directadmin/data/users/fred/domains/domain.com.conf has:
  • nginx=1

If you have both settings[nginx] and settings[domain_nginx] as 0 (but nginx_proyx=1),then you’d need to throw a warning (as no POSTs will be accepted) advising the User to enable the domain nginx=1 via the only_affect=nginx

option

Saving a template location setting

To set a given location to a template, use:

CMD_NGINX_TEMPLATES
method: POST
domain=domain.com
action=save
location=/wordpress
nginx_template=wordpress_with_fastcgi_cache
Deleting a template location setting

To clear a list of template locations, use:

CMD_NGINX_TEMPLATES
method: POST
domain=domain.com
action=delete
select1=/wordpress
(select2=/otherpath)

Relative Tokens

The following global token exists:

HAVE_NGINX_TEMPLATES=yes|no

if the feature is available in the current license.

Relative Templates

CustomBuild will manage the templates in /etc/nginx/templates/*.conf.

The format of the template will be a standard nginx code to be inserted into an nginx location block. The first line of the template is a data line, and should contain something like this:

#INFO=name=WordPress

where everything after the #INFO= string is url-encoded, allowing for extra vars in the future. If you do not specify the name, DA will name it the name of the file, less .conf (wordpress_with_fastcgi_cache).

Before the Include to this file, dA will set the $template_location variable to “/wordpress”, for example, which can be used in the Included template conf.

        location ~ ^(/wordpress)(/.*)?$
        {
                set $template_location "$1/";
                Include /etc/nginx/templates/wordpress_with_fastcgi_cache.conf;
                include /usr/local/directadmin/data/users/testuser/nginx_php.conf;
        }

DirectAdmin will store the list of locations in:

/usr/local/directadmin/data/users/USERNAME/domains/DOMAIN.COM.locations.json

which is a json file, listing each location. Each location is an array, and the sub-item that applies here would be the template name, eg:

{
        "/wordpress" : {
                "nginx_template" : "wordpress_with_fastcgi_cache"
        }
}

as this leaves other options which could be set for that location in the future.

Nginx locations: new internal structure for tokens

As nginx locations are quite rigid in terms of not allowing conflicts/duplicates, we’ve hit the point where in order to allow 2 features to use the same location block, internal management is now required.

The following global token will indicate if the feature is available:

HAVE_NGINX_TEMPLATES=yes|no
Relative Templates

The templates exist here:

nginx_server.conf
nginx_server_sub.conf
nginx_server_secure.conf
nginx_server_secure_sub.conf

The old content was as follows:

|*else|
|UNIT_PROXY|
|NGINX_REDIRECTS|
|PROTECTED_DIRECTORIES|
|HOTLINK_PROTECTION|
|EXTRA_LOCATIONS|
|*endif|

And the new content is as follows:

|*else|
|HOTLINK_PROTECTION|
|EXTRA_LOCATIONS|
|LOCATION_BLOCKS|
|*endif|

Using custom global templates with Nginx

This guide will describe how to set up customized global per-User/Domain templates so that your Nginx server configuration can be changed however you need. Note that this guide is a mirror of the similar guide for Apache.

Copy the templates to the custom area:

cd /usr/local/directadmin/data/templates/custom
cp ../nginx_*.conf .

There are many templates for Nginx, so if there are any that you don’t need to change, you can delete them from the custom folder and the defaults will be used. Templates in the custom folder override the default templates.

The rest of the changes are very similar to the Apache guide and share essentially the same TOKENS. If you want to see all tokens that you have to work with, you can use the |DUMPTOKENS|open in new window token in the Nginx configuration file, issue a rewrite, and it will add all tokens and their values to your configs. Of course, this won’t be syntactically valid, but it will let you see what you can work with.

When you want to issue a rewrite to try your new configs, type:

cd /usr/local/directadmin/custombuild
./build rewrite_confs

How to add a custom module to Nginx

If you want to add any extra modules to Nginx, they’ll most likely need to be compiled in. Any module that needs to be compiled in will have a --add-module type flag which will need to be used. To add this flag, run the following:

cd /usr/local/directadmin/custombuild
mkdir -p custom/nginx
cp -fp configure/nginx/configure.nginx custom/nginx/configure.nginx

Add your --add-module line to the end of the custom/nginx/configure.nginx file, and make sure the \ character exists at the end of all lines except the last one. The \ character tells the configure line to loop to the next line, making the configure settings easier to read. Without the \ character to trigger the wrap, the next line becomes a separate command, which is not correct. Once set, type:

./build used_configs

to ensure your custom configure.nginx file is being used. Then type:

./build nginx

How to enable PUT and DELETE methods in Nginx

Use the same guide as is used for Apache as it is applicable to Nginx also.

How to force HTTPS with Nginx

If you’re running Nginx, go to Admin Level -> Custom Httpd Config -> example.com and in token |CUSTOM4|, add this code:

|*if SSL_TEMPLATE="0"|
       return 301 https://$host$request_uri;
|*endif|

How to configure a wildcard *.example.com subdomain with Nginx

This guide is an extension of the Apache version and applies to a server running just Nginx or Apache with Nginx as a proxy (nginx_proxy).

  1. Use step 1 in the other guide to setup the DNS in the same manner.
  2. Use the tool Admin Level -> Custom HTTPD Configuration -> domain.com to edit the Nginx configuration and add this code into the top text area:
|?SERVER_ALIASES=`SERVER_ALIASES` *.`DOMAIN`|
|*if SUB="zzzz"|
|?SERVER_ALIASES=`SERVER_ALIASES` *.`DOMAIN`|
|*endif|

How to setup webmail.example.com with Nginx

Similar to the Apache version of this guide, Nginx has the ability to set up a webmail.domain.com subdomain using the templates.

In this example, we’ll be setting up a subdomain for Roundcube, so adjust the value on the left as desired (eg: roundcube or any other script you have in /var/www/html).

  1. You’ll need to setup the server section for the webmail subdomain. This can be accomplished by adding a 2nd server section below the domain’s main server section.
cd /usr/local/directadmin/data/templates
cp nginx_server.conf custom
cp nginx_server_secure.conf custom
cd custom
server
{
       listen |IP|:|PORT_80|;
       |MULTI_IP|

       server_name webmail.|DOMAIN|;

       root /var/www/html/roundcube;
       index index.php index.html index.htm;
       access_log /var/log/nginx/domains/|DOMAIN|.log;
       access_log /var/log/nginx/domains/|DOMAIN|.bytes bytes;
       error_log /var/log/nginx/domains/|DOMAIN|.error.log;

|*if HAVE_PHP1_FPM="1"|
       # use fastcgi for all php files
       location ~ \.php$
       {
               try_files $uri =404;
               fastcgi_split_path_info ^(.+\.php)(/.+)$;
               include /etc/nginx/fastcgi_params;
               fastcgi_index index.php;
               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
               include /etc/nginx/nginx_limits.conf;

               if (-f $request_filename)
               {
                       fastcgi_pass unix:/usr/local/php|PHP1_RELEASE|/sockets/webapps.sock;
               }
       }
|*endif|

|*if HAVE_NGINX_PROXY="1"|
       location /
       {
               # access_log off;
               proxy_pass http://127.0.0.1:|PORT_8080|;
               proxy_set_header X-Client-IP      $remote_addr;
               proxy_set_header X-Accel-Internal /nginx_static_files;
               proxy_set_header Host             $host;
               proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
       }
       location /nginx_static_files/
       {
               # access_log  /var/log/nginx/access_log_proxy;
               alias       /var/www/html/roundcube/;
               internal;
       }
|*endif|

       # deny access to apache .htaccess files
       location ~ /\.ht
       {
               deny all;
       }
}
  1. Also modify the secure host nginx_server_secure.conf file. Add:
server
{
       listen |IP|:|PORT_443| ssl|SPACE_HTTP2|;
       |MULTI_IP|

       server_name webmail.|DOMAIN|;

       root /var/www/html/roundcube;
       index index.php index.html index.htm;
       access_log /var/log/nginx/domains/|DOMAIN|.log;
       access_log /var/log/nginx/domains/|DOMAIN|.bytes bytes;
       error_log /var/log/nginx/domains/|DOMAIN|.error.log;

        ssl_certificate |CERT|;
        ssl_certificate_key |KEY|;

|*if HAVE_PHP1_FPM="1"|
       # use fastcgi for all php files
       location ~ \.php$
       {
               try_files $uri =404;
               fastcgi_split_path_info ^(.+\.php)(/.+)$;
               include /etc/nginx/fastcgi_params;
               fastcgi_index index.php;
               fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
               include /etc/nginx/nginx_limits.conf;

               if (-f $request_filename)
               {
                       fastcgi_pass unix:/usr/local/php|PHP1_RELEASE|/sockets/webapps.sock;
               }
       }
|*endif|

|*if HAVE_NGINX_PROXY="1"|
       location /
       {
                proxy_buffering |PROXY_BUFFERING|;
                proxy_pass https://|PROXY_IP|:|PORT_8081|;
                proxy_set_header X-Client-IP      $remote_addr;
                proxy_set_header X-Accel-Internal /nginx_static_files;
                proxy_set_header Host             $host;
                proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_hide_header Upgrade;

       }
       location /nginx_static_files/
       {
               # access_log  /var/log/nginx/access_log_proxy;
               alias       /var/www/html/roundcube/;
               internal;
       }
|*endif|

       # deny access to apache .htaccess files
       location ~ /\.ht
       {
               deny all;
       }
}
  1. Save, exit, then rewrite users’ nginx.conf files with:
cd /usr/local/directadmin/custombuild
./build rewrite_confs
  1. You’ll also need to setup the DNS portion.
cd /usr/local/directadmin/data/templates
cp dns_a.conf custom
cd custom
echo "webmail=|IP|" >> dns_a.conf

This will setup the webmail A record for new DNS zones. For existing DNS zones, you’ll have to manually add the webmail A record to point to the domains’ IPs.

How to activate web cache. Cache-Control HTTP headers

For a bit of threory, please check the apache section.

Activating per domain

Per domain caching can be activated via DirectAdmin admin page -> Custom HTTPD configuration -> find a domain -> nginx.conf , click CUSTOMIZE and in the CUSTOM3 tab, enter the following:

location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico)$ { expires 30d; add_header Cache-Control "public, no-transform"; }
location ~* \.(jpg|jpeg|gif|png|svg)$ {expires 365d;}
location ~* \.(pdf|css|html|js|swf)$ {expires 2d;}

Activating for all domains

To activate globally for all domains, create a directory:

mkdir -p /usr/local/directadmin/data/templates/custom/
cd /usr/local/directadmin/data/templates/custom/

And create a file called cust_nginx.CUSTOM.post, insert the same code as used above for activating for a single domain, and rewrite configs:

cd /usr/local/directadmin/custombuild
./build rewrite_confs

How to install the Pagespeed Nginx module

Mod_pagespeed is an open-source Apache HTTP Server (or Nginx) module, which automatically applies chosen filters to pages and associated assets such as stylesheets, JavaScript, and HTML files, as well as to images and website cache requirements.

One major advantage of this module is that it does not require modifications to existing content or workflow, meaning that all internal optimizations and changes to files are made on the server side, presenting modified files directly to the user. Each of 40+ filters correspond to one of Google’s web performance best practices rules.

Tested with Nginx on CentOS 8:

  1. Follow the official documentation concerning the module installation from https://www.modpagespeed.com/doc/build_ngx_pagespeed_from_sourceopen in new window (see the “Build instructions” section):
  • Check https://www.modpagespeed.com/doc/release_notesopen in new window for the latest version (as of today it is “1.13.35.2-stable“):
NPS_VERSION=1.13.35.2-stable
cd
wget https://github.com/apache/incubator-pagespeed-ngx/archive/v${NPS_VERSION}.zip
unzip v${NPS_VERSION}.zip
nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d)
cd "$nps_dir"
NPS_RELEASE_NUMBER=${NPS_VERSION/beta/}
NPS_RELEASE_NUMBER=${NPS_VERSION/stable/}
psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.tar.gz
[ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
wget ${psol_url}
tar -xzvf $(basename ${psol_url})
  1. Customize the Nginx config file to add the external module:
cd /usr/local/directadmin/custombuild/
mkdir -p custom/nginx
cp configure/nginx/configure.nginx custom/nginx/

Open the custom/nginx/configure.nginx file and add the following option before the last string:

"--add-module=/root/incubator-pagespeed-ngx-1.13.35.2-stable" \

And build nginx:

./build update
./build nginx

When completed, you should see the “–add-module=/root/incubator-pagespeed-ngx-1.13.35.2-stable” in the output of:

nginx -V
  1. Create the working directory:
mkdir -p /var/cache/ngx_pagespeed

Open the /etc/nginx/nginx-includes.conf file and add the following to enable the module globally:

pagespeed on;
pagespeed FileCachePath /var/cache/ngx_pagespeed;
pagespeed EnableFilters flatten_css_imports;

And restart Nginx:

service nginx restart
  1. Test if it is working with:
curl -Is domain.com | grep X-Page-Speed

You should be able to find text similar to the following in curl’s output:

X-Page-Speed: 1.13.35.2-0

Adding security headers to get A+ rating

This guide is similar to the apache guide for adding security headers, but is tailored to the Nginx webserver. You may refer to the mentioned Apache guide for generalized information regarding security headers and online tools for testing them. Here are the instructions for accomplishing the same with Nginx:

  1. Create the /usr/local/directadmin/data/templates/custom/cust_nginx.CUSTOM.post file
  2. Post the code:
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1";
    add_header X-Download-Options "noopen";
    add_header X-Permitted-Cross-Domain-Policies "master-only";
    add_header X-DNS-Prefetch-Control "on";
    add_header Referrer-Policy "no-referrer-when-downgrade";
    add_header Strict-Transport-Security "max-age=31536000";
    add_header Content-Security-Policy "block-all-mixed-content";
    add_header Permissions-Policy 'geolocation=*, midi=(), sync-xhr=(self "https://|DOMAIN|" "https://www.|DOMAIN|"), microphone=(), camera=(), magnetometer=(), gyroscope=(), payment=(), fullscreen=(self "https://|DOMAIN|" "https://www.|DOMAIN|" )';
  1. And rewrite configs:
cd /usr/local/directadmin/custombuild/
./build rewrite_confs

How to enable brotli compression

  1. Extract brotli under any path you prefer. In this case I chose to to extract it in the base of the custombuild directory.
cd /usr/local/directadmin/custombuild
mkdir brotli
git clone https://github.com/google/ngx_brotli.git brotli
cd brotli && git submodule update --init && cd .
  1. Add a custom add-module directive.
mkdir -p custom/nginx
cp -p ./configure/nginx/configure.nginx custom/nginx/

Add the following somewhere before the last configuration line in custom/nginx/configure.nginx

"--add-module=/usr/local/directadmin/custombuild/brotli" \

make sure to substitute /usr/local/directadmin/custombuild/brotli with whatever path it’s been extracted under.

  1. rebuild nginx
./build update
./build nginx

This should have compiled nginx with the brotli module.

You can configure brotli by modifying /etc/nginx/nginx-includes.conf. Refer to the documentation found hereopen in new window.

  1. To test that the configuration was successful, add the following to /etc/nginx/nginx-includes.conf:
brotli on;
brotli_static on;

Restart nginx

service nginx restart

curl one of your domains (exampledomain.com in this example).

curl -kL -I -H 'Accept-Encoding: br' http://exampledomain.com 2>&1 | grep -i encoding

If successful, the following output should be returned

Content-Encoding: br

To Get Daily Health Newsletter

We don’t spam! Read our privacy policy for more info.

Download Mobile Apps
Follow us on Social Media
© 2012 - 2025; All rights reserved by authors. Powered by Mediarx International LTD, a subsidiary company of Rx Foundation.
RxHarun
Logo