DEV Community

Cover image for Deploying Dart 2 apps on Heroku
Jermaine
Jermaine

Posted on • Edited on • Originally published at creativebracket.com

Deploying Dart 2 apps on Heroku

Having spent the last 2 weeks working on a web app as part of exploring client-side development in Dart, I've got it deployed on Heroku and I want to show how you could do the same. I won't be covering how I wrote the app since the focus here is on deployment. That being said, I will link to the source code at the end of the article ๐Ÿ˜‰

Prerequisites ๐Ÿ”ฅ

You'll need these to begin:

  1. Dart 2 SDK
  2. Git
  3. Heroku Account
  4. Heroku CLI

Once they're set up, login with your credentials by running heroku login in your terminal.


1. Set up your web project

Navigate to your project in the terminal. If you do not have one you could clone my repo containing my solution and skip straight to step #3.

Alternatively, you could generate a test project using the stagehand scaffolding tool:

$ pub global activate stagehand
$ mkdir web_project && cd web_project
$ stagehand web-simple
Enter fullscreen mode Exit fullscreen mode

2. Write an HTTP server

Amend the dependencies of the generated pubspec.yaml file to this:

dependencies:
  shelf: any
  shelf_static: any
Enter fullscreen mode Exit fullscreen mode

Run pub get to update our dependencies. We're using shelf to simplify creating a web server.

Create bin/main.dart with the logic for spawning our server:

import 'dart:io' show Platform;
import 'dart:async' show runZoned;
import 'package:path/path.dart' show join, dirname;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_static/shelf_static.dart';

void main() {
  // Assumes the server lives in bin/ and that `webdev build` ran
  var pathToBuild = join(dirname(Platform.script.toFilePath()), '..', 'build');

  var handler = createStaticHandler(pathToBuild, defaultDocument: 'index.html');

  var portEnv = Platform.environment['PORT'];
  var port = portEnv == null ? 9999 : int.parse(portEnv);

  runZoned(() {
    io.serve(handler, '0.0.0.0', port);
    print("Serving $pathToBuild on port $port");
  }, onError: (e, stackTrace) => print('Oh noes! $e $stackTrace'));
}
Enter fullscreen mode Exit fullscreen mode

3. Run the project locally

Install the webdev tool:

$ pub global activate webdev
Enter fullscreen mode Exit fullscreen mode

Then run the command below to generate our bundle:

$ webdev build # or `pub global run webdev build`
Enter fullscreen mode Exit fullscreen mode

This will produce a build folder.

Production bundle generated with webdev tool

Run dart bin/main.dart and visit http://localhost:9999

Image of localhost:9999

4. Create your Heroku app

Run the following command to create a new app:

$ heroku create
Creating secure-spire-84236... done, stack is cedar-14
http://secure-spire-84236.herokuapp.com/ | https://git.heroku.com/secure-spire-84236.git
Git remote heroku added
Enter fullscreen mode Exit fullscreen mode

This will generate a random name for your app, so secure-spire-84236 in this case.

Lastly, commit your project and add heroku remote:

$ git init
$ git add .
$ git commit -m "Initial commit."

$ heroku git:remote -a secure-spire-84236
Enter fullscreen mode Exit fullscreen mode

5. Configure the buildpack

Running the deploy command(git push heroku master) will throw an exception since Heroku requires the correct buildpack for running Dart apps.

A buildpack contains scripts that set the necessary dependencies to build and serve your project. Heroku does not officially support Dart at this present time.

However the platform allows us to specify custom buildpacks, and although the Dart team has one, I made a tweak to get it working with Dart 2, so we'll use my buildpack:

$ heroku buildpacks:set https://github.com/graphicbeacon/heroku-buildpack-dart.git
Enter fullscreen mode Exit fullscreen mode

And set the required configurations needed by the buildpack:

$ heroku config:set DART_SDK_URL=https://storage.googleapis.com/dart-archive/channels/dev/release/2.0.0-dev.67.0/sdk/dartsdk-linux-x64-release.zip # From the dart install page
$ heroku config:set DART_BUILD_CMD="/app/dart-sdk/bin/pub global activate webdev && /app/dart-sdk/bin/pub global run webdev build"
Enter fullscreen mode Exit fullscreen mode

The tells the buildpack to pull the latest Dart SDK and build the project using the webdev tool.

6. Deploy all the things! ๐Ÿš€

Create a Procfile at our project root with the instructions to start our server:

web: ./dart-sdk/bin/dart bin/main.dart
Enter fullscreen mode Exit fullscreen mode

Commit that change and now deploy:

$ git push heroku master
Enter fullscreen mode Exit fullscreen mode

You should see a confirmation message with the web url:

Confirmation message with web url

And visit in the browser:

Site open in browser

Conclusion

I hope you enjoyed this tutorial. Jot down some comments and let me know how you felt on this one.

Here's the game I deployed and the source code.

Like, share and follow me ๐Ÿ˜ for more content on Dart.

Quick links

  1. Dart 2 SDK
  2. How Heroku Works
  3. Get Started | Webdev Dart
  4. Free Dart screencasts on Egghead.io

Top comments (5)

Collapse
 
erwinagpasa profile image
Erwin

Failed to build webdev:webdev:
../../.pub-cache/hosted/pub.dartlang.org/dds-2.1.6+2/lib/src/cpu_samples_manager.dart:73:21: Error: Type 'CpuSamplesEvent' not found.
void cacheSamples(CpuSamplesEvent samples) {
^^^^^^^^^^^^^^^
../../.pub-cache/hosted/pub.dartlang.org/dds-2.1.6+2/lib/src/cpu_samples_manager.dart:73:21: Error: 'CpuSamplesEvent' isn't a type.
void cacheSamples(CpuSamplesEvent samples) {

Collapse
 
pcherkasova profile image
Polina Cherkasova

It worked. Thank you!

Collapse
 
creativ_bracket profile image
Jermaine

Perfect.

Collapse
 
stargator profile image
Stargator • Edited

Isn't webdev for Dart 2.0 apps?

Edit: Ah I see, you intentionally are doing a Dart 2.0 app.

I would add Dart 2.0 as a prerequisite

Collapse
 
creativ_bracket profile image
Jermaine

Hey Stargator, sorry for the confusion. Updated the Prerequisites.