You have built a great project: it is modularized, has tests, has been automatized to do common tasks, and finally you have built a production version with Gulp; however, now how do you deploy to a production server?
This chapter examines what to do with the production version of your project. Here, you will see how to run your node server and frontend assets in a production environment.
There are many choices to run your project in production mode; you can deploy on a bare metal server, use a virtual machine, on a shared host such as DigitalOcean or RackSpace, or maybe just deploy it to a PaaS (Platform as a service) service such as Heroku.
In the following section, we will see how to deploy to an Heroku instance, this is the easiest way to make a deployment as you don't have to worry about the server details and you can manage all the configurations in a single configuration file.
If you already have your own infrastructure or simply prefer to work with server instances such as DigitalOcean or RackSpace virtual server, we will show you how to configure a production environment on a server, where you have access to a shell.
Heroku is a PaaS, which means that you don't have to worry about the details of the server configuration where you are deploying your code, you only focus on your code; Heroku will do the difficult job with the infrastructure configuration.
Instead of using a shell to install, configure, and tune up your packages in order to run in production mode, you only have to edit a configuration file and publish your changes with the standard git push
command.
Heroku uses lightweight Linux containers that run a single command in order to run your projects in the Heroku platform. Heroku calls these containers Dynos. A Dyno can host your code and run it as a single process in an isolated Linux environment.
If you don't have an experience in Linux containers such as Docker, you can imagine a container to be like a small virtual machine without hardware emulation; a Linux container uses the same kernel as the host machine, it means that you don't need to emulate hardware:
By default, Heroku will use Celadon Cedar stack to build Dynos; and Celadon Cedar stack is based on the Ubuntu distribution. With this is mind, you will get an Ubuntu-like distribution, where you can run your code written on:
Dyno comes in three different types, as shown in the following:
As you may have guessed that in this book, we will only use the Web Dynos with Node.js to run our Contacts app
.
The first thing to do in order to start working with Heroku is to register with the service, as follows:
Once you are registered in the platform, you will need to install the Heroku Toolbelt in your host; there are versions available for Linux, Mac OS X, and Windows. After the installation process, you can use the heroku
command to authenticate the service:
$heroku login Enter your Heroku credentials. Email: [email protected] Password (typing will be hidden): Authentication successful.
After you have authenticated with the Heroku service, you can start creating Dynos using the create command:
$ heroku create Creating enigmatic-anchorage-3587... done, stack is cedar-14 https://enigmatic-anchorage-3587.herokuapp.com/ | https://git.heroku.com/enigmatic-anchorage-3587.git Git remote heroku added
When you create a new Dyno on Heroku, it generates a random name for your Dyno. In the preceding example, the name is enigmatic-anchorage-3587
and you can access to your Dyno at https://enigmatic-anchorage-3587.herokuapp.com:
You can deploy your application by pushing your changes to the Git server located at https://git.heroku.com/enigmatic-anchorage-3587.git. You will need to add this address as a remote server in your repo:
$ git remote add heroku https://git.heroku.com/enigmatic-anchorage-3587.git
If you make a push right now, the deployment will not work and that's because you need to tell Heroku how to run your project; this is done with a configuration file named Procfile
that you should put in the application root:
web: node server/index.js
The code is very simple, run the server/index.js
script. You can test whether the configuration is working with the local
command; this command is very useful in order to find bugs or issues before making a real deployment:
$ heroku local Installing Heroku Toolbelt v4... done Setting up iojs-v3.2.0... done Installing core plugins heroku-apps, heroku-fork, heroku-git, heroku-local, heroku-run, heroku-status... done Downloading forego-0.16.1 to /Users/abiee/.heroku... done forego | starting web.1 on port 5000 web.1 | Server running You can access the server using the browser at the http://localhost:8000/ URL. If you don't get any issues, you can make a real deployment by pushing the code at the master branch: $ git checkout master $ gulp build $ git add . $ git commit "Deployment build" $ git push heroku master Counting objects: 63, done. Delta compression using up to 8 threads. Compressing objects: 100% (57/57), done. Writing objects: 100% (63/63), 380.85 KiB | 0 bytes/s, done. Total 63 (delta 3), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Node.js app detected remote: remote: -----> Creating runtime environment remote: remote: NPM_CONFIG_LOGLEVEL=error remote: NPM_CONFIG_PRODUCTION=true remote: NODE_ENV=production remote: NODE_MODULES_CACHE=true remote: remote: -----> Installing binaries remote: engines.node (package.json): unspecified remote: engines.npm (package.json): unspecified (use default) remote: remote: Resolving node version (latest stable) via semver.io... remote: Downloading and installing node 0.12.7... remote: Using default npm version: 2.11.3 remote: remote: -----> Restoring cache remote: Skipping cache (new runtime signature) remote: remote: -----> Building dependencies remote: Pruning any extraneous modules remote: Installing node modules (package.json) ... remote: -----> Caching build remote: Clearing previous node cache remote: Saving 1 cacheDirectories (default): remote: - node_modules remote: remote: -----> Build succeeded! remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: ├── [email protected] remote: └── [email protected] remote: remote: -----> Discovering process types remote: Procfile declares types -> web remote: remote: -----> Compressing... done, 25.4MB remote: -----> Launching... done, v3 remote: https://enigmatic-anchorage-3587.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy.... done. To https://git.heroku.com/enigmatic-anchorage-3587.git
In the output logs, you can see what Heroku is doing:
Node
project due the presence of the package.json
file.NODE_ENV
environment variable in your code in order to use some special configuration for production environments.package.json
file to see what version of node to install. You can specify a node version to install with the engines configuration, as follows:"engines": { "node": "^0.12.21" },
package.json
file.Procfile
.Once the project is running in the Heroku infrastructure, you can see the result at https://enigmatic-anchorage-3587.herokuapp.com/:
As you can see, deploying to Heroku infrastructure is very straightforward, you don't have to worry about the server details such as the HTTP server or the process management so that you can focus on your application development and forget about the infrastructure.
If you have any issues with your application in production, you can see what's happening with the logs
command:
$ heroku logs –tail
This will show the last log messages in the Heroku server. Please consult the online documentation of the service for more details; here you can find information about how to scale your application, connect Dyno instances to databases, and so on.
13.58.220.83