See bootstrap-image.sh

Security

SSH keys only, no passwords
SSH set usernames only (no root)
SSH non default port
fail2ban - config in /etc/fail2ban/jail.local
UFW, IP Tables / Rules

New Image

check root / sudo access
update /etc/hostname & /etc/hosts
update system: sudo apt-get update
install build essential: sudo apt-get install build-essential
create /srv/appname folder
add group (www)
add user (www-) serve app with home of /srv/appname
add user to allowed SSH logins at /etc/ssh/sshd_config
change user password using sudo passwd username
add yourself to www group
add .profile & .bashrc to user 
add .ssh authorised key
change ownership recursively of /srv/appname to user

install NVM as www-user (if applicable setup globally (this is not recommended by maintainer)
place scripts in .bashrc (controls non-login shell)
install node via NVM
add dns record

Create swapfile

sudo dd if=/dev/zero of=/path/to/swapfile bs=1024 count=1048576
sudo chmod 600 /path/to/swapfile
sudo mkswap /path/to/swapfile
sudo swapon /path/to/swapfile
Add to /etc/fstab to enable at reboot:
/path/to/swap none swap sw 0 0

Setup postgres

sudo su postgres
psql $DATABASE < /srv/$PROJECT/package/sql/database.sql

Setup nginx

sudo apt-get install nginx
Add global password
sudo sh -c "echo -n 'username:' >> /etc/nginx/.htpasswd"
sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd" // will respond with password
add configuration to /etc/nginx/sites-available/appname.conf
remove default sites-enabled
sudo ln -s /etc/nginx/sites-available/eg.conf /etc/nginx/sites-enabled/eg.conf //symlink to sites-enabled
sudo service nginx restart

Setup Supervisor

sudo apt-get install supervisor
add non-root config to /etc/supervisor/supervisord.conf // To run as non-root, use http server (inet) rather than unix socket.
add config to start /etc/supervisor/conf.d/appname.conf
sudo supervisord -c /etc/supervisor/supervisord.conf // launch supervisor
create logs directory

Checks

sudo ufw allow 3000/tcp // allow Port 3000

deploy files