Nginx – create our first virtual host

I recently posted an entry related to the installation and basic configuration of Nginx web server. In this chapter we will add the configuration of our website to server. This time we will no longer have to install any additional packages in the system or use additional external repositories. Everything is limited to editing existing files and optionally creating new ones – just as in Apache, which includes the configuration of each website. Of course, I’m assuming that you have already installed the Nginx server in accordance with the instructions from the previous chapter. This entry does not concern PHP configuration – this aspect will be discussed in the next chapter.

Nginx installation and first configuration

Nginx virtual host configuration

Use PHP-FPM with Nginx

Describe and change php.ini settings

PHP-FPM – config improvements

Use strong Nginx encryption settings

Nginx optimizations, tips and tricks

Let’s say we want to add a web site that uses WordPress to our server – we are skipping PHP support for the moment. This configuration is very easy – just specify the address, port we will use, and redirect all requests to the index.php file. Apache uses the .htaccess file and mod_rewrite rules. Nginx also has the ability to rewrite requests, but it works slightly differently, as will be shown in the examples below. First, let’s see an example of a virtual host configuration. We can store it in /etc/nginx/sites-available/ and then create the symbolic link in /etc/nginx/sites-enabled/ and restart the nginx server:

nano /etc/nginx/sites-available/my_website

After make changes and write file:

ln -s /etc/nginx/sites-available/my_website /etc/nginx/sites-enabled/my_website

and server restarting:

service nginx restart

Let’s see our vhost configuration:

server {
    listen 80;

    # Website directory
    root /var/www/;

    # Error logs
    access_log /var/log/nginx/;
    error_log /var/log/nginx/;

    # Rewrite non-exist files/directories to index.php 
    location / {
        try_files $uri $uri/ /index.php?$args;

# Redirect all www requests to non-www 
server {
    listen 80;

    # Disable all logs
    access_log off;
    log_not_found off;
    error_log /dev/null crit;

    return 301$request_uri;

It’s very simple, standard vhost configuration. Every virtual host is in the server {} configuration block. Settings for specific virtual host are inside this block. First line server_name is our domain. We can use many names in one line, to use only one configuration for different domains. You can also use wildcard configuration: * Second is listening port – we use default HTTP 80 port, but on next chapters will change this to 443 and encrypted connections. Third line is our webiste root directory on server. Everyting depends where you put your website files – /var/www it’s only an default example. Remember to not use ending slash in this line! Two next lines are logs configuration. Access logs to write information about each request to our website, and second to log errors. You can configure logs format, archiving and rotating in main Nginx configuration file (/etc/nginx/nginx.conf). Default options should be good for the beginning.

Location {} configuration block is to store settings for specific directories/resources on our parent virtual host. You can create many location {} block inside server {} block. There is only „magic” to rewrite our requests to index.php file. With Apache we must use mod_rewrite, check file/directory existing using RewriteCond. There is only try_files (it isn’t „true” Nginx rewriting!). What does it mean? Nginx will try: first original $uri (file). If it doesn’t exist, Nginx will try next: $uri/ (so, directory). If it doens’t exists, request will be redirected to index.php will all arguments. Simple and clean. Of course, you can create your schemas for that – check specific files or directories. Back to location block – it can be configure using that syntax:

location [MODIFIER] PATH {
    # Our settings

PATH is clear – we use it to set path (or regular expression) for our settings. MODIFIER is optional and configures how Nginx should match our path. Possible modifiers are: none (match to beggining of request), „=„ (match only if request exactly matches our path), „~” (match with case-sensitive), „~*” (match witch case-insensitive), and „^~” (match best non regex path). There are few location examples with commands:

# Match specific file
location  = /secret_file {
    # Return error 403
    return 403;

# Match location and all data inside
location /data/ {
    # Disable access logs for this location
    access_log off; 

# Match case-insensitive extension
location ~* .(pdf|exe|zip)$ {
    # Return error 404
    return 404;

# Match best non regex path
 location ^~ /wp-admin/ {
    # Auth basic
    auth_basic            "Please enter password";
    auth_basic_user_file  /var/www/.htpasswd;

Using location with modifiers and other commands we can create very flexible configuration in each virtual host.

Sewcond server {} block is to redirect our www domain to non-www. It uses different server name, the same port, disables all logs. We can’t use „off” in error_log, so we move these logs to /dev/null and log only critical errors. Last line return 301 redirection to non-www version of our request. It’s all for simple vhost configuration. We will create more complex configuration and use rewrite rules in next chapters.