AWS Elastic Beanstalk
Developer Guide (API Version 2010-12-01)
Did this page help you?  Yes | No |  Tell us about it...
« PreviousNext »
View the PDF for this guide.Go to the AWS Discussion Forum for this product.Go to the Kindle Store to download this guide in Kindle format.

Deploying an Express Application to AWS Elastic Beanstalk

This section walks you through deploying a sample application to AWS Elastic Beanstalk using EB CLI and Git, and then updating the application to use the Express framework.

Note

This example uses Amazon RDSs, and you may be charged for its usage. For more information about pricing, go to Amazon Relational Database Service (RDS) Pricing. If you are a new customer, you can make use of the AWS Free Usage Tier. For details, go to AWS Free Usage Tier.

Step 1: Set Up Your Git Repository

EB CLI is a command line interface that you can use with Git to deploy applications quickly and more easily. EB is available as part of the Elastic Beanstalk command line tools package. For instructions to install EB CLI, see Getting Set Up with EB Command Line Interface (CLI) 3.x.

Initialize your Git repository. After you run the following command, when you run eb init, EB CLI will recognize that your application is set up with Git.

git init .

Step 2: Set Up Your Express Development Environment

Set up Express and create the project structure. The following walks you through setting up Express on a Linux operating system.

To set up your Express development environment on your local computer

  1. Install node.js. For instructions, go to http://nodejs.org/. Verify you have a successful installation before proceeding to the next step.

    $ node -v

    Note

    For information about what Node.js versions are supported, see Supported Platforms.

  2. Create a directory for your express application.

    $ mkdir node-express
    $ cd node-express
  3. Install npm if you don't already have it installed. Here's one example of how to install npm.

    node-express# cd . && yum install npm
  4. Install Express globally so that you have access to the express command.

    node-express# npm install -g express-generator
  5. Depending on your operating system, you may need to set your path to run the express command. If you need to set your path, use the output from the previous step when you installed Express. The following is an example.

    node-express# export:PATH=$PATH:/usr/local/share/npm/bin/express
  6. Run the express command. This generates package.json.

    node-express# express

    When prompted if you want to continue, type y.

  7. Set up local dependencies.

    node-express# cd . && npm install
  8. Verify it works.

    node-express# npm start

    You should see output similar to the following:

    Express server listening on port 3000

    Press Ctrl+C to stop the server.

  9. Initialize the Git repository.

    node-express# git init 
  10. Edit the .gitignore file and add the following files and directories to it. These files will be excluded from being added to the repository. This step is not required, but it is recommended.

    node-express# cat > .gitignore <<EOT 
    node_modules/
    .gitignore
    .elasticbeanstalk/
    EOT

Step 3: Configure AWS Elastic Beanstalk

You use eb, a command line tool, to configure AWS Elastic Beanstalk. If you haven't already installed eb on your local computer, do that now at the AWS Sample Code & Libraries website. If you are running eb on a Linux operating system, you will need to install Python 2.7 or 3.0.

Before you use eb, set your PATH to the location of eb. The following table shows an example for Linux/UNIX and Windows.

In Linux and UNIXIn Windows
$ export PATH=$PATH:<path to unzipped eb CLI package>/eb/linux/python2.7/

If you are using Python 3.0, the path will include python3 rather than python2.7.

C:\> set PATH=%PATH%;<path to unzipped eb CLI package>\eb\windows\

Use the init command, and AWS Elastic Beanstalk will prompt you to enter this information. If a default value is available, and you want to use it, press Enter.

To configure AWS Elastic Beanstalk

  1. From the directory where you created your local repository, type the following command:

    eb init
  2. When you are prompted for the AWS Elastic Beanstalk region, type the number of the region. For information about this product's regions, go to Regions and Endpoints in the Amazon Web Services General Reference. For this example, we'll use US West (Oregon).

  3. When you are prompted for the AWS Elastic Beanstalk application to use, type the number corresponding to the option Create new Application. AWS Elastic Beanstalk generates an application name based on the current directory name if an application name has not been previously configured. In this example, we use expressapp.

    Enter an AWS Elastic Beanstalk application name (auto-generated value is "node-express"): expressapp

    Note

    If you have a space in your application name, make sure you do not use quotation marks.

  4. Type y if AWS Elastic Beanstalk correctly detected the correct platform you are using. Type n if not, and then specify the correct platform.

  5. When prompted, type y if you want to set up Secure Shell (SSH) to connect to your instances. Type n if you do not want to set up SSH. In this example, we will type n.

    Do you want to set up SSH for your instances?
    (y/n): n
  6. Create your running environment.

    eb create
  7. When you are prompted for the AWS Elastic Beanstalk environment name, type the name of the environment. AWS Elastic Beanstalk automatically creates an environment name based on your application name. If you want to accept the default, press Enter.

    Enter Environment Name
    (default is HelloWorld-env):

    Note

    If you have a space in your application name, make sure you do not have a space in your environment name.

  8. When you are prompted to provide a CNAME prefix, type the CNAME prefix you want to use. AWS Elastic Beanstalk automatically creates a CNAME prefix based on the environment name. If you want to accept the default, press Enter.

    Enter DNS CNAME prefix
    (default is HelloWorld):
    

EB CLI will display your environment details and the status of the create operation.

To deploy a sample application

  • From the directory where you created your local repository, type the following command:

    eb deploy

    This process may take several minutes to complete. AWS Elastic Beanstalk will provide status updates during the process. If at any time you want to stop polling for status updates, press Ctrl+C. Once the environment status is Green, AWS Elastic Beanstalk will output a URL for the application. You can copy and paste the URL into your web browser to view the application.

Step 4: View the Application

To view the application

  • To open your application in a browser window, type the following:

    eb open

Step 5: Update the Application

After you have deployed a sample application, you can update it with your own application. In this step, we update the sample application to use the Express framework. You can download the final source code from http://elasticbeanstalk-samples-us-east-1.s3.amazonaws.com/nodejs-example-express.zip.

To update your application to use Express

  1. Stage the files.

    node-express# git add .
    node-express# git commit -m "First express app"
    node-express# eb deploy					
  2. Once the environment is green and ready, refresh the URL to verify it worked. You should see a web page that says "Welcome to Express".

Next, let's update the Express application to server static files and add a new page.

To configure static files and add a new page to your Express application

  1. On your local computer, create an .ebextensions directory in the top-level directory of your source bundle. In this example, we use node-express/.ebextensions.

  2. Create a configuration file, /node-express/.ebextensions/static.config. For more information about the configuration file, see Customizing and Configuring a Node.js Environment. Type the following inside the configuration file to configure static files:

    option_settings:
      - namespace: aws:elasticbeanstalk:container:nodejs:staticfiles
        option_name: /public
        value: /public
  3. On your local computer, comment out the static mapping in node-express/app.js. This step is not required, but it is a good test to see if the static mappings are configured correctly.

    //  app.use(express.static(path.join(__dirname, 'public'))); 
  4. Add your updated files to your local repository and commit your changes.

    node-express# git add .ebextensions/ app.js
    node-express# git commit -m "Making stylesheets be served by nginx."
  5. On your local computer, add node-express/routes/hike.js. Type the following:

    exports.index = function(req, res) {
     res.render('hike', {title: 'My Hiking Log'});
    };
    
    exports.add_hike = function(req, res) {
    };
  6. On your local computer, update node-express/app.js to include three new lines.

    First, add the following line to add a require for this route:

     , hike = require('./routes/hike');

    Your file should look similar to the following snippet:

    var express = require('express')
      , routes = require('./routes')
      , user = require('./routes/user')
      , http = require('http')
      , path = require('path')
      , hike = require('./routes/hike');

    Then, add the following two lines to node-express/app.js after app.get('/users', users.list);

    app.get('/hikes', hike.index);
    app.post('/add_hike', hike.add_hike);

    Your file should look similar to the following snippet:

    app.get('/', routes.index);
    app.get('/users', user.list);
    app.get('/hikes', hike.index);
    app.post('/add_hike', hike.add_hike);
  7. On your local computer, copy node-express/views/index.jade to node-express/views/hike.jade.

    node-express# cp views/index.jade views/hike.jade
  8. Add your files to the local repository, commit your changes, and deploy your updated application.

    node-express# git add .
    node-express# git commit -m "added new file"
    node-express# eb deploy
  9. Your environment will be updated after a few minutes. After your environment is green and ready, verify it worked by refreshing your browser and appending hikes at the end of the URL (e.g., http://node-express-env-syypntcz2q.elasticbeanstalk.com/hikes).

    You should see a web page titled My Hiking Log.

Next, let's update the application to add a database.

To update your application with a database

  1. On your local computer, update node-express/app.js to add the database information and add a record to the database. You can also copy app.js from http://elasticbeanstalk-samples-us-east-1.s3.amazonaws.com/nodejs-example-express.zip.

    /**
     * Module dependencies.
     */
    
    var express = require('express')
      , routes = require('./routes')
      , user = require('./routes/user')
      , hike = require('./routes/hike')
      , http = require('http')
      , path = require('path')
      , mysql = require('mysql')
      , async = require('async');
    
    var app = express();
    
    app.configure(function(){
      app.set('port', process.env.PORT || 3000);
      app.set('views', __dirname + '/views');
      app.set('view engine', 'jade');
      app.use(express.favicon());
      app.use(express.logger('dev'));
      app.use(express.bodyParser());
      app.use(express.methodOverride());
      app.use(app.router);
    //  app.use(express.static(path.join(__dirname, 'public')));
    });
    
    app.configure('development', function() {
      console.log('Using development settings.');
      app.set('connection', mysql.createConnection({
        host: '',
        user: '',
        port: '',
        password: ''}));
      app.use(express.errorHandler());
    });
    
    app.configure('production', function() {
      console.log('Using production settings.');
      app.set('connection', mysql.createConnection({
        host: process.env.RDS_HOSTNAME,
        user: process.env.RDS_USERNAME,
        password: process.env.RDS_PASSWORD,
        port: process.env.RDS_PORT}));
    });
    
    function init() {
      app.get('/', routes.index);
      app.get('/users', user.list);
      app.get('/hikes', hike.index);
      app.post('/add_hike', hike.add_hike);
    
      http.createServer(app).listen(app.get('port'), function(){
        console.log("Express server listening on port " + app.get('port'));
      });
    }
    
    var client = app.get('connection');
    async.series([
      function connect(callback) {
        client.connect(callback);
      },
      function clear(callback) {
        client.query('DROP DATABASE IF EXISTS mynode_db', callback);
      },
      function create_db(callback) {
        client.query('CREATE DATABASE mynode_db', callback);
      },
      function use_db(callback) {
        client.query('USE mynode_db', callback);
      },
      function create_table(callback) {
         client.query('CREATE TABLE HIKES (' +
                             'ID VARCHAR(40), ' +
                             'HIKE_DATE DATE, ' +
                             'NAME VARCHAR(40), ' +
                             'DISTANCE VARCHAR(40), ' +
                             'LOCATION VARCHAR(40), ' +
                             'WEATHER VARCHAR(40), ' +
                             'PRIMARY KEY(ID))', callback);
      },
      function insert_default(callback) {
        var hike = {HIKE_DATE: new Date(), NAME: 'Hazard Stevens',
              LOCATION: 'Mt Rainier', DISTANCE: '4,027m vertical', WEATHER:'Bad'};
        client.query('INSERT INTO HIKES set ?', hike, callback);
      }
    ], function (err, results) {
      if (err) {
        console.log('Exception initializing database.');
        throw err;
      } else {
        console.log('Database initialization complete.');
        init();
      }
    });
  2. On your local computer, update node-express/views/hike.jade to display a record from the database.

    extends layout
    
    block content
      h1= title
      p Welcome to #{title}
    
      div
        h3 Hikes
        table(border="1")
          tr
            td Date
            td Name
            td Location
            td Distance
            td Weather
          each hike in hikes
            tr
              td #{hike.HIKE_DATE.toDateString()}
              td #{hike.NAME}
              td #{hike.LOCATION}
              td #{hike.DISTANCE}
              td #{hike.WEATHER}
  3. On your local computer, update node-express/routes/hike.js to configure the route to show the record.

    var uuid = require('node-uuid');
    
    exports.index = function(req, res) {
      res.app.get('connection').query( 'SELECT * FROM HIKES', function(err, rows) {
        if (err) {
          res.send(err);
        } else {
          console.log(JSON.stringify(rows));
          res.render('hike', {title: 'My Hiking Log', hikes: rows});
      }});
    };
    
    exports.add_hike = function(req, res){
    };
  4. On your local computer, update node-express/package.json to add dependencies.

    {
      "name": "application-name",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "start": "node app"
      },
      "dependencies": {
        "express": "3.1.0",
        "jade": "*",
        "mysql": "*",
        "async": "*",
        "node-uuid": "*"
      }
    }
  5. On your local computer, update node-express/.ebextensions/static.config to add a production flag to the environment variables.

    option_settings:
      - namespace: aws:elasticbeanstalk:container:nodejs:staticfiles
        option_name: /public
        value: /public
      - option_name: NODE_ENV
        value: production
  6. Add your files to the local repository, commit your changes, and deploy your updated application.

    node-express# git add .
    node-express# git commit -m "updated files"
    node-express# eb deploy
  7. Your environment will be updated after a few minutes. After your environment is green and ready, verify it worked by refreshing your URL. Remember to append hikes at the end of the URL. You should see the following page.

Next, update the application to accept new entries and display records from the database.

To update the application to allow new entries into the database

  1. On your local computer, update node-express/views/hike.jade so the user can enter new entries. Add the form block inside the block content.

    extends layout
    
    block content
      h1= title
      p Welcome to #{title}
    
      form(action="/add_hike", method="post")
        table(border="1")
          tr
            td Your Name
            td
              input(name="hike[NAME]", type="textbox")
          tr
            td Location
            td
              input(name="hike[LOCATION]", type="textbox")
          tr
            td Distance
            td
              input(name="hike[DISTANCE]", type="textbox")
          tr
            td Weather
            td
              input(name="hike[WEATHER]", type="radio", value="Good")
              | Good
              input(name="hike[WEATHER]", type="radio", value="Bad")
              | Bad
              input(name="hike[WEATHER]", type="radio", value="Seattle", checked)
              | Seattle
          tr
            td(colspan="2")
              input(type="submit", value="Record Hike")
    
      div
        h3 Hikes
        table(border="1")
          tr
            td Date
            td Name
            td Location
            td Distance
            td Weather
          each hike in hikes
            tr
              td #{hike.HIKE_DATE.toDateString()}
              td #{hike.NAME}
              td #{hike.LOCATION}
              td #{hike.DISTANCE}
              td #{hike.WEATHER}
  2. On your local computer, update node-express/routes/hike.js to accept new entries. Update exports.add_hike to be the following.

    exports.add_hike = function(req, res){
      var input = req.body.hike;
      var hike = { HIKE_DATE: new Date(), ID: uuid.v4(), NAME: input.NAME,
          LOCATION: input.LOCATION, DISTANCE: input.DISTANCE, WEATHER: input.WEATHER};
    
      console.log('Request to log hike:' + JSON.stringify(hike));
      req.app.get('connection').query('INSERT INTO HIKES set ?', hike, function(err) {
        if (err) {
          res.send(err);
        } else {
          res.redirect('/hikes');
        }
      });
    };
  3. Add your files to the local repository, commit your changes, and deploy your updated application.

    node-express# git add .
    node-express# git commit -m "added new file"
    node-express# eb deploy
  4. Your environment will be updated after a few minutes. After your environment is green and ready, verify it worked by refreshing your URL and adding a couple of entries. Remember to append hikes at the end of the URL. You should see a page similar to the following diagram.

Step 6: Clean Up

If you no longer want to run your application, you can clean up by terminating your environment and deleting your application.

Use the terminate command to terminate your environment and the delete command to delete your application.

To terminate your environment and delete the application

  • From the directory where you created your local repository, type the following command:

    eb terminate

    This process may take a few minutes. AWS Elastic Beanstalk displays a message once the environment has been successfully terminated.

    Note

    If you attached an Amazon RDS DB instance to your environment, your Amazon RDS DB will be deleted, and you will lose your data. To save your data, create a snapshot before you delete the application. For instructions on how to create a snapshot, go to Creating a DB Snapshot in the Amazon Relational Database Service User Guide.