How to Deploy an Express.js application to AWS

Express is a flexible Node.js web framework for creating web and mobile applications quickly and easily. It provides a minimal layer of features on top of the standard Node.js library.

In this tutorial you'll learn how to prepare an existing Express application for production, and how to deploy it to AWS. You'll also learn to how to configure and deploy an nginx reverse proxy.

This tutorial uses the Nanobox Express.js quickstart, however, the process will be the same for any existing Express application.

Prerequsites

A basic knowledge of Node.js and Express, along with an existing Express application is recommended.

We also suggest you read the Express performance best practices before deploying your application.

We'll use Nanobox for deployment because it makes the process much quicker and easier. You can create an account (it's free!) and download Nanobox to get started.

Configure Express for Production

Before deploying your application to AWS there are a few things that need to happen.

First, make sure your app is listening on all available IPs by updating your bin/www:

server.listen(port, '0.0.0.0');  

Next, you'll add a simple configuration file, then connect your database, and finally setup the nginx reverse proxy.

The boxfile.yml

Nanobox uses a simple config file, the boxfile.yml, to provision your applications environment. In the boxfile.yml you’ll specify everything your application needs to run.

Create a boxfile.yml at the root of your project with the following:

run.config:  
  engine: nodejs

  # add nginx package
  extra_packages:
    - nginx

# add a postgres database
data.db:  
  image: nanobox/postgresql

# add a web component and give it a "start" command
web.main:  
  start:
    nginx: nginx -c /app/config/nginx.conf
    node: npm start

# add a worker component and give it a "start" command
# worker.main:
#   start: node worker.js

The boxfile.yml is used to provision both a local development environment and your production environment.

Note: This example uses a postgres database. Make sure that you specify the correct data component for your application.

Connecting the Database

To maintain the portability of your environment and the security of your application, it's recommended that you use environment variables (evars) when connecting to services such as a database.

First, make sure that you have any dependencies your database requires installed. Since this application is using postgres it needs the pg-promise module installed:

nanobox run yarn add pg-promise

You can then add/update your database.js with the following:

var pgp = require("pg-promise")(/*options*/);  
var db = pgp("postgres://${process.env.DATA_DB_USER}:${process.env.DATA_DB_PASS}@${process.env.DATA_DB_HOST}/gonano");

Configure Nginx as a Reverse Proxy

Create a /config directory at the root of your project and add the following nginx.conf:

config/nginx.conf
worker_processes 1;  
daemon off;

events {  
    worker_connections 1024;
}

http {  
    include /data/etc/nginx/mime.types;
    sendfile on;

    gzip              on;
    gzip_http_version 1.0;
    gzip_proxied      any;
    gzip_min_length   500;
    gzip_disable      "MSIE [1-6]\.";
    gzip_types        text/plain text/xml text/css
                      text/comma-separated-values
                      text/javascript
                      application/x-javascript
                      application/atom+xml;

    # Proxy upstream to the node process
    upstream express {
        server 127.0.0.1:3000;
    }

    # Configuration for Nginx
    server {

        # Listen on port 8080
        listen 8080;

        root /app/public;

        try_files $uri/index.html $uri @express;

        # Proxy connections to express
        location @express {
            proxy_pass         http://express;
            proxy_redirect     off;
            proxy_set_header   Host $host;
        }
    }
}

Stage a Production Deploy

Nanobox allows you to stage a production deploy on your local machine with the dry-run command.

Add a DNS alias for easy access from the browser and then do a test deploy:

# Add a DNS alias for easy access
nanobox dns add dry-run express.stage

# Deploy to a local staging environment
nanobox deploy dry-run

This will deploy your app locally, simulating a production deploy. Once complete, you can visit your app at express.stage/.

Deploy Express to AWS

After staging your app to verify it works, it’s ready to deploy to production. If you haven't already, create a free account with Nanobox.

Launch an App on AWS

Before you're able to deploy you'll need to add AWS as a hosting provider.

add-aws-as-provider

Once you've linked your AWS account you can launch a new app.

Deploy to AWS

Once your app is created, add it as a remote (by name) and deploy to it.

nanobox remote add app-name  
nanobox deploy  

When you deploy, Nanobox builds your codebase locally and sends it to the server, then it create containers for each of the app’s components (web and database), and starts your application.

That’s it! Your app is live!

Update NODE_ENV

One last thing you'll want to make sure you do is set your app to run in production mode.

From your dashboard go to your app -> config -> environment variables. There add a new evar with they key NODE_ENV and the value of production.

For this change to take place you'll need to redeploy your application (there is handy link right there to do so).

redploy-after-adding-evar

Once your app is redeployed you'll be running in production.

What next?

Setting up an Express development environment (coming soon)
Optimizing Express in production (coming soon)
Managing Express in production (coming soon)

Need help?

Let us know if you have any questions, or run into any issues. We love helping you get your apps running so much that we do it for free!

You can reach us at help@nanobox.io or join our Slack team and reach out.

Posted in Deployment, Node.js, Express.js, AWS, Nanobox