Heroku is billed as the easiest way to deploy your apps no matter the language. Node.js, PHP, Python, or Ruby – they’re all super easy to deploy says their marketing materials. What they don’t tell you is that it isn’t that simple. The value prop is that you get to focus on deployment without having to worry about servers. Trouble is, while that might technically be true, you’re trading in one set of problems for another. There’s no one size fits all “how to deploy your app to Heroku” guide but there are a few tips you can follow that’ll at least get your in the right direction and help you think of things you might not have thought of.
The golden assumptions
When you develop locally – regardless of the language – there are a set of assumptions or common modules you use.
The first thing you need to transfer is your database connection. In development you’ll use a locally hosted database. In a production environment you connect to a different database. The issue is that you need to set up a remote database and access it depending on your environment.
This means that when you set up your database connections locally you need to use reusable variables that will change based on environment variables or ternary statements based on the current environment. This way when you deploy the correct database connection is always used depending on where you’re deploying your app.
So how do you do this? Where are the code samples? There aren’t any. Check out my GitHub profile to see how I’ve done it in other projects without using the Dotenv module. Or check out Dotenv and do it that way. Either way you’ll need to use a either ternary statements or environment variables to get the job done. If you know what those things are then you can figure this out. If not, you need to read up on environment variables and ternary statements to truly get it.
Everything you do in your application startup script should take your environment into account. If you’re hiding secret data in environment variables then you need to set those up in your config vars on Heroku. Heroku will automatically set your environment to production so you need to be ready for that.
Those are the two core assumptions or gotchas that mess people up when deploying to Heroku. But there is more.
Depending on what kind of app you deploy to Heroku you may need to tailor your application to properly deploy. Here are some examples.
For Ruby apps, especially Rails, there’s a special set of development, test, and production gems you need to add to your Gemfile groups.
For Node apps you have to be sure that your package.json has a start command defined within the scripts object.
There are more but just keep those in mind.
How Heroku works
I always advise people to deploy to their own servers because what Heroku is hiding from you is actually quite simple and running your own server is cheaper and gives you more flexibility.
When you create a new app on Heroku they spin up an Amazon EC2 instance for you and then configure a server with a web server like nginx or whatever your app needs to run on it. From there you need to tailor your app to run on their preconfigured server instead of deploying the app you want and bending the server configuration to your needs.
The benefits are that you don’t have to set up servers which takes time and they do the work of securing the servers. What sucks is that you can’t host your database and app on the same server. You need to either buy expensive addons or use a service like mLab and use it to connect to a database hosted remotely. That’s s lot of moving parts.
Moving parts are bad when you have little control over them. I can understand hosting your own web app server and database server on separate VMs on a private network and scaling your app that way but the problem here is that if you want that kind of flexibility you’re going to pay a pretty penny for it otherwise your database is hosted somewhere else on a public network which isn’t so bad except that when you have to handle more than side project levels of traffic your response times will end up getting slow AF.
Read the Heroku docs
Always read the docs. What I’ve written here are the pitfalls I’ve seen people bitten by but that’s not an excuse to ignore the docs. Let the docs guide you toward a basic deployment and begin debugging from there. And remember the all important
heroku logs command which will show you what’s happening in your app as it runs, even errors. Most of the time the logs are harder to read than a Ruby stack trace and even more useless but in the end you’ll occasionally get some useful info from a stack trace from Heroku’s logging facilities.
Beware the addons that Heroku sells you to add basic things to your apps like databases and SSL. On a $10 VPS you get these things for free. The learning curve is a bit steeper but once you overcome it you’ll not only know how to run a server but you’ll know how to build your own Heroku. Unfortunately, the promise of “you code and we host with a simple git push” couldn’t be further from the truth. Having done both for years now I can definitively say running and scaling one or more VPS servers is far easier and cheaper than Heroku.
But if you must resort to Heroku, keep what I said in mind. Mind your databases and environment variables.
I’m working on an article about how to use Bookshelf.js with a relational database in a Node app like one based on Express. I’m just about finished with it so that’ll likely be the next thing I publish.