Set up a new virtual host (server block) on your Nginx server.

Leave reply

In one of our previous tutorials we explained How to install and configure LNMP (Nginx, MySQL and PHP) server on a Debian 6 (squeeze) VPS, now we’re going to look at how to set up a new server block (virtual host) for each new domain.

Note: “VirtualHost” is an Apache term. Nginx does not have Virtual hosts, it has “Server Blocks” that use the server_name and listen directives to bind to tcp sockets.

The following script can be used to set up a new server block on your Nginx server.

#!/usr/bin/env bash
#
# Nginx - new server block
# http://rosehosting.com

# Functions
ok() { echo -e '\e[32m'$1'\e[m'; } # Green
die() { echo -e '\e[1;31m'$1'\e[m'; exit 1; }

# Variables
NGINX_AVAILABLE_VHOSTS='/etc/nginx/sites-available'
NGINX_ENABLED_VHOSTS='/etc/nginx/sites-enabled'
WEB_DIR='/var/www'
WEB_USER='www-data'

# Sanity check
[ $(id -g) != "0" ] && die "Script must be run as root."
[ $# != "1" ] && die "Usage: $(basename $0) domainName"

# Create nginx config file
cat > $NGINX_AVAILABLE_VHOSTS/$1 <<EOF
server {
  server_name $1;
  listen 80;
  root $WEB_DIR/$1/public_html;
  access_log $WEB_DIR/$1/logs/access.log;
  error_log $WEB_DIR/$1/logs/error.log;
  index index.html index.php;
  location / {
    try_files \$uri \$uri/ @rewrites;
  }
  location @rewrites {
    rewrite ^ /index.php last;
  }
  location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
    access_log off;
    expires max;
  }
  location ~ /\.ht {
    deny  all;
  }
  location ~ \.php {
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
  }
}
EOF

# Creating {public,log} directories
mkdir -p $WEB_DIR/$1/{public_html,logs}

# Creating index.html file
cat > $WEB_DIR/$1/public_html/index.html <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
        <title>$1</title>
        <meta charset="utf-8" />
</head>
<body class="container">
        <header><h1>$1<h1></header>
        <div id="wrapper"><p>Hello World</p></div>
        <footer>© $(date +%Y)</footer>
</body>
</html>
EOF

# Changing permissions
chown -R $WEB_USER:$WEB_USER $WEB_DIR/$1

# Enable site by creating symbolic link
ln -s $NGINX_AVAILABLE_VHOSTS/$1 $NGINX_ENABLED_VHOSTS/$1

# Restart
echo "Do you wish to restart nginx?"
select yn in "Yes" "No"; do
    case $yn in
        Yes ) /etc/init.d/nginx restart ; break;;
        No ) exit;;
    esac
done

ok "Site Created for $1"

Here’s what it does, in a nutshell:

  1. Creates a new directory for the site (/var/www/DOMAIN.COM/public_html)
  2. Creates a new directory for log files (/var/www/DOMAIN.COM/logs)
  3. Sets correct owner/group.
  4. Creates a simple index.html file to show the site is working.
  5. Asks for restart.

To use the script type:

./nginx_vhost.sh  newdomain.com

The script should work on Debian, Ubuntu and closely related distributions.

PS. If you liked this post please share it with your friends on the social networks using the buttons on the left or simply leave a reply below. Thanks.

5 Responses to “Set up a new virtual host (server block) on your Nginx server.”

  1. How to install LAMP (Linux Apache MySQL and PHP) on CentOS 6 with phpMyAdmin and APC cache | RoseHosting.com Blog

    [...] LAMP stack to host multiple domains using Apache’s ‘Virtual Host Directives’ as we showed you how to do that if you’re using the Nginx webserver. We will also describe how to enable SSL (secure socket layer) for your website(s), so stay [...]

    Reply
  2. Faisal Humayun

    Hi,
    Great idea. A question about the PHP handling.
    Wouldn’t different domains require the port to change (e.g domain 1 = 9000, domain 2 = 9001, etc)?
    Cheers,
    Faisal

    Reply
    • admin

      hi,

      it depends on how you’ve set-up your fpm pools. if you’re using different pools for your domains then you need to adjust your server blocks appropriately.

      Reply
  3. KS

    Hey, thanks for this script! It works pretty well, but I’m running into an issue with subdomains.

    I used the script to set up a.com, and that works. Then I used it again to set up sub.a.com, and the script ran fine and the correct files exist, and nginx restarted successfully. The problem is that sub.a.com, even though it has a separate server_block, just points to a.com directly. I’m not really sure how to troubleshoot this?

    Reply
    • admin

      Please take a look at your ‘sub.a.com’ virtual host (server block) and make sure that ‘server_name’ and ‘root’ directives are set properly. Also, check your nginx error log file for any error messages.

      Reply

Leave a Reply