Deploying Applications

The droplet is set up to serve applications using nginx as a reverse proxy; a service that can take requests to the droplet itself and redirect them to specific services. This enabled different website addresses pointing to the droplet to serve as internal addresses for locations or services on the machine. Changing nginx configuration or adding sites to /var/www require super user privileges or altered file access permissions

Static Sites1

A static site serves plain, unchanging files from a folder on the droplet; front end builds or plain html.

sudo mkdir /var/www/<sitename>
sudo chown -R $USER:$USER /var/www/<sitename>
sudo setfacl -m u:<user>:rwx -R /var/www/<sitename>
vi /var/www/<sitename>/index.html
<html>
    <head>
        <title>Welcome to your_domain!</title>
    </head>
    <body>
        <h1>Success!  The your_domain server block is working!</h1>
    </body>
</html>
sudo vi /etc/nginx/sites-available/<sitename>
server {
  root /var/www/sitename;
  error_page 404 /404.html;
  index index.html;
  
  server_name sitename www.sitename;
  
  if ($host = www.sitename) {
    return 301 https://sitename$request_uri
  } #redirect www.sitename to sitename secured

  location / {
    try_files $uri $uri.html $uri/index.html =404
  }
  
  location /404.html {
    internal;
  }
}
sudo ln -s /etc/nginx/sites-available/<sitename> /etc/nginx/sites-enabled/<sitename>
sudo nginx -t
sudo systemctl restart nginx

HTTPs configuration

In order to serve your site to a new domain (or subdomain) securely over the internet (https), you’ll need to set up ssl certificates. Before that, you’ll need to add DNS record*(s)* pointing to the droplet through the relevant registar.

sudo certbot --nginx -d <site>.bci4kids.ca -d www.<site>.bci4kids.ca

certbot will automatically renew certificates for the provided domains when they are close to expiry, notifying a provided email if this renewal fails. To change the reminder email run:

sudo certbot update_account --email <email address>
sudo nginx -t
sudo systemctl restart nginx

Servers1

A live server can be easily set up to deliver over local http port to the internet at droplet.bci4kids.ca/service with no additional DNS setup required.

sudo mkdir /var/www/droplet.bci4kids.ca/<service>
sudo chown -R $USER:$USER /var/www/droplet.bci4kids.ca/<service>
sudo setfacl -m u:<user>:rwx -R /var/www/droplet.bci4kids.ca/<service>
pm2 start <entry_script> -n <service_name>
More About PM2

You can use the following commands to manage applications running on pm2, providing an application name, process id, or “all” where relevant. Note: pm2 processes are tied to the user account that started them.

pm2 start
pm2 list
om2 stop
pm2 delete
pm2 restart

By default, processes will be killed on a system shutdown/reboot.
To address this, you can add a pm2 startup script:

pm2 startup

If you already have a startup script, new processes are added to it once started by saving the list

pm2 save
sudo vi /etc/nginx/sites-available/droplet.bci4kids.ca
server {
  # base configuration and other locations
  ...
  location /service/ {
    proxy_pass http://localhost:port_number/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
  ...
  # certbot certificate block
  ...
}
sudo nginx -t
sudo systemctl restart nginx

Pushing site content2

The simplest way to get site content into the content folder is to simply clone it

git clone <https://github.com/user/repository> /var/www/<sitename>

However, if you are working from a private repository, you will need to create and add an ssh key pair on the droplet, add the public key to your github account, and then clone over ssh.

Continuous Deployment with a Git Hook2

Optional but highly recommended

Droplet Setup

If you simply clone your repository, you will have to push changes to origin, connect to the droplet, pull changes from origin, then execute any steps to set up or restart your application.

It is preferable to do this with one command.

In order to accomplish this, you can set up a git hook to push whatever you want to a specified location on the droplet, performing any reload tasks as required. This also bypasses the need for git credentials.

cd var/www/<sitename>
mkdir git
cd git
git init --bare
vi hooks/post-receive

This script will be run when the the repository is pushed to, and will populate the target folder with the working tree. Any other shell commands can also be executed.

!/bin/bash

GIT_DIR=/var/www/site.bci4kids.ca/git
TARGET=/var/www/site.bci4kids.ca

while read oldrev newrev ref
do
  BRANCH=$(git rev-parse --symbolic --abbrev-ref $ref)
  echo "Push recieved, deploying branch: ${BRANCH}..."
  git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
done

For instance, for a node service:
note that you would need to push the server files, install packages, and start the process once before automating it for subsequent deployments

!/bin/bash

TARGET=/var/www/droplet.bci4kids.ca/service
GIT_DIR="${TARGET}/git"

PROCESS=service

echo "Push received, deploying..."
git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f

cd $TARGET
echo "installing node packages"
npm install

echo "restarting ${PROCESS} process"
pm2 restart process

Local Setup

On your local development machine, you’ll need to set up a repo to push from, using the droplet as a remote.

git remote add live ssh://<user>@droplet.bci4kids.ca:/var/www/<sitename>/git

or var/www/droplet.bci4kids/<service>/git

cd dist
git add .
git commit -m "Updates from script deployment"
git push live main

References


  1. Setting up NginX Server Blocks ↩︎ ↩︎

  2. Deploying Code with a Git Hook ↩︎ ↩︎