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.
- create site folder
/var/www/<sitename>(it is easiest to use a subdomain ofbci4kids.ca)
sudo mkdir /var/www/<sitename>
- give yourself ownership over the site folder
sudo chown -R $USER:$USER /var/www/<sitename>
- grant file access permissions
sudo setfacl -m u:<user>:rwx -R /var/www/<sitename>
- create simple test page
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>
- create and populate corresponding nginx site configuration file
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;
}
}
- create symbolic link to
/etc/nginx/sites-enabled, enabling site
sudo ln -s /etc/nginx/sites-available/<sitename> /etc/nginx/sites-enabled/<sitename>
- check for syntax errors in your nginx config
sudo nginx -t
- restart nginx to enable your changes
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.
- add an
Arecord for each desired subdomainsite,www.site, etc, where the final address issite.bci4kids.cawith a value of the droplet’s IPv4 address:146.190.153.1- note that DNS changes can have a delay before propogating
- run certbot to issue and automatically renew certificates for the desired domains
- this will automatically add the certificates to your nginx config
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>
- verify nginx config
sudo nginx -t
- restart nginx to enable changes
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.
- create site folder
/var/www/droplet.bci4kids.ca/<service>
sudo mkdir /var/www/droplet.bci4kids.ca/<service>
- give yourself ownership over the site folder
sudo chown -R $USER:$USER /var/www/droplet.bci4kids.ca/<service>
- grant file access permissions
sudo setfacl -m u:<user>:rwx -R /var/www/droplet.bci4kids.ca/<service>
- add and run the server on a chosen port
- get site content in the folder (see below)
- perform initial installation steps (npm install)
- run app with pm22
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
- add your service as a location to the
droplet.bci4kids.canginx server block
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
...
}
- check for syntax errors in the nginx config
sudo nginx -t
- restart nginx to enable your changes
sudo systemctl restart nginx
- optional - add your new service to the index
- edit
/var/www/droplet.bci4kids.ca/index.htmlto include a link to your new service
- edit
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.
- create a bare git folder on the droplet somewhere you have permission to write
- I have used a plain
/gitfolder in the site or service folder for simplicity
- I have used a plain
cd var/www/<sitename>
mkdir git
cd git
git init --bare
- create and edit post-receive hook in bare repo
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.
- create up a distribution folder
- this could be your front end build folder, or just somewhere that you copy desired files into with a script when deploying
- initialize a local repository with
git init - configure live remote pointing to the location of your bare repository
git remote add live ssh://<user>@droplet.bci4kids.ca:/var/www/<sitename>/git
or var/www/droplet.bci4kids/<service>/git
- add, commit, and
git push live main- you should be prompted for your ssh key and then see your files pushed through
- optional - add script to automate the deployment process
- note: the script process needs to be user aware to use your ssh key
- example cmd script following npm build:
cd dist
git add .
git commit -m "Updates from script deployment"
git push live main