Deploying Angular and Lucky Monorepo Using Netlify and Heroku

07/12/20182 Min Read — In Angular, Lucky, Netflix, Heroku, Monorepo

I like to keep my client and server together because it makes me more efficient by allowing me to open both apps in a single VS Code workspace. The difficulty comes when deploying the apps separately, but Luckily we can use services like Netlify and Heroku to simplify that for us!

As a reference my blog is made with a JSON Api built with Lucky and a front end build with Angular. You can look at the source code on github for a reference on state management with ngrx or using Lucky as a JSON api.

The folder structure is something like this:

/client # Angular Front End
/server # Lucky Api Back End
/bin
/deploy_server

Heroku

Heroku doesn't allow using a non root directory for publishing your application, I got around this by using git subtree which I learned from this post on coderwall.

First create the heroku app, add the buildpack and set the environment variables necessary for the Lucky app to run on Heroku. You can find full instructions in the Lucky Guides, but I'll reproduce them here for convenience:

Note for the Lucky Api you only need the crysal buildpack.

  • Add a git remote that points to your Heroku app: heroku git:remote -a "APP-NAME"
  • Add the following buildpacks in order:
  • Set LUCKY_ENV to production: heroku config:set LUCKY_ENV=production
  • Generate a secret key: lucky gen.secret_key
  • Set SECRET_KEY_BASE: heroku config:set SECRET_KEY_BASE=<GENERATED_SECRET_KEY>
  • Set APP_DOMAIN: heroku config:set APP_DOMAIN=https://your-domain.com
  • If you are sending emails, set SEND_GRID_KEY: heroku config:set SEND_GRID_KEY=<key from sendgrid.com>. If you’re not sending emails, go to config/email.cr and change the adapter to Carbon::DevAdapter.
  • Add a postgresql database add-on: heroku addons:create heroku-postgresql:hobby-dev

Now the difference is in how we deploy to heroku. Instead of git push heroku master we're going to use git subtree to only push a subdirectory of our repo.

git subtree push --prefix server heroku master

Change the --prefix parameter to the name of your sub-directory.

I put that command in a file at bin/deploy_server and made it executable with chmod u+x for convenience.

Netlify

Netlify is easily my favorite service for deploying static applications. I use it for all my Angular apps and it's got great features even at the free tier.

Deploying From Git

To deploy all we need to do is log in to netlify, go to the sites page at app.netlify.com/account/sites and select the "New Site from Git" button.

This will prompt you to log in with Github or Bitbucket, then select a repository to link to.

Configuring Base Directory

Now since our application is in a sub-directory we could create a package.json in our root directory and use a "postinstall" script to trigger an npm install and build (eg: "postinstall": "cd client && npm install"), then use a deploy command like "build": "cd client && ng build...".

This will deploy fine the first time but due to the way netlify caches directories like node_modules, it will not cache the packages installed from the package.json in the sub-directory and subsequent deploys will fail. To get around this we can create a netlify.toml file to set the base directory or our application, specify our build command and our publish directory. This will make netlify cache our node_modules folder correctly and allow our build scripts to run.

The file will look like this:

# netlify.toml
# Global settings applied to the whole site.
#
# “publish” is the directory to publish (relative to root of your repo),
# “command” is your build command,
# “base” is directory to change to before starting build. if you set base:
# that is where we will look for package.json/.nvmrc/etc not repo root!
[build]
base = "client"
publish = "client/dist/apps/portfolio"
command = "npm run build-netlify"

Note the publish directory path needs to be set from the root, while the build command will be run from the base directory (in this case client/)

You can find more configuration options in the netlify docs.

Building the App

The npm run build-netlify actually expands to: ng build --prod --build-optimizer && cp _redirects dist/apps/portfolio. When running a single page application you need to redirect every non-/ route back to your index.html, otherwise netlify will display a 404 page which we don't want.

We use a _redirects file with a simple configuration to handle this:

# client/_redirects
/* /index.html 200

Now anytime we push to github the application will deploy to netlify. And we can deploy to heroku using our bin/deploy_server command or pushing the subtree --prefix server to our heroku git endpoint.

Super simple, right?

Our final directory structure looks like this:

/client # Angular Front End
/_redirects
/package.json
/...
/server # Lucky Api Back End
/...
/bin
/deploy_server
netlify.toml

Join Us

I hope you enjoyed this tutorial and found it useful. Join us on the Lucky gitter channel to stay up to date on the framework or checkout the docs for more information on how to bring your app idea to life with Lucky.