Step 3: Scripting an Nginx Site
Table of Contents
Objective: Create an Nginx site using a script.
Creating shell scripts are easy and useful! Let’s demonstrate how.
Note
These commands are from Nginx Quick References
Setting up the Script
First, let’s create a
scripts
directory in our home folder. We can use this directory to store all of our scripts.
mkdir ~/scripts
Next, we’ll create the file.
touch ~/scripts/create-nginx-reverse-proxy.sh
Edit the file and add the shebang.
#!/bin/bash
Let’s add a welcome message to the user. Not necessary, but a nice touch.
echo "" echo "-----------------------------------" echo "Welcome to our Nginx Site Builder!" echo "-----------------------------------" echo ""
Execute the file to verify that it runs without errors.
Prompt the User
Now, let’s prompt the user for some information.
Use your own domain name to personalize it.
Note
As a personal preference, I capitalize variables to identify them easily.
# Default values FQD=sub.jj8i.cc PORT=8888 #[] denotes the default value read -r -p "Please enter the fully qualified name of the site [$FQD]: " RESPONSE if [ -n "$RESPONSE" ]; then FQD=$RESPONSE fi read -r -p "Enter the port of the reverse proxy [$PORT]: " RESPONSE if [ -n "$RESPONSE" ]; then PORT=$RESPONSE fi # Display output echo "" echo "Creating reverse proxy for $FQD -> localhost:$PORT" echo ""
Run the script to verify that it operates correctly before continuing.
Expected Output---------------------------------- Welcome to our Nginx Site Builder! ---------------------------------- Please enter the fully qualified name of the site [sub.jj8i.cc]: test.jj8i.cc Enter the port of the reverse proxy [8888]: 8901 Creating reverse proxy for test.jj8i.cc -> localhost:8901 root@vps298933:~/scripts#
Write the Site Data
Now, let’s write the site to the configurations file and enable it.
Note
We have to escape the
$
characters that are used in the Nginx config. Otherwise, Bash treats them as variables.echo " server { listen 80; server_name $FQD; location / { proxy_pass http://localhost:$PORT; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; } }" > /etc/nginx/sites-available/$FQD # Enable the site ln -s /etc/nginx/sites-available/$FQD /etc/nginx/sites-enabled
Next, we should ask the user to verify the config for errors before restarting Nginx.
Note
The
if
condition is true for any character exceptn
orN
.
echo "" echo "Verifying config..." echo "" nginx -t echo "" read -r -p "Restart Nginx? ?[Y/n] " RESPONSE if [[ ! $RESPONSE =~ ^[Nn]$ ]] then systemctl restart nginx else # Exit the script if "n" or "N". exit; fi
Prompt the user to encrypt the with SSL.
echo "" read -r -p "Create SSL certificate? ?[Y/n] " RESPONSE if [[ ! $RESPONSE =~ ^[Nn]$ ]] then echo "" certbot --nginx -d $FQD fi
Lastly, we can verify that the site works.
echo "" echo "Verifying site using curl --head http://$FQD" echo "" curl --head http://$FQD
Expected Output
-----------------------------------------------------------
Welcome to our Nginx Site Builder!
-----------------------------------------------------------
Please enter the fully qualified name of the site [sub.jj8i.cc]: test.jj8i.cc
Enter the port of the reverse proxy [8888]: 8899
Creating reverse proxy for test.jj8i.cc -> localhost:8899
Verifying config...
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart Nginx to enable config? ?[Y/n]
Create SSL certificate? ?[Y/n] n
Verifying site using curl --head http://test.jj8i.cc
HTTP/1.1 502 Bad Gateway
Server: nginx/1.14.0 (Ubuntu)
Date: Sat, 27 Apr 2019 03:28:42 GMT
Content-Type: text/html
Content-Length: 182
Connection: keep-alive
Wrap up
This script does most of the work for us and provides some user interaction. There are other tweaks that we could add to improve it.
This script adds complexity by prompting the user for input and providing some status output. That additional information is not necessary. You could omit the menu and use command-line arguments for the domain name and port.
A simpler script would accept the arguments from the command line, run the commands, and provide minimal output.
#!/bin/bash
# Verify that there are two arguments
if [[ $# -ne 2 ]]
then
echo "Please provide two arguments: <domain name> <port>"
exit
else
FQD=$1
PORT=$2
fi
echo "
server {
listen 80;
server_name $FQD;
location / {
proxy_pass http://localhost:$PORT;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
}
}" > /etc/nginx/sites-available/$FQD
# Enable the site and restart
ln -s /etc/nginx/sites-available/$FQD /etc/nginx/sites-enabled
systemctl restart nginx
echo "Verifying site using curl --head http://$FQD"
curl --head http://$FQD
root@vps298933:~/scripts# bash create-site.sh demo.jj8i.cc 8844
Verifying site using curl --head http://demo.jj8i.cc
HTTP/1.1 502 Bad Gateway
Server: nginx/1.14.0 (Ubuntu)
Date: Sat, 27 Apr 2019 03:51:29 GMT
Content-Type: text/html
Content-Length: 182
Connection: keep-alive