Tuesday, August 14, 2012

Running Dart in the Cloud with Heroku

[EDIT: Updated on 2014-10-11]

Dart, the new programming language for modern web apps, certainly compiles to JavaScript. Did you know that Dart also runs on the server as well? Thanks to Heroku's support for third-party runtimes, you can now run your server-side Dart app on Heroku's cloud. Read on to learn how.

(Disclaimer: Even though Heroku can host arbitrary runtimes, they don't officially support the Dart runtime.)


Dart for modern web apps

Dart is a class based, single inheritance, object-oriented, optionally typed language that is built to help developers of many backgrounds build awesome modern web apps. Most importantly, Dart compiles to JavaScript so that your Dart apps can run all over the web.

Dart is familiar to JavaScript, Java, C, C++, and C# developers. There's even bits of Smalltalk in there. While it has a syntax that is instantly recognizable, it also has cool new features like optional static types and isolates. Check out the Dart language tour or watch an Introduction to Dart to learn more.

Dart is more than a language. The project is also building an Editor, core libraries, a static analyzer, and even a virtual machine. The Dart VM can run Dart code directly on the command line for server-side apps.

Heroku for easy cloud scaling

Heroku is a platform as a service for cloud hosted web apps. Originally a super easy way to host Ruby apps, they've since expanded to support Java, Python, node.js, and more. Use a git based deploy process to upload your app, and Heroku takes care of the infrastructure and configuration. Learn more about how Heroku works.

Recently, Heroku started offering support for hosting arbitrary runtimes. They combine your web app's code with your binaries (as long as the binaries are compiled for 64-bit Linux) and distribute it across their infrastructure. These buildpacks enable 3rd parties to bundle runtimes for Heroku.

Heroku + Dart

Yes, this means that we can take pre-built binaries of the Dart virtual machine and use it to power server-side apps running on the Heroku cloud. The Heroku buildpack for Dart is exactly what we need to tell Heroku how to configure and run a Dart server-side app.

Now you can use the same language for building the client app and the server app. Awesome!

Build a simple Dart server

To start, create a simple Dart server app. I won't cover the full libraries available for server-side programming in Dart, but check out the dart:io library to see what is available. For the curious, the dart:io library lets you read and write files and directories, start processes, connect to sockets, and run a web server.

For higher-level frameworks, check out Shelf (and its many plugins (middleware), such as shelf_static), express, redstone, force, and more on pub.dartlang.org.

To keep things simple, here's a minimal HTTP server built with dart:io primitives:


import 'dart:io';
import 'dart:json' as JSON;

main() {
  var port = int.parse(Platform.environment['PORT']);
  HttpServer.bind('0.0.0.0', port).then((HttpServer server) {
    print('Server started on port: ${port}');
    server.listen((HttpRequest request) {
      var resp = JSON.stringify({
        'Dart on Heroku': true,
        'Buildpack URL': 'https://github.com/igrigorik/heroku-buildpack-dart',
        'Environment': Platform.environment}
      );
      request.response..headers.set(HttpHeaders.CONTENT_TYPE, 'application/json')
                      ..write(resp)
                      ..close();
    });
  });
}




The above code creates an HttpServer and sets up a default handler. All requests to this server will receive a JSON encoded response, full of information about the running environment. Even though this code starts its own HTTP server, Heroku runs this app behind its own set of proxies, firewalls, etc.

Next, create a Procfile in the root of your project. The Procfile tells Heroku how to run the app.

web: /app/dart-sdk/bin/dart main.dart

The above file says that to run the web server for this app, execute the dart command and run the main.dart script.

Deploying to Heroku

With the application code created, you're ready to create the application at Heroku. Make ure you have downloaded and installed the Heroku toolbelt, and have created a Heroku account.

Remember that Heroku uses a git based deploy, so you need to get the files into git before pushing up to Heroku.

$> cd <to where main.dart and Procfile are>
$> git init
$> git add .
$> git commit -am "first commit"

Now create the app at Heroku. You must use the Cedar-14 stack, which runs on Ubuntu 14. You must also specify the URL to the Dart SDK, compiled and compressed into a single .zip file. Find all the Dart SDK downloads, including the 64-bit Linux builds, from the Dart Download Archives.


$> heroku create myapp_name -s cedar-14
$> heroku config:set DART_SDK_URL=<.zip of a 64-bit Dart SDK>
$> heroku config:add BUILDPACK_URL=https://github.com/igrigorik/heroku-buildpack-dart.git

Finally, push the app up to the Heroku cloud.

$> git push heroku master


You should see something like:


....lots of debug output....
Built 5 files to "build".
total
-----> Discovering process types
       Procfile declares types -> web

-----> Compressing... done, 10.8MB
-----> Launching... done, v6
       http://dartserver.herokuapp.com/ deployed to Heroku


Tada! You now have a Dart server app running in the cloud.

More details of using Heroku with Dart can be found in the Dart buildpack homepage on Github.


Props and thanks

Let's thank Ilya Grigorik for working out the kinks in the process and open sourcing his work.
Post a Comment

Disclaimer

I'm probably required to say that the views expressed in this blog are my own, and do not necessarily reflect those of my employer. Also, except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the BSD License.