Deploying a Rails 5 + Vue.js 2 App to Heroku


After you’ve finished your Ruby on Rails application locally, you may think that the hard part of the process is over. However, the next big step of putting it online in a production deployment can be just as tricky, especially for a typical software developer without much experience in this space. Thankfully, Heroku provides a platform that significantly streamlines this process and allows developers to quickly get an application up-and-running online. This option is particularly great for hobby developers as they offer a free tier. While there are plenty of guides online for how to do this with a Rails app, there is a distinct lack of information of how to deploy a Vue.js front-end in conjunction on Heroku.

This tutorial assumes you have a back-end and a front-end in separate folders/repos. The only pre-reqs for this tutorial are node and git. The back-end should be configured to use PostgreSQL.

Introduction

My application WhoDecidesFood? is developed as a single-page application where the front-end code (Vue.js) is completely separate from the back-end Rails API code. In fact, the two parts are two individual git repositories (see whodecidesfood-app and whodecidesfood-api).

This is the general approach being taken by many people now because it provides various benefits. One big benefit that I identified for this is, as a hobby project, it would allow me to easily create new front-ends accessing the same back-end, i.e. if I were to create a phone app or use a different framework like Angular or React, by just swapping out the front-end. De-intertwining the front-end from the back-end here makes this much easier. In theory, this would also allow me to deploy both applications separately (i.e. for load balancing purposes), but I negate that benefit in this tutorial by deploying them together - you may want to consider a different approach if this is more than a hobby project or you have a dedicated team that can manage this.

(Optional) Getting the Applications

Hopefully you have your own back-end and front-end developed, but to allow you to use something else for demo purposes, this section will detail how to use my own back-end and front-end.

Begin by cloning the repos into separate locations. I will rename the cloned folder to a generic name to make the rest of the tutorial generic.

$ git clone https://github.com/mjmeli/whodecidesfood-app.git frontend
$ git clone https://github.com/mjmeli/whodecidesfood-api.git backend

Now install the Node packages for the front-end. These are needed as you will have to build the front-end locally. This obviously requires you to have Node installed.

$ cd frontend
$ npm install

That’s all.

Getting Ready for Heroku

The first step in deploying to Heroku is to create a Heroku account at this link.

Next, to be able to integrate with Heroku easily, you will need to make sure you have the Heroku command-line client. Installation depends on your operating system but there are good instructions on the Heroku Dev Center.

Finally, you will want to use the Heroku CLI to login.

$ heroku login
Enter your Heroku credentials.
Email: <ENTER EMAIL>
Password: <ENTER PASSWORD>
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/you/.ssh/id_rsa.pub

If prompted, press enter to generate a new SSH public key.

Creating the Heroku App

Navigate to your back-end repo and use the Heroku CLI to create the application:

$ cd backend
$ heroku create
Creating app... done, ⬢ <app-name>
https://<app-name>.herokuapp.com/ | https://git.heroku.com/<app-name>.git

You will notice that Heroku adds a remote git repo to handle deployment. When you wish to deploy to Heroku, you will simply push to this git repo’s master branch. Easy!

If you now navigate to your Heroku Dashboard, you will see this newly created app. You can also navigate to it by using the URL given, but right now there is nothing there.

Adding Front-End Content

Rails comes configured to use the puma web server by default. This is what runs when you do rails server locally and it can also be used easily and well in production. In the default configuration, puma will look into the public folder of your Rails application and it will serve everything in there as static content.

This is extremely useful because our front-end is static content! So all we have to do it put our front-end build there and puma will automatically handle it.

So let’s do that. Begin by ensuring the public folder is empty except for .gitkeep (when you generate the Rails app, it will contain some files).

$ cd backend
$ rm -rf *

Next, navigate to your front-end and create a minified production build.

$ cd ../frontend/public
$ npm run build
> [email protected] build /home/me/frontend
> node build/build.js
...
⠴ building for production...
...

Build complete.

Tip: built files are meant to be served over an HTTP server.
Opening index.html over file:// won't work.

This will generate a folder in your front-end called dist. Inside this folder will be a file, index.html, and a folder, static. This is your front-end.

$ ls dist
index.html  static

You want to copy these files to your back-end public folder.

$ cp -r dist/* ../backend/public

Deploying to Heroku

You have a couple of options now. Remember that Heroku works as a git repo. That means that any files you wish to deploy (including your front-end) must be commited to the repo. So you can do this if you want and just use the git push heroku master command to deploy, but I think this is a bad idea because you don’t want front-end builds in your back-end git repo or history.

However, Heroku’s decision to use git was not necessarily one for version-control management. Since you already have a back-end repo, you don’t care about the Heroku repo’s history or state as much. As such, I suggest the following alternative approach, which is the one I use.

Navigate to your back-end and create a new branch.

$ cd ../backend
$ git checkout -b heroku-deploy

Now, commit the front-end files in this new branch.

$ git add public
$ git commit -m "deploy"

We are going to now do a push to Heroku to kick off the deployment process. Note that we must do a couple of modifications to our git push command to make this work. First of all, we want to use the -f flag to force push to the repo. If we didn’t do this, then we may run into issues in later deployments as the git histories may diverge, so to avoid that we just obliterate the Heroku repo each time as we do not care about its history. Next, we want to push to the Heroku master branch, but we are not on the master branch ourselves; as such, we will need to explicitly map this branch to the remote master branch. All in all, this command will suffice:

$ git push -f heroku heroku-deploy:master

Now the deployment process will kick off. You will see the progress of it in your terminal. When it is complete, assuming it ran with no errors, be sure to run a database migrate.

$ heroku run rake db:migrate

While we are “technically” done, we just did a bunch of hacky git things and will want to clean that up. That is easy by just deleting our branch.

$ git checkout master
$ git branch -D heroku-deploy

Awesome! That’s it! You can now navigate to your application and everything should be up and running.

$ heroku open

Just run through this process again to deploy subsequent times.

Scripting the Deployment

This process has a bunch of commands to type out that do not differ between deployments so its a prime candidate for scripting. I wrote a script to do so in my front-end repo. You can see it here. You’ll notice it follows the same flow as this tutorial.

Additional Resources

If you have any problems deploying the Rails app to Heroku, please see the official documentation for more detailed instructions.

If you have any aspect of your website that requires submitting sensitive information (i.e. login), I highly recommend enabling SSL. This is extremely easy with Heroku if you are in a paid tier (Hobby or higher). Follow these instructions to automatically generate a certificate through Heroku and then pick up from Step 4 of these instructions to configure the Rails app. You can also provide your own certificates if you are on the free tier - simply follow the second link from the beginning and skip the first link.

Tags

ruby-on-rails rails vuejs deployment heroku whodecidesfood