Step 3: Scripting an Nginx Site =============================== .. include:: urls.rst .. contents:: 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 :ref:`nginx-commands` 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. .. code-block:: bash mkdir ~/scripts 2. Next, we'll create the file. .. code-block:: bash touch ~/scripts/create-nginx-reverse-proxy.sh 3. Edit the file and add the shebang. .. code-block:: bash #!/bin/bash 4. Let's add a welcome message to the user. Not necessary, but a nice touch. .. code-block:: bash echo "" echo "-----------------------------------" echo "Welcome to our Nginx Site Builder!" echo "-----------------------------------" echo "" 5. Execute the file to verify that it runs without errors. Prompt the User ^^^^^^^^^^^^^^^ 1. 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. .. code-block:: bash # 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 "" 2. Run the script to verify that it operates correctly before continuing. .. code-block:: bash :caption: 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 ^^^^^^^^^^^^^^^^^^^ 1. 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. .. code-block:: bash 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 2. Next, we should ask the user to verify the config for errors before restarting Nginx. .. note:: The ``if`` condition is true for any character **except** ``n`` or ``N``. .. code-block:: bash 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 3. Prompt the user to encrypt the with SSL. .. code-block:: bash echo "" read -r -p "Create SSL certificate? ?[Y/n] " RESPONSE if [[ ! $RESPONSE =~ ^[Nn]$ ]] then echo "" certbot --nginx -d $FQD fi 4. Lastly, we can verify that the site works. .. code-block:: bash echo "" echo "Verifying site using curl --head http://$FQD" echo "" curl --head http://$FQD Expected Output ^^^^^^^^^^^^^^^ .. code-block:: bash ----------------------------------------------------------- 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. .. code-block:: bash #!/bin/bash # Verify that there are two arguments if [[ $# -ne 2 ]] then echo "Please provide two arguments: " 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 .. code-block:: bash :caption: Output 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