Deployment of Static Files to Heroku

If you use Ruby on Rails, Django or NodeJS frameworks on the same domains they have special folders, usually called static, public or assets. But what if you what deploy just “static” file which are usually not so static, by they way.

Heroku uses Cedar stack as an application creation tool and it doesn’t support flat-out deployment of static files such as HTML, CSS or JavaScript, unless they come with some server-side language, e.g, PHP, Ruby, Python. This might come in handy if you are using front-end applications build with jQuery or BackboneJS framework and services like Parse.com or Firebase.com or consume your own back-end deployed as a different application on different instance and/or domain.

There are multiple ways to trick Heroku and Cedar into thinking that your HTML, CSS and JavaScript files are PHP or Ruby on Rails, or any other legitimate Cedar stack, applications. Here is the simplest way is to create index.php file in your project folder, on the same level as your .git folder. You can do this in terminal with this command:

$ touch index.php

Then we turn off PHP with .htaccess directive. You can add line to .htaccess and create it with this terminal command:

$ echo 'php_flag engine off' > .htaccess

This two terminal command will create empty index.php file and .htaccess file which turns PHP off. This solution was discovered by Kenneth Reitz.

Another approach is less elegant but also involves PHP. Create file index.php on the same level as index.html in the project folder which you would like to publish/deploy to Heroku with the following content:

<?php echo file_get_contents('index.html'); ?>

Third way is to use Ruby and Ruby Bamboo stack. In this case, we would need the following structure:

 -project folder
    config.ru
   /public
      index.html
      /css
      app.js
      ...

The path in index.html to CSS and other assets should be relative. i.e. ‘css/style.css’. The config.ru file should contain the following code:

use Rack::Static, 
  :urls => ["/stylesheets", "/images"],
  :root => "public"

run lambda { |env|
  [
    200, 
    {
      'Content-Type'  => 'text/html', 
      'Cache-Control' => 'public, max-age=86400' 
    },
    File.open('public/index.html', File::RDONLY)
  ]
}

For more details, you could refer to official Bamboo Heroku documentation.

Last but not least, for Python and Django developers, you could add following to your urls.py:

urlpatterns += patterns(”, (r’^static/(?P.*)$’, ‘django.views.static.serve’, {‘document_root’: settings.STATIC_ROOT}),)

Or with this Procfile line:

web: python my_django_app/manage.py collectstatic --noinput; bin/gunicorn_django --workers=4 --bind=0.0.0.0:$PORT my_django_app/settings.py 

The full Django post is at Managing Django Static Files on Heroku.

If you use NodeJS, here is how to write your own server:

var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;

http.createServer(function(request, response) {

  var uri = url.parse(request.url).pathname
    , filename = path.join(process.cwd(), uri);

  path.exists(filename, function(exists) {
    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';

    fs.readFile(filename, "binary", function(err, file) {
      if(err) {        
        response.writeHead(500, {"Content-Type": "text/plain"});
        response.write(err + "\n");
        response.end();
        return;
      }

      response.writeHead(200);
      response.write(file, "binary");
      response.end();
    });
  });
}).listen(parseInt(port, 10));

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

Pilot Rapid Prototyping with JavaScript and NodeJS Class

Traditional Computer Science education sucks big time when it comes to modern agile technologies like Ruby on Rails, Django, NodeJS, and NoSQL databases. Last time I checked, the maximum that was offered were classes in Web Design I, Web Design II and Photoshop Basics. WTF?! Don’t get me wrong. I have Master’s degree in Information Systems Technology and value fundamentals, but I was never taught anything up-to-date. There was some ASP, some C++, some SQL, but most of my learning I had to do on my own. Sure there are tons information online and in books, but not everybody has time, dedication, focus and self-discipline to master a new technical skill this way. Reading a book or watching a screencast is just not enough. The best learning comes from 25% books, 25% peer-to-peer communication and discussion, 25% student-to-teacher relationship; the last 25% is the time and practice on your own.

I saw a huge need for effective technical trainings and decided to validate my idea. I already had plenty of teaching experience from college years, during which I wrote my first textbook, had it published on a curriculum for my classmates a year later, and from teaching yoga classes. I needed a pilot class, so I approached startup accelerator and fund, StartupMonthly, and offered to develop and teach the “Rapid Prototyping with JavaScript and NodeJS” training.

I chose JavaScript and NodeJS because students will be able to use the same language both for front-end and back-end development. Their brains don’t have to switch thus saving time and speeding the learning process. NodeJS is becoming more and more popular due to its real-time support and I’m very passionate about this technology. The training runs over a long weekend, starting on Friday night with an optional Q&A session on setting up your environment. Then, we have two full days on Saturday and Sunday, making the course 16 hours total. This way, people who have full time jobs don’t have to take time off to attend. The class is very hands-on and, as much as possible, inline with the principles of Flipped Teaching.

Rapid Prototyping with JavaScript and NodeJS - Day 1
Day 1

The goal was not to make a profit. So we priced the training very aggressively twice or thrice lower than the market price of our competitors in order to attract students. The results were amazing! The goal was to sell at least 10 seats and we had 15 people in our first class! Big thanks to Yuri Rabinovich, killer StartupMonthly team and its vast network of people interested in technology :)

Rapid Prototyping with JavaScript and NodeJS - Day 2
Day 2

Then the hard work began. In a true spirit of lean startup methodology (hey, this is what we teach, right?) the manual had only a bare minimum of information and was tailored towards intermediate web and JavaScript developers. The majority was doing well, but I couldn’t say that for everyone. This was a good feedback for me, and helped to improve the manual by including many simple steps and additional terminal commands for deployment and Git.

Optimize but not too over optimize
“Optimize, but not over optimize”

Overall, students were tired, but happy with the number of new technologies they’ve tried. It was sort of a Chinese Buffet of Programming. You don’t have to try everything, you only pick what you want and indulge in it :) Here is the list of topics to give you an idea:

  • Agile, Continuous Deployment, TDD, Pair Programming
  • Basic front-end technologies: JavaScript, HTML, CSS
  • NodeJS and its advantages. Event driven programming.
  • MongoDB and Document Store and Key-Value concepts.
  • JSON, structure and examples.
  • Could computing. Cloud platforms: Windows Azure, Heroku.
  • Structure of HTTP Request and Response: headers, body, methods
  • RESTful API, examples and advantages.
  • Overview of HTML: structure, tags and syntax. Inclusion of CSS, JavaScript files/tags.
  • jQuery: AJAX, cross-domain calls and JSONP
  • Twitter Bootstrap: grid layout, form components, icons
  • LESS: mixins, variables and compilation.
  • BackboneJS: structure, events, view, sub-views, models, collections and event listeners and event binding.
  • Parse.com: plain REST API calls with jQuery ajax function and JavaScript SDK with Backbone compatible library.
  • Generating of SSH keys, configuring Git, GitHub, Heroku and Windows Azure for deployment.
  • Installation and basic configuration of NodeJS and MongoDB in local environment.
  • Deployment of NodeJS and MongoDB and static/front-end applications to PaaS cloud services like Windows Azure and Heroku with Git.
  • Building sample applications with NodeJS, jQuery, BackboneJS, Twitter Bootstrap, MongoDB, Parse.com and other tools/technologies. Deploying it to cloud services.
  • Building your own idea/prototype and presenting it. Deploying it to cloud services.
  • Practicing Paired Programming and Test-Driven Development techniques.
Next Billion-Dollar Idea
Next Billion-Dollar Idea

By the end of the weekend, we had 3 teams with 2 to 3 people in each. The teams built or started to build applications using their own ideas. One of them was a remake of Reddit with better UX/UI and the other was a service for angry ex-girlfriends to post (mostly negative I suspect) feedbacks on their ex-boyfriends :)

Here are some testimonials from the students:

“Thanks Yuri and all of you folks. It was a great session – very educative, and it certainly helped me brush up on my Javascript skills. Look forward to seeing/working with you in the future” – Sam Sur.

“Thanks for putting this workshop together this weekend… what we did with Bootstrap + Parse was really quick & awesome” – Mariya Yao.

“Thanks a lot to all and special thanks to Azat and Yuri.
I enjoyed it a lot and felt motivated to work hard to know these technologies” – Shelly Arora.

Q&A Session
Q&A Session

Next weekend, August 10–12 2012, I’m teaching the second class of “Rapid Prototyping with JavaScript and NodeJS”. I’m exited to share my experience and passion with another 10–20 smart people and make a small dent in technical education!

“Advanced Prototyping with JavaScript and NodeJS” and “Mobile Prototyping with JavaScript” trainings are coming on the weekend of August 25–26 2012. We have other cities like Los Angeles and New York in a pipeline and, (knock on wood) the future for “Rapid Prototyping” series looks very promising .