Digital Ocean Deployment using Docker

A step by step guide to deploying Client/Server app using Docker.

1. Prerequisites

1. Install Docker , if it has not been installed already.

2. Sign up to the Digital Ocean (DO), if you don't have an account already.

3. Create a personal SSH key, if you don't have one already.

At the command prompt type ssh-keygen -t ed25519 -C "natalie.seltzer@gmail.com"

Accept defaults, pw optional.

Go to your .ssh folder under your home dir and add contenent of public and private keys to the password valt. This keys will be used by DO to access github repo.

4. Create github Access Token, if you don't have one already.

To careate github Access Token Login to githubon the Developer settings menu at the bottom of the left-hand side menu. And click on the Personal access tokens left-hand side menu. Then click on the Generate new token button. Choose read: packages option under the write:packages sub-section.

Copy the token and add it to the password walt.

2. Project Setup

On a dev laptop copy existing Client / Server project into a new directory.

Remove all references to old project.

Delete .git dir from the route of the project.

Run npm init in both client and server directories.

Add

.env file containing env variables to the /server dir of your project.

Make desired changes and test.

Add docker-compose.yaml file to the project's root directory and Docker files to both client and server directories and test.

Create github repository.

Create git repository, create/update .gitignore file. Add .env to the .gitignore file.

Deploy to github.

At the root of the project create .github/workflows directories and add main.yaml file to it.

Deploy to github.

????? on github.

3. Initial Deployment to Digital Ocean
3.1. Set up Digital Ocean Project

Login into Digital Ocean.

Create Digital Ocean Project by clicking on the + New Project left-hand side menu.

3.2. Create Digital Ocean Droplet

Then, click on the green Create button and select Droplets to create DO Droplet with following options:

Image: Ubuntu 22.04 (latest)
Plan: Basic
CPU opitons: Regular with SSD
Datacenter: London
Authentication: SSH keys (use your publich SSH key)
Hostname: replace with your project name, e.g. myProject-test

* If you do not see your personal public SSH key in the Authentication section, add it by clicking on the New SSH Key button and entering the contenet of your public SSH key.

Save the IP address of the newly created Droplet.

3.3. Connect to the Digital Ocean Droplet via command line *

At the local command prompt type

ssh root@99.999.99.99

* Where 99.999.99.99 is the IP Address of your new Droplet.

3.4. Bring Digital Ocean Droplet up to date

Bring Droplet env up-to-date by running the following commands at the Droplet's command line:

apt update
apt upgrade

* Click enter to accept defaults.

3.5. Install Docker on Digital Ocean Droplet

Follow instructions on the docs.docker.com/engine/install/ubuntu webpage and install Docker at your Droplet by running the following commands at the Droplet's command line:

1. Set up the repository:

sudo apt-get install \
  ca-certificates \
  curl \
  gnupg \
  lsb-release

2. Add Docker’s official GPG key:

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

3. Use the following command to set up the repository:

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

4. Install Docker Engine

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
apt install docker-compose

* Accept all defaults by pressing Enter.

3.6. Install HTTP Server in local env to serve Quasar

HTTP Server will be used to server Client Single Page build by Quasar

On the dev machine, go to the project folder and run the following command to get to the client container command line:

docker-compose exec client /bin/bash

Then run the following command:

npm install http-server


3.7. Install MYSQL on Digital Ocean

On the Digital Ocean Server, go to the project folder and run the following command to install MYSQL:

apt-get install mysql-server

Create a db:

to MYSQL by typing:
mysql

Then at mysql prompt create your project db:

mysql> CREATE DATABASE myprojectdb;

Create db user:

mysql> CREATE USER 'myprojectuser'@'localhost' IDENTIFIED BY 'myprojectuserpassword';
mysql> GRANT ALL PRIVILEGES ON myprojectdb.* TO 'myprojectuser'@'localhost';
mysql> CREATE USER 'myprojectuser'@'%' IDENTIFIED BY 'myprojectuserpassword';
mysql> GRANT ALL PRIVILEGES ON myprojectdb.* TO 'myprojectuser'@'%';
mysql> exit

Update MYSQL config:

nano /etc/mysql/mysql.conf.d/mysqld.cnf

Update as following:

bind-address      = 127.0.0.1,172.18.0.1


3.8. Add docker-compose.yaml file and github access to your Digital Ocean Droplet

1. At the Droplet's command line create docker-compose.yaml file

cd /srv
mkdir myProjectDir
cd myProjectDir
nano docker-compose.yaml

containing:

version: '2'
services:
  server:
    image: ghcr.io/criptogirl/myproject-server:master
    ports:
      - '8081:8081'
    env_file:
      - .env
    volumes:
      - ./config:/config
      - ./datafiles:/datafiles
  client:
    image: ghcr.io/criptogirl/myproject-client:master
    ports:
      - '8080:8080'

* Note that image link is all low-case

4. Add Github access token to DO Droplet.

docker login ghcr.io -u CriptoGirl

* use github Access Token as password.

3.9. Add .env file to your Digital Ocean Droplet & create directories

At the Droplet's command line go to your project's directory and create .env file:

cd /srv/myProjectDir
nano .env

containing env variables, e.g.

MYSQL_MYPROJECT_HOST=172.18.0.1
MYSQL_MYPROJECT_USER=myprojectdbuser
MYSQL_MYPROJECT_PW=myprojectdbuserpassword
MYSQL_MYPROJECT_DB=myprojectdb
GOOGLE_FIREBASE_myproject=/conf/myproject-firebase-adminsdk-.....json
DATA_UPLOAD_DIR=/datafiles

At the DO Project Directory, create config and datafiles directories

mkdir datafiles
mkdir config

Add myproject-firebase-adminsdk-....json filet to the DO config directory.

cd config
nano myproject-firebase-adminsdk-....json

Copy content of firebase config file from local env into this file.


3.10. Config Changes for Deployment

1. On your dev machine update the /client/Dockerfile as follows:

FROM node:12 AS base
ENV PATH=/usr/src/node_modules/.bin:$PATH
WORKDIR /usr/src
ADD package.json package-lock.json .
RUN npm install
# CMD tail -f /dev/null
CMD ./node_modules/.bin/quasar dev

FROM base AS prod
ADD . /usr/src
RUN ./node_modules/.bin/quasar build
CMD ./node_modules/.bin/http-server dist/spa -p 7080

2. On your dev machine update the /server/Dockerfile as follows:

FROM node:10 AS base
WORKDIR /usr/src
ADD package.json package-lock.json .
RUN npm install
CMD ./node_modules/.bin/nodemon server.js

FROM base AS prod
ADD . /usr/src
CMD ./node_modules/.bin/nodemon server.js

3. On your dev machine update the docker-compose.yaml file adding the following line to both client and server build sections:

target: base

4. On your dev machine update the env section of the /client/quasar.conf.js file as follows:

SERVER_URL: 'HTTP://99.999.99.99:7081/'

5. On your dev machine update the /server/.gitignore file file as follows:

*node_modules/
notes/
/config/
datafiles/

6. On your dev machine make sure that .js files containing sql commands uses LF (Unix) rather then CRLF (Windows) line endings. Use your editor to check and change if required.


3.11. Pull images from github to your Digital Ocean Droplet *

1. Add your latest changes to github:

git add .
git commit -m "changes"
git push origin master

The github will build a new image.

Go to the github select your project's repository and click on the Actions tab to see the image buing build.

When images are built, pull the images by running the following command at the Droplet's command line:

cd /srv/myProject
docker-compose pull


3.12. Run Docker on Digital Ocean Droplet *

Start Docker containers by running the following command at the DO command line:

docker-compose up -d

Check logs by typing

docker-compose logs

or

docker-compose logs -f client

Test in a browser. E.g. 99.999.99.99:7080



3.13. Set up Cron Job on Digital Ocean Droplet

Note that Cron jobs would normally run on the server and not on dev.

Create scripts folder under the server folder of your project and add myScript.js file to the /server/scripts folder.

At the DO Droplet's command prompt create Cron Job file:

nano /etc/cron.d/myCronJob

containing:

# comment line to run every minute: every min, every hour, every day, every month, every week day
* * * * * root docker exec myproject_server_1 node scripts/myScript.js > /tmp/myLog

To run your script ones a day at 5am: 0 5 * * *

To see the log

cd /tmp
cat myLog

For more info visit crontab.guru



3.14. Run Sequelize Migrations & Seeds on Digital Ocean Droplet

On DO server execute following commands:

cd srv/myrpject
docker-compose exec server bin/bash

Followed by:

npx sequelize-cli db:migrate --debug
npx sequelize-cli db:seed:all

In case above did not work, run sql at MYSQL command prompt.Copy file into your project directory, then:

mysql> USE myprojectdb;
mysql> source initial_db.sql;
mysql> show tables;



4. Deployment to Digital Ocean
4.1. Create github image

1. Add your latest changes to github:

git add .
git commit -m "changes"
git push origin master

The github will build a new image.

Go to the github select your project's repository and click on the Actions tab to see the image buing build.

Wait for the image to be built before proceeding to the next step.

4.2. Connect to the Digital Ocean Droplet via command line & deploy latest image

At the local command prompt type

ssh root@99.999.99.99

* Where 99.999.99.99 is the IP Address of your new Droplet.

Pull the images from github by running the following command at the Droplet's command line:

cd /srv/myProject
docker-compose pull

4.3. Run Docker on Digital Ocean Droplet

Start Docker containers by running the following command at the DO command line:

docker-compose up -d

Check logs by typing

docker-compose logs

or

docker-compose logs -f client

Test in a browser. E.g. 99.999.99.99:7080


5. Remove project & droplet from Digital Ocean

1. Login to Digital Ocean.

2. Select project from the left hand side menu.

3. Click on the ... on the right hand side of the associated droplet and click on the Destroy option to Destroy the Droplet.

4. Click on the project's Settings tab and scroll down to the Delete Project section. Click on the Delete Project button.

You might need to mark another project as default, to be able to delete your project. This can be done from the Settings tab of another project.