Setting up virtual hosts on any sort of web server normally takes at least a few minutes and several commands (if you’re not running a control panel of some variety, and even then it normally takes a good number of clicks and checking boxes to get what you want). All of this can be quite annoying when you have to set up several of these a day.
So I put together a simple bash script to quickly provision the hosting for a new static site running on Nginx. The script was originally build for use on the Amazon AMI running on AWS. The script uses the sudo command as the password is not required for the default user on the AWS AMI, however if you are running as a non root user with access to the sudo command then you should be prompted for your password when running the script.
What does the script do:
- Creates a new vhosts entry for nginx using a basic template
- Creates a new directory for the new vhost and sets nginx as the owner
- Adds a simple index.html file to the new directory to show the site is working.
- Reloads Nginx to allow the new vhost to be picked up
How it works:
It uses the debian style set up for apache as its basis for handling vhosts with Nginx. This means under your Nginx config directory (/etc/nginx) you need to have two extra directories:
- sites-available
- sites-enabled
In the sites available dir goes the the individual config files for each vhost, each new vhost using a new file. Under the sites enabled directory goes a symlink to the config file in the sites available directory, this gives you the ability to disable sites without removing tis files or config. This all works by adding the following line to the end of the /etc/nginx/nginx.conf file (within the http section)
# Load all vhosts ! include /etc/nginx/sites-enabled/*.conf;
The hosting directory for the new site can be set by modifying the WEB_DIR value at the top of the script which defaults to /var/www
So the new hosting directory for your domain example.com ends up as:
/var/www/example_com
Whilst the original version of the script created a new user for each site and made that user the owner of the hosting directory I have removed this functionality to make the script less taylored to my needs (if needed this user creation bit could easily be re-added) . For the moment then the script grants the nginx user owner rights to the new vhost directory (which from a security perspective is not great), so you may want to modify this.
How to use it:
Simply download the tar file at the end of the this article and extract it. If your not sure how to extract a tar file either read the man pages or use the command below:
tar -xzf create_nginx_vhost.tar.gz
Once you have extracted the archive just run the create_nginx_site.sh script passing to it the domain name as the only parameter (you will need execute permissions), e.g.
./create_nginx_site.sh example.comAnd you should see an output similar to the following:
Creating hosting for: example.com Reloading nginx: [ OK ] Site Created for example.com
The script:
# Script by: Seb Dangerfield - sebdangerfield.me.uk NGINX_CONFIG='/etc/nginx/sites-available' NGINX_SITES_ENABLED='/etc/nginx/sites-enabled' WEB_DIR='/var/www' SED=`which sed` CURRENT_DIR=`dirname $0` if [ -z $1 ]; then echo "No domain name given" exit 1 fi DOMAIN=$1 # check the domain is roughly valid! PATTERN="^([[:alnum:]]([[:alnum:]\-]{0,61}[[:alnum:]])?\.)+[[:alpha:]]{2,6}$" if [[ "$DOMAIN" =~ $PATTERN ]]; then DOMAIN=`echo $DOMAIN | tr '[A-Z]' '[a-z]'` echo "Creating hosting for:" $DOMAIN else echo "invalid domain name" exit 1 fi #Replace dots with underscores SITE_DIR=`echo $DOMAIN | $SED 's/\./_/g'` # Now we need to copy the virtual host template CONFIG=$NGINX_CONFIG/$DOMAIN.conf sudo cp $CURRENT_DIR/virtual_host.template $CONFIG sudo $SED -i "s/DOMAIN/$DOMAIN/g" $CONFIG sudo $SED -i "s!ROOT!$WEB_DIR/$SITE_DIR!g" $CONFIG # set up web root sudo mkdir $WEB_DIR/$SITE_DIR sudo chown nginx:nginx -R $WEB_DIR/$SITE_DIR sudo chmod 600 $CONFIG # create symlink to enable site sudo ln -s $CONFIG $NGINX_SITES_ENABLED/$DOMAIN.conf # reload Nginx to pull in new config sudo /etc/init.d/nginx reload # put the template index.html file into the new domains web dir sudo cp $CURRENT_DIR/index.html.template $WEB_DIR/$SITE_DIR/index.html sudo $SED -i "s/SITE/$DOMAIN/g" $WEB_DIR/$SITE_DIR/index.html sudo chown nginx:nginx $WEB_DIR/$SITE_DIR/index.html echo "Site Created for $DOMAIN"
Download:
Please note both downloads contain exactly the same files
download (tar.gz)
download (zip)
Comments or Questions:
If you have any comments or questions please use the comments section below.
Hey, can you please check your tar archive is right? I’m getting an error.
The download appears to work fine. However just to make sure I have re-created the compressed tar archive and also uploaded a zip file of the files, both archives contain the same files just different formats depending on what people fancy.
Thank you Seb! This script is just what I was looking for
How would you add another argument for the IP address and have it add to listen in the .conf file?
If we pass the IP as the second argument to the script then the simplest way todo this is to add a new line into the virtual_host.template file to tell nginx which IP address to listen on as follows:
Then modify the create_site_simple.sh and add a new line in the script after line 30 (i.e. in the section “Now we need to copy the virtual host template”):