##Introduction
This tutorial will have you deploying a Node.js app in minutes.
Hang on for a few more minutes to learn how it all works, so you can make the most out of Heroku.
The tutorial assumes that you have a free Heroku account, and that you have Node.js and npm installed.
##Set up
In this step you will install the Heroku Toolbelt. This provides you access to the Heroku Command Line utility, as well as git and Foreman, tools you’ll use in later steps.
Download Heroku Toolbelt for Mac OS X
Once installed, you can use the heroku command from your command shell.
Log in using the email address and password you used when creating your Heroku account:
$ heroku login
Enter your Heroku credentials.
Email: zeke@example.com
Password:
Authentication successful.
Authenticating is required to allow both the heroku and git commands to operate.
Note that if you’re behind a firewall that requires use of a proxy to connect with external HTTP/HTTPS services, you can set the HTTP_PROXY or HTTPS_PROXY environment variables before running the heroku command.
##Prepare the app
In this step, you will prepare a simple application that can be deployed.
Execute the following commands to clone the sample application:
$ git clone https://github.com/heroku/node-js-getting-started.git
$ cd node-js-getting-started
You now have a functioning git repository that contains a simple application as well as a package.json file, which is used by Node’s dependency manager.
##Deploy the app
In this step you will deploy the app to Heroku.
Create an app on Heroku, which prepares Heroku to receive your source code.
$ heroku create
Creating sharp-rain-871... done, stack is cedar-14
http://sharp-rain-871.herokuapp.com/ | https://git.heroku.com/sharp-rain-871.git
Git remote heroku added
When you create an app, a git remote (called heroku
) is also created and associated with your local git repository.
Heroku generates a random name (in this case sharp-rain-871
) for your app - you can pass a parameter to specify your own, or rename it later with heroku apps:rename.
Now deploy your code:
$ git push heroku master
Counting objects: 343, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (224/224), done.
Writing objects: 100% (250/250), 238.01 KiB, done.
Total 250 (delta 63), reused 0 (delta 0)
-----> Node.js app detected
-----> Resolving engine versions
Using Node.js version: 0.10.3
Using npm version: 1.2.18
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
....
Dependencies installed
-----> Building runtime environment
-----> Discovering process types
Procfile declares types -> web
-----> Compiled slug size: 4.1MB
-----> Launching... done, v9
http://sharp-rain-871.herokuapp.com deployed to Heroku
To git@heroku.com:sharp-rain-871.git
* [new branch] master -> master
The application is now deployed. Ensure that at least one instance of the app is running:
$ heroku ps:scale web=1
Now visit the app at the URL generated by its app name. As a handy shortcut, you can open the website as follows:
$ heroku open
##View logs
Heroku treats logs as streams of time-ordered events aggregated from the output streams of all your app and Heroku components, providing a single channel for all of the events.
View information about your running app using one of the logging commands, heroku logs:
$ heroku logs --tail
2011-03-10T10:22:30-08:00 heroku[web.1]: State changed from created to starting
2011-03-10T10:22:32-08:00 heroku[web.1]: Running process with command: `node index.js`
2011-03-10T10:22:33-08:00 heroku[web.1]: Listening on 18320
2011-03-10T10:22:34-08:00 heroku[web.1]: State changed from starting to up
Visit your application in the browser again, and you’ll see another log message generated.
Press Control+C to stop streaming the logs
##Define a Procfile
Use a Procfile, a text file in the root directory of your application, to explicitly declare what command should be executed to start your app.
The Procfile in the example app you deployed looks like this:
web: node index.js
This declares a single process type, web, and the command needed to run it. The name web is important here. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed.
Procfiles can contain additional process types. For example, you might declare one for a background worker process that processes items off of a queue.
##Scale the app
Right now, your app is running on a single web dyno. Think of a dyno as a lightweight container that runs the command specified in the Procfile.
You can check how many dynos are running using the ps command:
$ heroku ps
=== web (1X): `node index.js`
web.1: up 2014/04/25 16:26:38 (~ 1s ago)
Having only a single web dyno running will result in the dyno going to sleep after one hour of inactivity. This causes a delay of a few seconds for the first request upon waking. Subsequent requests will perform normally.
To avoid this, you can scale to more than one web dyno. For example:
$ heroku ps:scale web=2
For abuse prevention, scaling the application may require account verification. If your account has not been verified, you will be directed to visit the verification site.
For each application, Heroku provides 750 free dyno-hours. Running your app at 2 dynos would exceed this free, monthly allowance, so scale back:
$ heroku ps:scale web=1
##Declare app dependencies
Heroku recognizes an app as Node.js by the existence of a package.json file in the root directory. For your own apps, you can create one by running npm init.
The demo app you deployed already has a package.json, and it looks something like this:
{
"name": "node-js-getting-started",
"version": "0.1.2",
...
"dependencies": {
"express": "~4.9.x"
},
...
"engines": {
"node": "0.10.x"
},
}
The package.json file determines both the version of Node.js that will be used to run your application on Heroku, as well as the dependencies that should be installed with your application. When an app is deployed, Heroku reads this file and installs the appropriate node version together with the dependencies using the npm install command.
Run this command in your local directory to install the dependencies, preparing your system for running the app locally:
$ npm install
npm http GET https://registry.npmjs.org/express
npm http 304 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/stream-spigot
npm http GET https://registry.npmjs.org/connect/2.12.0
...
express@4.9.4 node_modules/express
+---methods@0.1.0
+---merge-descriptors@0.0.1
+---range-parser@0.0.4
+---cookie-signature@1.0.1
+---debug@2.0.0
+---fresh@0.2.0
+---buffer-crc32@0.2.1
+---cookie@0.1.0
+---mkdirp@0.3.5
+---send@0.9.2 (destroy@1.0.3, ms@0.6.2, mime@1.2.11)
...
Once dependencies are installed, you will be ready to run your app locally.
##Run the app locally
Now start your application locally using Foreman, which was installed as part of the Toolbelt:
$ foreman start web
14:39:04 web.1 | started with pid 24384
14:39:04 web.1 | Listening on 5000
Just like Heroku, Foreman examines the Procfile to determine what to run.
Your app will now be running at localhost:5000. Test that it’s working with curl or a web browser, then Ctrl-C to exit.
Foreman doesn’t just run your app - it also sets “config vars”, something you’ll encounter in a later tutorial.
##Push local changes
In this step you’ll learn how to propagate a local change to the application through to Heroku. As an example, you’ll modify the application to add an additional dependency and the code to use it.
Modify package.json to include a dependency for cool-ascii-faces:
"dependencies": {
"express": "~4.9.x",
"cool-ascii-faces": "~1.3.x"
},
Modify index.js so that it requires this module at the start. Also modify the call to route that handles ‘/‘ to use it. Your final code should look like this:
var express = require('express')
var app = express();
var cool = require('cool-ascii-faces');
app.set('port', (process.env.PORT || 5000))
app.get('/', function(request, response) {
response.send(cool());
});
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
Now test locally:
$ npm install
$ foreman start
Visiting your application at http://localhost:5000/
, you should see cute faces displayed on each refresh: ( ⚆ _ ⚆ ).
Now deploy. Almost every deploy to Heroku follows this same pattern. First, add the modified files to the local git repository:
$ git add .
Now commit the changes to the repository:
$ git commit -m "Demo"
Now deploy, just as you did previously:
$ git push heroku master
Finally, check that everything is working:
$ heroku open
##Provision add-ons
Add-ons are third-party cloud services that provide out-of-the-box additional services for your application, from persistence through logging to monitoring and more.
By default, Heroku stores 1500 lines of logs from your application. However, it makes the full log stream available as a service - and several add-on providers have written logging services that provide things such as log persistence, search, and email and SMS alerts when certain conditions are met.
Provision the papertrail logging add-on:
$ heroku addons:add papertrail
Adding papertrail on sharp-rain-871... done, v4 (free)
Welcome to Papertrail. Questions and ideas are welcome (support@papertrailapp.com). Happy logging!
Use `heroku addons:docs papertrail` to view documentation.
To help with abuse prevention, provisioning an add-on may require account verification. If your account has not been verified, you will be directed to visit the verification site.
The add-on is now deployed and configured for your application. You can list add-ons for your app like so:
$ heroku addons
To see this particular add-on in action, visit your application’s Heroku URL a few times. Each visit will generate more log messages, which should now get routed to the papertrail add-on. Visit the papertrail console to see the log messages:
$ heroku addons:open papertrail
A console will open up, showing the latest log events, and providing you with an interface to search and set up alerts:
##Start a console
You can run a command, typically scripts and applications that are part of your app, in a one-off dyno using the heroku run command. It can also be used to launch a REPL process attached to your local terminal for experimenting in your app’s environment:
$ heroku run node
Running `node` attached to terminal... up, ps.1
>
If you receive an error, Error connecting to process, then you may need to configure your firewall.
When the console starts, it has nothing loaded other than the Node.js standard library. From here you can require some of your application files.
For example, you will be be able to run the following:
> var cool = require('cool-ascii-faces')
> cool()
( ⚆ _ ⚆ )
To get a real feel for how dynos work, you can create another one-off dyno and run the bash command, which opens up a shell on that dyno. You can then execute commands there. Each dyno has its own ephemeral filespace, populated with your app and its dependencies - once the command completes (in this case, bash), the dyno is removed.
$ heroku run bash
Running `bash` attached to terminal... up, run.3052
~ $ ls
Procfile README.md composer.json composer.lock vendor views web
~ $ exit
exit
Don’t forget to type exit to exit the shell and terminate the dyno.
##Define config vars
Heroku lets you externalise configuration - storing data such as encryption keys or external resource addresses in config vars.
At runtime, config vars are exposed as environment variables to the application. For example, modify index.js so that the method repeats an action depending on the value of the TIMES environment variable:
app.get('/', function(request, response) {
var result = ''
var times = process.env.TIMES || 5
for (i=0; i < times; i++)
result += cool();
response.send(result);
});
Foreman will automatically set up the environment based on the contents of the .env file in your local directory. Create a .env file that has the following contents:
TIMES=2
If you run the app with foreman start, you’ll see two faces will be generated every time.
To set the config var on Heroku, execute the following:
$ heroku config:set TIMES=2
View the config vars that are set using heroku config:
$ heroku config
== sharp-rain-871 Config Vars
PAPERTRAIL_API_TOKEN: erdKhPeeeehIcdfY7ne
TIMES: 2
Deploy your changed application to Heroku to see this in action.
##Provision a database
The add-on marketplace has a large number of data stores, from Redis and MongoDB providers, to Postgres and MySQL. In this step you will add a free Heroku Postgres Starter Tier dev database to your app.
Add the database:
$ heroku addons:add heroku-postgresql:hobby-dev
Adding heroku-postgresql:hobby-dev... done, v3 (free)
This creates a database, and sets a DATABASE_URL environment variable (you can check by running heroku config).
Edit your package.json file to add the pg npm module to your dependencies:
"dependencies": {
"pg": "4.x",
"express": "~4.9.x",
"cool-ascii-faces": "~1.3.x"
}
Type npm install to install the new module for running your app locally. Now edit your index.js file to use this module to connect to the database specified in your DATABASE_URL environment variable:
var pg = require('pg');
app.get('/db', function (request, response) {
pg.connect(process.env.DATABASE_URL, function(err, client, done) {
client.query('SELECT * FROM test_table', function(err, result) {
done();
if (err)
{ console.error(err); response.send("Error " + err); }
else
{ response.send(result.rows); }
});
});
})
This ensures that when you access your app using the /db route, it will return all rows in the test_table table.
Deploy this to Heroku. If you access /db you will receive an error as there is no table in the database. Assuming that you have Postgres installed locally, use the heroku pg:psql command to connect to the remote database, create a table and insert a row:
$ heroku pg:psql
psql (9.3.2, server 9.3.3)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.
=> create table test_table (id integer, name text);
CREATE TABLE
=> insert into test_table values (1, 'hello database');
INSERT 0 1
=> \q
Now when you access your app’s /db route, you will see something like this:
[
{
"id": 1,
"name": "hello database"
}
]
Read more about Heroku PostgreSQL.
A similar technique can be used to install MongoDB or Redis add-ons.
##Next steps
You now know how to deploy an app, change its configuration, view logs, scale, and attach add-ons.
Here’s some recommended reading. The first, an article, will give you a firmer understanding of the basics. The second is a pointer to the main Node.js category here on Dev Center:
- Read
How Heroku Works(https://devcenter.heroku.com/articles/how-heroku-works)
for a technical overview of the concepts you’ll encounter while writing, configuring, deploying and running applications.
- Read
Deploying Node.js Apps on Heroku(https://devcenter.heroku.com/articles/deploying-nodejs)
to understand how to take an existing Node.js app and deploy it to Heroku.
- Visit the
Node.js category(https://devcenter.heroku.com/categories/nodejs)
to learn more about developing and deploying Node.js applications.