Deploying to Heroku
Deploying a sails app to Heroku
Deploying to heroku was a fairly straightforward process but there are a couple of things to know.
When you push your code to heroku, it will simply call
npm start in the root directory. By default, this will essentially do the same thing as
sails lift. This will trigger the grunt build which in turn download client side js dependencies using bower and compile LESS into CSS. This process is asynchronous and can take several seconds. This means that everytime your application is awaken from sleep, it will trigger that process. The problem is that express will serve some files while other are still being generated. In the case of a single page app, the first user after a sleep will get a page without CSS and most client side js library won’t be available.
// for heroku-buildpack-nodejs-grunt grunt.registerTask('heroku:development', 'build'); grunt.registerTask('heroku:production', 'prod');
We tried to keep cost as low as possible but we still required a couple of heroku add-ons. Here is what we used.
1 web dyno & 1 worker dyno - 34.50$
As recommended in the heroku documentation we designed the application so we do a little as possible on the web request. We do all the heavy lifting on a worker process using a queueing system. For example, we send emails and we do big SQL query for batch processing in the worked process.
Note that even the smallest heroku dynos has 4 CPU. This means that you can use node-cluster to create multiple workers inside one dyno.
One thing you need to know when using heroku is that the application will be put in sleep mode when not used for an hour. It will wake up automatically when a request is made but this is not instantaneous. We initially thought that activating one worker dyno would prevent the application from sleeping. The docs says “Apps that have more than 1 web dyno running never go to sleep and worker dynos (or other process types) are never put to sleep.”. The key here is 1 web dyno. This means that unless you add another web dyno (another 35$ ish/month) or you mange to hit your web worker at least once per hour, your app will sleep.
Heroku Postgres - 50$/month
We started with the
Hobby Dev/Basic plan but we had to upgrade to the
Standard 0 plan. The problem with the introduction plans is the connection limit. When sails setup the database, it creates a lot of parallel connections to read and update the database schema. This maxed out the number of connections and made the process crash.
Redis Cloud - 0$/month
The free plan was enough since we only persist user sessions in redis. The next plan is only 10$ and would cover our needs to a while. We could also use client side session to remove the dependency on redis. There is also a node adapter but it’s not integrated with sails and the redis integration works so well that it was not worth changing.
RabbitMQ Bigwig - 0$/month
SSL - 20$/month
We handle user login and we will process credit card transactions so https is a requirement. Heroku has a great guide on how to setup that. We purchased our ssl certificate with godaddy (I know…) and they generated two
.crt files. You will need to combine them using
cat secure.mysite.com.crt gd_bundle.crt > combined.crt and then
heroku certs:add combined.crt server.key.
We tried to bypass this add-on and install the certificate straight into node/express/sails. The problem is that heroku firewall everything except port 80.
But… this is not a perfect solution
No SQL logs
Not being able to get the full query log when debugging a database issue is a big problem. We were lucky enough to be able to reproduce the issue locally but otherwise, we would have been in a dead end.
As we explained, the application will sleep unless you add another web dyno. I think that paying for a worker dyno should prevent the application from sleeping.
Not that cheap
104.50$ a month is not much, but when you have 0$ income it’s a significant amount of money. To reduce hosting cost, we tried AWS.
blog comments powered by Disqus