{"id":172,"date":"2015-04-06T18:30:15","date_gmt":"2015-04-07T00:30:15","guid":{"rendered":"http:\/\/www.managerjs.com\/blog\/?p=172"},"modified":"2015-04-06T15:24:24","modified_gmt":"2015-04-06T21:24:24","slug":"book-notes-heroku-up-and-running","status":"publish","type":"post","link":"https:\/\/www.managerjs.com\/blog\/2015\/04\/book-notes-heroku-up-and-running\/","title":{"rendered":"Book Notes: Heroku Up and Running"},"content":{"rendered":"<p class=\"p1\"><span class=\"s1\">Some time ago I read an early release of the O&#8217;reilly book\u00a0<a href=\"http:\/\/shop.oreilly.com\/product\/0636920027409.do\"><span class=\"s2\"><i>Heroku Up and Running<\/i><\/span><\/a><i>\u00a0<\/i> by Neil Middleton. Here are\u00a0my impressions and notes that struck me from the book for whatever reason.<\/span><\/p>\n<h2 class=\"p2\"><span class=\"s1\">The book is a nice overview of Heroku<\/span><\/h2>\n<p class=\"p1\"><span class=\"s1\">It covers the history of Heroku, the Heroku philosophy, and gives many insights into how it all works and why it works that way. \u00a0The ebook is only $8 and available right now. I found it worth the money. The formal release was scheduled for October 2013.\u00a0<\/span><\/p>\n<p class=\"p1\"><span class=\"s1\">As a casual user of Heroku, this book helped fill in many blanks and give me a more solid footing for visiting the <a href=\"https:\/\/devcenter.heroku.com\/\"><span class=\"s2\">Heroku developer site<\/span><\/a>. The hard-core documentation is left to that developer site.<\/span><\/p>\n<p class=\"p1\"><!--more--><\/p>\n<h2 class=\"p2\"><span class=\"s1\">Contents<\/span><\/h2>\n<p class=\"p1\"><span class=\"s1\">The following are the chapter titles with some of my own comments in parentheses.<\/span><\/p>\n<ol class=\"ol1\">\n<li class=\"li1\"><span class=\"s1\">What is Heroku?<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">How Heroku Works<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">Understanding Performance and Scale<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">Heroku Regions<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">Heroku Postgres<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">Deployment<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">When it goes wrong (debugging Heroku apps and getting support)<\/span><\/li>\n<li class=\"li1\"><span class=\"s1\">Buildpacks (extending Heroku to support even more binaries)<\/span><\/li>\n<\/ol>\n<h2 class=\"p2\"><span class=\"s1\">Notes and Highlights<\/span><\/h2>\n<p class=\"p1\"><span class=\"s1\">Notes and highlights from reading the book. \u00a0Take it for what it&#8217;s worth.<\/span><\/p>\n<table class=\"t1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"td1\" valign=\"top\">\n<p class=\"p3\"><span class=\"s1\"><b>Kindle Location<\/b><\/span><\/p>\n<\/td>\n<td class=\"td2\" valign=\"top\">\n<p class=\"p3\"><span class=\"s1\"><b>Highlighted Text<\/b><\/span><\/p>\n<\/td>\n<td class=\"td3\" valign=\"top\">\n<p class=\"p3\"><span class=\"s1\"><b>My Commentary<\/b><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">96<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">I switched back to using Heroku and found that those things I couldn&#8217;t do once, I had no desire to do anymore. What once seemed like arbitrary limitations, now showed as well seasoned advice from an opinionated platform.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku is an opinionated platform. It&#8217;s forcing you to build apps that scale well horizontally.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">269<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku idles any applications running a single dyno when not in use to free resources for other applications.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Since 1 dyno per app is free, they reserve the right to idle it. This means you will sometimes have to wait many seconds for your app to come back up. If this is a problem, run at least 2 dynos and they won&#8217;t idle you.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">292<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">the router processing the request will only wait for 30 seconds before returning a timeout error to the end user.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\">30 seconds is an eternity in web land.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">294<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Once that first byte of response is returned, the router will then set a 55 second rolling window before an error is returned.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">You can still stream things using Heroku.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">337<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">release comprises a combination of your application code (or slug), and the configuration around it.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku tracks all the releases your app has ever had.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">414<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Once your application is up and running its dynos are silently cycled automatically once a day to ensure that the dyno image version they are running is the latest available runtime (your slug will stage the same) You can see this in your application logs as Cycling against a particular dyno. Therefore, if you were to deploy an application to HEroku and leave it for several months, it would be no more out of date than on deployed a day ago.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Woah! Nice!<\/span><\/p>\n<p class=\"p1\"><span class=\"s1\">Also means your dynos aren&#8217;t running for hundreds of hours in a row. Might hide endurance problems like memory leaks.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">420<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">A dyno can be thought of like a container for UNIX processes.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">If it runs on linux, and you can get it to run on a small AWS instance, you can probably get it running on Heroku.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">428<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">You can also schedule one-off background tasks with Heroku&#8217;s scheduler. This is like a worker, bot only runs a specific command for a given interfal. This is very similar to how you might schedule a task to be run with Cron. Tasks run by scheduler are only charged for the time they use.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku makes it easy for you to run your worker processes as cheaply as possible.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">452<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku does not provide log files per se, but offers this stream.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Instead of copying down a huge log file, you direct a stream to a log analytics service like log entries. In our case, we &#8220;drain&#8221; our logs to Splunk.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">483<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku Postgres.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku provides it&#8217;s own postgres add-on. It is pretty tricked out. We don&#8217;t need it here, but it was a very interesting read nonetheless.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">484<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">If you are deploying using a popular database backed web framework, such as Ruby on Rails, then Heroku will provision and configure the PostgreSQL add-on for your application.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Automatically.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">499<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">You can push into other branches if you wish, but these will only be stored on Heroku and not deployed as the platform will only ever deploy the master branch.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">To deploy code, you push it to master.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">503<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku takes your code and identifies it [using build packs].<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Buildpacks are what allowed heroku to become a &#8220;polyglot&#8221; platform. In this paragraph, they function as links in a chain of responsibility\u2013automatically sensing the type of project being deployed. The can do much more, too.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">507<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Buildpacks are provided by the Heroku operations team, but also by other opensource developers.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">517<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">All of the default buildpacks can be seen on GitHub here: https:\/\/github.com\/heroku<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">556<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku uses &#8220;ephemeral&#8221; disks, that are cleared at least once every 24 hours.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Just don&#8217;t use the disk.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">587<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku does not auto scale your app for you.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">They have a pretty decent rationale for why they don&#8217;t provide autoscaling and why they have no plans to do it in the future. You have to manually change the dyno count.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">599<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku can give you access to the tools in order to measure and make scaling easier than ever, but there should be a few eyes on the process.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">618<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">When a request arrives, it is randomly sent to one of your applications and available dynos for processing. Should a dyno be unavailable for some reason, it is dropped from the pool of dynos receiving request automatically. However, remember that while this is happening, the router processing the request is counting down from 30 seconds before returning an error to the user. Therefore, it is important to monitor your application&#8217;s queue length to see if more resources are required to handle the load.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">649<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku&#8217;s Cedar stack has no Nginx or Apache layer to serve static files.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">For performance, use a CDN.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">705<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Frameworks such as Rails have the ability to &#8220;auto explain&#8221; any queries that run over a given threshold while in development.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Nifty!<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">742<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">While this strategy can work well for development and prototyping it scales horribly. The more entries you have in your database the worst speed and relevancy will be.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Apropos using text search in the database for implementing a search feature. They recommend using a dedicated search technology like Lucene.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">754<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">don&#8217;t ship your &#8220;search&#8221; feature powered by a like query.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">760<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">If you&#8217;re interested in getting real world performance measurements, there are two ways to keep track of your app. Use in app performance analytics services and use external load and performance testing tools.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">787<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">One simple, yet useful tool for this is &#8220;YSlow,&#8221; which will attempt to &#8220;rank&#8221; the front end performance of your app and give you general advice on how to improve.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">842<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">At the time of writing the available regions for deployment were US and EU only.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">850<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku have provided fork, a simple way of cloning an application from one location into another:<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku tries to make it easy to set up your app in multiple availability zones.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">947<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku will do everything aside from architect and optimize your database. There is no need to worry about patching for security or stability, and there is no need to worry about backups; everything is taken care of for you. All that is left for you to do is to worry about your data and how to store it efficiently.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">That is, if you use their PostgreSQL add-on.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1261<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Running on rolled-back code is meant as a temporary fix to a bad deployment. If you are on rolled-back code and your slug is recompiled (for any reason other than a new deployment) your app will be move back to running on the most recent release. Subscribing to a new add-on or adding\/removing a config var will result in your slug being recompiled.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Important caveats to the roll-back feature.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1273<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">A simple way of improving [the size of your slug] is via the .slugignore file.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Just like .gitignore. You can use it to strip test resources from your slug, for example.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1277<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">.slugignore uses exactly the same format as .gitignore.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1372<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">when setting up your own DNS, it is always a good idea to use CNAME&#8217;s to alias your domain to the herokyapp.com domain<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">of course, we use a reverse proxy.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1379<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Some companies such as DNSimple now offer their own custom types of records in your DNS that allow you to alias apex domains the same way as a CNAME.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1410<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">The Heroku DevCenter can be found at http:\/\/devcenter.heroku.com<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Mkay!<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1427<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">checking <a href=\"http:\/\/status.heroku.com\/\"><span class=\"s2\">http:\/\/status.heroku.com<\/span><\/a> can save you a bot of headache if the issue isn&#8217;t on your end.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">yup<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1434<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">You can subscribe to notifications and wait for it to come back online.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">&#8230; if Heroku is down.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1439<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">making sure config, add ons and any labs features are on par across both servers: <\/span><span class=\"s4\">$ heroku config ; heroku addons:list ; heroku labs:list<\/span><span class=\"s1\">.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Useful when cloning apps for debugging.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1444<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">trick for forcing a deploy is to add a blank commit in your project <\/span><span class=\"s4\">$ git commit &#8211;allow-empty -m &#8220;debugging&#8221;<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">We do that a lot around here.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1454<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">pull out the big guns and use a custom debugging for of the buildpack.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Very powerful technique for when you just can&#8217;t figure out why the deploy won&#8217;t work.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1462<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">In the compile step of a buildpack anything sent to the standard out will display in the build process.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1476<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">point the BUILDPACK_URL of your staging app to your repo, check that your changes were pushed correctly to the repo specified in the BUILDPACK_URL.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">The BUILDPACK_URL config variable can force Heroku to use a particular buildpack for your app. Set it to your debugging fork when debugging the deploy.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1478<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">simply remove the BUILDPACK_URL from your staging app&#8217;s configuration vars<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">when you are done debugging<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1481<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">deploys shouldn&#8217;t take too long.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Otherwise you lose a lot of the benefits of continuous delivery, which is a basic part of the Heroku philosophy. It also slows you down when scaling up.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1484<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">the timeout may change in the future, it will likely stay somewhere around the 10 minute mark.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Heroku limits how long your build can take.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1513<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">To help out with notifying team members and building deploy related applications Heroku offers a Deploy Hooks addon: <\/span><span class=\"s4\">$ heroku addons:add deployhooks:email<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1538<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">It is a good idea to run performance metrics once or more a week to determine if your application&#8217;s data stores are running out of capacity.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1556<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">You can attach an unbounded number of log drains to a Heroku application without impacting the performance of your Heroku app.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">We currently drain to Splunk.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1560<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">If your application has a logged in user state and there is a restricted admin flag on users, it can be helpful to use dynamic error pages.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">These pages can show fault details to developers, but vanilla error messages to users.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1571<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Since many [exception notification services] group related exceptions it can be very useful for determining the issues that affect the most users.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1771<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Once you&#8217;ve got [your own] simple buildpack you can leverage the existing Heroku maintained buildpacks along with another community maintained buildpack called &#8220;heroku-buildpack-multi&#8221;<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">You can create buildpacks that add elements to the runtime environment and feather them all together with standard buildpacks using the multi buildpack.<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">1776<\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Instead of deploying using someone else&#8217;s buildpack off of GitHub, you should fork it and deploy using your own copy.<\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p1\"><span class=\"s1\">Since the build process is so important for replicating results, the author urges you to keep your own copy of custom buildpacks.<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>Notes on the book Heroku Up and Running.<\/p>\n","protected":false},"author":1,"featured_media":173,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[41,42],"class_list":["post-172","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-lab-notebook","tag-book-notes","tag-heroku","wow fadeInUp","entry"],"_links":{"self":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts\/172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/comments?post=172"}],"version-history":[{"count":1,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts\/172\/revisions"}],"predecessor-version":[{"id":174,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts\/172\/revisions\/174"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/media\/173"}],"wp:attachment":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/media?parent=172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/categories?post=172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/tags?post=172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}