Deploying an app from Gitlab to Heroku using the Quasar framework and Sailsjs
Published: 2019-11-03 11:10:58


In this tutorial I'm quickly going to give you an idea on how to deploy an application from heroku to Gitlab using auto CI/CD


This tutorial assumes that you must have known a little bit of Quasar framework and JavaScript it also assumes that you have basic understanding of Node itself and Auto DevOps.

In this example will be using Sailsjs and Quasar framework so make sure you have those dependencies installed globally.


### Getting things  ready

```bash
$ npm i -g sails @quasar/cli
```

now that you have those dependency installed all you had to do is make a directory *demoapp* as a directory name [you can change the name to your taste]

```bash
$ mkdir demoapp && cd demoapp 
```
Now create the client folder using quasar

```bash
$ quasar create client
```
Quasar will ask you some questions about your application, make sure you answer them to your projects requirements, it also needs to download a starter kit so make sure you have an active internet connection  

After creating the client folder now create the server folder, you can open a new terminal tab to speed up the development process while installing dependencies for each.

```bash
$ sails new app --no-frontend
```
you should see something like this on your terminal


```bash
➜  demoapp sails new server --no-frontend
 info: Installing dependencies...
Press CTRL+C to cancel.
(to skip this step in the future, use --fast)
```

This creates a new sails app without a frontend this comes handy when you want to generate a server only based application without worrying about the views since the views we are going to be replaced with quasar-framework distribution files.

your root folder should look something like this

```bash
.
├── client
│   ├── babel.config.js
│   ├── node_modules
│   ├── package.json
│   ├── package-lock.json
│   ├── quasar.conf.js
│   ├── README.md
│   └── src
├── package.json
└── server
    ├── api
    ├── app.js
    ├── config
    ├── node_modules
    ├── package.json
    ├── package-lock.json
    └── README.md
    
```

Now initialize `git` int the root project of your application 

```sh
$ git init
```
Make sure to add your gitlab origin to your app folder 


```sh
$ git remote add origin YOUR_APP_NAME
```

## Setting up sails to load quasar dist file pragmatically 

Naturally sails is meant to load files found in the assets folder, but we want our files to be in the `views` directory 
So we will create a directory called `views`

from the root directory run:
```bash
$ mkdir ./server/views
```
Now create a config file telling sails where our built files from quasar will be or live

```bash
$ code ./server/config/paths.js
```
This will open VSCODE editor and create an empty file.
inside the `paths.js` file, place this code there:

```javascript
module.exports.paths = {
	public: "views"
}
```
Now when you lift sails, it will load up any `index.html` found in the views folder.


## Adding a buildscript

There are many ways to archive this but i prefer to use a simple bash script to install, build and copy the files to their respective folder.
   
 
Here's the `install.sh` script

```sh
#!/bin/bash
echo  ' - Alright, here we go. trigerring auto deploy .. ..'  &&  echo
  
installDependencies() {
	echo  " Installing global dependencies.."  &&  		echo
	npm i -g @quasar/cli sails
}

  

setupServer() {
	echo  " Installing server dependencies .. .."
	cd ./server
	npm install
	cd ..
}

  

setupClient() {
	echo  " Installing application dependencies .. .."  &&  echo
	cd ./client
	npm install
	quasar build -m spa
	cd ..
}

  

copy() {
	echo  " Copying assets to server"  &&  echo
	mkdir -p ./server/views
	cp -R ./client/dist/spa/* ./server/views
	}
}

installDependencies && setupServer && setupClient && copy

```


What the script really does

- Installs the global dependencies
- Uses the dependencies to build their project files
- Copies the built files to where the server will pick and load them up for public access.




## Setting up heroku

First thing to do is to make sure that heroku toolbelt is installed on your machine 

```sh
$ npm i -g heroku
```
Create an Heroku's account or login using your terminal

```sh
$ heroku login
```
Follow the prompt and login. After a successful login, create a project

```sh
$  heroku apps:create demoapp-ci
```

You can use the main heroku site for this but to be faster i used heroku CLI toolbelt,

Naturally heroku, [prunes the `devDependencies` after installing dependencies](https://devcenter.heroku.com/articles/nodejs-support#package-installation)

so to make sure that your `devDependencies` are still there after installing your projects dependencies
run 

```bash
$  heroku config:set NPM_CONFIG_PRODUCTION=false YARN_PRODUCTION=false -a YOUR_APP_NAME
```
where `YOUR_APP_NAME` is your projects application name on heroku.

Heroku looks for a `start` script in your `package.json` file and attempts to run it with `npm start` so create or initialize npm to create the file.

From the root folder of your project run:
```bash
$ npm init --yes
```
The above command creates a dummy `package.json`  in the root folder of your app. Open the `package.json` file and add two commands in the `script` section


- *posintall* - runs before heroku starts your application, this is where we'll be calling the `install.sh` script which will run and install our projects dependencies.

- *start* - this is the main entry point of our server entry file.
Actually what we'll be doing in the `start` section is to `cd` into the server folder and run the `start` script there too

so your `package.json` file should look like this:


```json
{
	"name": "demoapp",
	"version": "1.0.0",
	"description": "",
	"main": "index.js",
	"scripts": {
		"postinstall": "bash install.sh",
		"start": "cd ./server && npm run start",
		"test": "echo \"Error: no test specified\" 		&& exit 1"
},

	"keywords": [],
	"author": "",
	"license": "ISC"
}
```

## Setting up Gitlab

Now that everything is setup, we would probably be setting up Gitlab, if you don't have an account try creating one or if you already have, login into your account and create a project, we'll be using `demoapp` as the name of the project.

Now add the newly created application to your local git, i used the `SSH` strategy in this case, you can opt-in for `HTTPS`

```bash
$ git remote add origin git@gitlab.com:YOUR_USERNAME/demoapp.git
```
replace `YOUR_USERNAME` with your gitlab username, don't yet push now until we'v setup everything.

## Getting your HEROKU_API_KEY

This where Gitlab gets to talk to Heroku servers about your application once a code is pushed.

Goto your heroku's [dashboard](https://dashboard.heroku.com/account)
under the `API Key` section click on `reveal` to show your API key, it should look like this `c488826c-e081-4434-a27f-45133f93c389`

Now goto back to gitlab, click on the navigation menu on the left side of your browser and goto `setting > CI/CD`

or copy this link and replace `demoapp` with your gitlabs project name
[https://gitlab.com/navicstein/demoapp/-/settings/ci_cd](https://gitlab.com/navicstein/demoapp/-/settings/ci_cd)

under the `Variables` section toggle the `expand` button
create a key as:  `HEROKU_API_KEY` and copy the `API Key` from heroku into the `value` box  then click `Save ariables`




## Setting up CI/CD

As described by [GitLab Pages documentation](https://docs.gitlab.com/ee/user/project/pages/), everything happens with a `.gitlab-ci.yml` file placed in the root of your repository. This working example will get you started:
Paste this code in the root of your folder

```yml
image: node:12.13.0

stages:
	- production
  
cache:
	paths:
		- node_modules/

# HEROKU
production:
	type: deploy
	stage: production
	image: ruby:latest

script:
	- apt-get update -qy
	- apt-get install -y ruby-dev
	- gem install dpl
	- dpl --provider=heroku --app=demoapp-ci --api-key=$HEROKU_API_KEY

only:
	- master
```

In the script part of the yml file
`	- dpl --provider=heroku --app=demoapp-ci `
replace `demoapp-ci` with the application name you created on heroku


## Going live

If you come this far without any troubles, then congrats you're ready to push your code, but before that make sure you follow sails guidelines for deploying your application [sails guidelines for deploying your application](https://sailsjs.com/documentation/concepts/deployment) 

```sh
$ git add . 
```
```sh
$ git commit -am  "Going live" 
```

Pushing will

- trigger the CI and run the jobs
- upload artifacts to heroku 
- heroku in turn will run the `postinstall` script before attempting to run the `start` script
- finally, heroku will lift your app located at `./server/app.js`
This will push and trigger gitlabs servers to run the  `.gitlab-ci.yml` in your folder once the build succeeds

open your application and see your app go life, feel free to contact me or follow me on twitter when you run into issues, i'll be happy to talk with you about your project or issues you encounter.