

# Deploying Node.js applications with Elastic Beanstalk
<a name="create_deploy_nodejs"></a>

This chapter provides instructions for configuring and deploying your Node.js web application to AWS Elastic Beanstalk. It also provides walkthroughs for common tasks such as database integration and working with the Express framework. Elastic Beanstalk makes it easy to deploy, manage, and scale your Node.js web applications using Amazon Web Services.

You can deploy your application in just a few minutes using the Elastic Beanstalk Command Line Interface (EB CLI) or by using the Elastic Beanstalk console. After you deploy your Elastic Beanstalk application, you can continue to use the EB CLI to manage your application and environment, or you can use the Elastic Beanstalk console, AWS CLI, or the APIs.

Follow the [QuickStart for Node.js](nodejs-quickstart.md) for step-by-step instructions to create and deploy a *Hello World* Node.js web application with the EB CLI.

**Topics**
+ [QuickStart: Deploy a Node.js application to Elastic Beanstalk](nodejs-quickstart.md)
+ [Setting up your Node.js development environment for Elastic Beanstalk](nodejs-devenv.md)
+ [Using the Elastic Beanstalk Node.js platform](create_deploy_nodejs.container.md)
+ [More Elastic Beanstalk example applications and tutorials for Node.js](nodejs-getstarted.md)
+ [Deploying a Node.js Express application to Elastic Beanstalk](create_deploy_nodejs_express.md)
+ [Deploying a Node.js Express application with clustering to Elastic Beanstalk](nodejs-express-clustering.md)
+ [Deploying a Node.js application with DynamoDB to Elastic Beanstalk](nodejs-dynamodb-tutorial.md)
+ [Adding an Amazon RDS DB instance to your Node.js Elastic Beanstalk environment](create-deploy-nodejs.rds.md)
+ [Node.js tools and resources](create_deploy_nodejs.resources.md)

# QuickStart: Deploy a Node.js application to Elastic Beanstalk
<a name="nodejs-quickstart"></a>

This QuickStart tutorial walks you through the process of creating a Node.js application and deploying it to an AWS Elastic Beanstalk environment.

**Not for production use**  
Examples are intended for demonstration only. Do not use example applications in production.

**Topics**
+ [Your AWS account](#nodejs-quickstart-aws-account)
+ [Prerequisites](#nodejs-quickstart-prereq)
+ [Step 1: Create a Node.js application](#nodejs-quickstart-create-app)
+ [Step 2: Run your application locally](#nodejs-quickstart-run-local)
+ [Step 3: Deploy your Node.js application with the EB CLI](#nodejs-quickstart-deploy)
+ [Step 4: Run your application on Elastic Beanstalk](#nodejs-quickstart-run-eb-ap)
+ [Step 5: Clean up](#go-tutorial-cleanup)
+ [AWS resources for your application](#nodejs-quickstart-eb-resources)
+ [Next steps](#nodejs-quickstart-next-steps)
+ [Deploy with the Elastic Beanstalk console](#nodejs-quickstart-console)

## Your AWS account
<a name="nodejs-quickstart-aws-account"></a>

If you're not already an AWS customer, you need to create an AWS account. Signing up enables you to access Elastic Beanstalk and other AWS services that you need.

If you already have an AWS account, you can move on to [Prerequisites](#nodejs-quickstart-prereq).

### Create an AWS account
<a name="nodejs-quickstart-aws-account-procedure"></a>

#### Sign up for an AWS account
<a name="sign-up-for-aws"></a>

If you do not have an AWS account, complete the following steps to create one.

**To sign up for an AWS account**

1. Open [https://portal.aws.amazon.com/billing/signup](https://portal.aws.amazon.com/billing/signup).

1. Follow the online instructions.

   Part of the sign-up procedure involves receiving a phone call or text message and entering a verification code on the phone keypad.

   When you sign up for an AWS account, an *AWS account root user* is created. The root user has access to all AWS services and resources in the account. As a security best practice, assign administrative access to a user, and use only the root user to perform [tasks that require root user access](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#root-user-tasks).

AWS sends you a confirmation email after the sign-up process is complete. At any time, you can view your current account activity and manage your account by going to [https://aws.amazon.com/](https://aws.amazon.com/) and choosing **My Account**.

#### Create a user with administrative access
<a name="create-an-admin"></a>

After you sign up for an AWS account, secure your AWS account root user, enable AWS IAM Identity Center, and create an administrative user so that you don't use the root user for everyday tasks.

**Secure your AWS account root user**

1.  Sign in to the [AWS Management Console](https://console.aws.amazon.com/) as the account owner by choosing **Root user** and entering your AWS account email address. On the next page, enter your password.

   For help signing in by using root user, see [Signing in as the root user](https://docs.aws.amazon.com/signin/latest/userguide/console-sign-in-tutorials.html#introduction-to-root-user-sign-in-tutorial) in the *AWS Sign-In User Guide*.

1. Turn on multi-factor authentication (MFA) for your root user.

   For instructions, see [Enable a virtual MFA device for your AWS account root user (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/enable-virt-mfa-for-root.html) in the *IAM User Guide*.

**Create a user with administrative access**

1. Enable IAM Identity Center.

   For instructions, see [Enabling AWS IAM Identity Center](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-set-up-for-idc.html) in the *AWS IAM Identity Center User Guide*.

1. In IAM Identity Center, grant administrative access to a user.

   For a tutorial about using the IAM Identity Center directory as your identity source, see [ Configure user access with the default IAM Identity Center directory](https://docs.aws.amazon.com//singlesignon/latest/userguide/quick-start-default-idc.html) in the *AWS IAM Identity Center User Guide*.

**Sign in as the user with administrative access**
+ To sign in with your IAM Identity Center user, use the sign-in URL that was sent to your email address when you created the IAM Identity Center user.

  For help signing in using an IAM Identity Center user, see [Signing in to the AWS access portal](https://docs.aws.amazon.com/signin/latest/userguide/iam-id-center-sign-in-tutorial.html) in the *AWS Sign-In User Guide*.

**Assign access to additional users**

1. In IAM Identity Center, create a permission set that follows the best practice of applying least-privilege permissions.

   For instructions, see [ Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/get-started-create-a-permission-set.html) in the *AWS IAM Identity Center User Guide*.

1. Assign users to a group, and then assign single sign-on access to the group.

   For instructions, see [ Add groups](https://docs.aws.amazon.com//singlesignon/latest/userguide/addgroups.html) in the *AWS IAM Identity Center User Guide*.

## Prerequisites
<a name="nodejs-quickstart-prereq"></a>

To follow the procedures in this guide, you will need a command line terminal or shell to run commands. Commands are shown in listings preceded by a prompt symbol (\$1) and the name of the current directory, when appropriate.

```
~/eb-project$ this is a command
this is output
```

On Linux and macOS, you can use your preferred shell and package manager. On Windows you can [install the Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash.

### EB CLI
<a name="nodejs-quickstart-prereq.ebcli"></a>

This tutorial uses the Elastic Beanstalk Command Line Interface (EB CLI). For details on installing and configuring the EB CLI, see [Install EB CLI with setup script (recommended)](eb-cli3.md#eb-cli3-install) and [Configure the EB CLI](eb-cli3-configuration.md).

### Node.js
<a name="nodejs-quickstart-prereq.runtime"></a>

Install Node.js on your local machine by following [How to install Node.js](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs) on the Node.js website. 

Verify your Node.js installation by running the following command.

```
~$ node -v
```

## Step 1: Create a Node.js application
<a name="nodejs-quickstart-create-app"></a>

Create a project directory.

```
~$ mkdir eb-nodejs
~$ cd eb-nodejs
```

Next, create an application that you'll deploy using Elastic Beanstalk. We'll create a "Hello World" RESTful web service.

**Example `~/eb-nodejs/server.js`**  

```
const http = require('node:http');

const hostname = '127.0.0.1';
const port = 8080;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello Elastic Beanstalk!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
```

This application opens a listener on port 8080. Elastic Beanstalk forwards requests to your application on port 8080 by default for Node.js.

## Step 2: Run your application locally
<a name="nodejs-quickstart-run-local"></a>

Run the following command to run your application locally.

```
~/eb-nodejs$ node server.js
```

You should see the following text.

```
Server running at http://127.0.0.1:8080/
```

Enter the URL address `http://127.0.0.1:8080/` in your web browser. The browser should display “Hello Elastic Beanstalk\$1”.

## Step 3: Deploy your Node.js application with the EB CLI
<a name="nodejs-quickstart-deploy"></a>

Run the following commands to create an Elastic Beanstalk environment for this application.

**To create an environment and deploy your Node.js application**

1. Initialize your EB CLI repository with the **eb init** command.

   ```
   ~/eb-nodejs$ eb init -p node.js nodejs-tutorial --region us-east-2
   ```

   This command creates an application named `nodejs-tutorial` and configures your local repository to create environments with the latest Node.js platform version.

1. (Optional) Run **eb init** again to configure a default key pair so that you can use SSH to connect to the EC2 instance running your application.

   ```
   ~/eb-nodejs$ eb init
   Do you want to set up SSH for your instances?
   (y/n): y
   Select a keypair.
   1) my-keypair
   2) [ Create new KeyPair ]
   ```

   Select a key pair if you have one already, or follow the prompts to create one. If you don't see the prompt or need to change your settings later, run **eb init -i**.

1. Create an environment and deploy your application to it with **eb create**. Elastic Beanstalk automatically builds a zip file for your application and deploys it to an EC2 instance in the environment. After deploying your application, Elastic Beanstalk starts it on port 8080.

   ```
   ~/eb-nodejs$ eb create nodejs-env
   ```

   It takes about five minutes for Elastic Beanstalk to create your environment.

## Step 4: Run your application on Elastic Beanstalk
<a name="nodejs-quickstart-run-eb-ap"></a>

When the process to create your environment completes, open your website with **eb open**.

```
~/eb-nodejs$ eb open
```

Congratulations\$1 You've deployed a Node.js application with Elastic Beanstalk\$1 This opens a browser window using the domain name created for your application.

## Step 5: Clean up
<a name="go-tutorial-cleanup"></a>

You can terminate your environment when you finish working with your application. Elastic Beanstalk terminates all AWS resources associated with your environment.

To terminate your Elastic Beanstalk environment with the EB CLI run the following command.

```
~/eb-nodejs$ eb terminate
```

## AWS resources for your application
<a name="nodejs-quickstart-eb-resources"></a>

You just created a single instance application. It serves as a straightforward sample application with a single EC2 instance, so it doesn't require load balancing or auto scaling. For single instance applications Elastic Beanstalk creates the following AWS resources:
+ **EC2 instance** – An Amazon EC2 virtual machine configured to run web apps on the platform you choose.

  Each platform runs a different set of software, configuration files, and scripts to support a specific language version, framework, web container, or combination thereof. Most platforms use either Apache or nginx as a reverse proxy that processes web traffic in front of your web app, forwards requests to it, serves static assets, and generates access and error logs.
+ **Instance security group** – An Amazon EC2 security group configured to allow incoming traffic on port 80. This resource lets HTTP traffic from the load balancer reach the EC2 instance running your web app. By default, traffic is not allowed on other ports.
+ **Amazon S3 bucket** – A storage location for your source code, logs, and other artifacts that are created when you use Elastic Beanstalk.
+ **Amazon CloudWatch alarms** – Two CloudWatch alarms that monitor the load on the instances in your environment and are triggered if the load is too high or too low. When an alarm is triggered, your Auto Scaling group scales up or down in response.
+ **CloudFormation stack** – Elastic Beanstalk uses CloudFormation to launch the resources in your environment and propagate configuration changes. The resources are defined in a template that you can view in the [CloudFormation console](https://console.aws.amazon.com/cloudformation).
+  **Domain name** – A domain name that routes to your web app in the form **subdomain*.*region*.elasticbeanstalk.com*. 

Elastic Beanstalk manages all of these resources. When you terminate your environment, Elastic Beanstalk terminates all the resources that it contains.

## Next steps
<a name="nodejs-quickstart-next-steps"></a>

After you have an environment running an application, you can deploy a new version of the application or a different application at any time. Deploying a new application version is very quick because it doesn't require provisioning or restarting EC2 instances. You can also explore your new environment using the Elastic Beanstalk console. For detailed steps, see [Explore your environment](GettingStarted.md#GettingStarted.Explore) in the *Getting started* chapter of this guide.

**Try more tutorials**  
If you'd like to try other tutorials with different example applications, see [More Elastic Beanstalk example applications and tutorials for Node.js](nodejs-getstarted.md).

After you deploy a sample application or two and are ready to start developing and running Node.js applications locally, see [Setting up your Node.js development environment for Elastic Beanstalk](nodejs-devenv.md).

## Deploy with the Elastic Beanstalk console
<a name="nodejs-quickstart-console"></a>

You can also use the Elastic Beanstalk console to launch the sample application. For detailed steps, see [Create an example application](GettingStarted.md#GettingStarted.CreateApp) in the *Getting started* chapter of this guide.

# Setting up your Node.js development environment for Elastic Beanstalk
<a name="nodejs-devenv"></a>

This topic provides instructions to set up a Node.js development environment to test your application locally prior to deploying it to AWS Elastic Beanstalk. It also references websites that provide installation instructions for useful tools.

**Topics**
+ [Install Node.js](#nodejs-devenv-nodejs)
+ [Confirm npm installation](#nodejs-devenv-npm)
+ [Install the AWS SDK for Node.js](#nodejs-devenv-awssdk)
+ [Install the Express generator](#nodejs-devenv-express)
+ [Set up an Express framework and server](#nodejs-devenv-express-framework)

## Install Node.js
<a name="nodejs-devenv-nodejs"></a>

Install Node.js to run Node.js applications locally. If you don't have a preference, get the latest version supported by Elastic Beanstalk. See [Node.js](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs) in the *AWS Elastic Beanstalk Platforms* document for a list of supported versions.

Download Node.js at [nodejs.org](https://nodejs.org/en/).

## Confirm npm installation
<a name="nodejs-devenv-npm"></a>

Node.js uses the npm package manager to help you install tools and frameworks for use in your application. Since npm is distributed with Node.js, you will automatically install it when you download and install Node.js. To confirm you have npm installed you can run the following command:

```
$ npm -v
```

For more information on npm, visit the [npmjs](https://www.npmjs.com/get-npm) website.

## Install the AWS SDK for Node.js
<a name="nodejs-devenv-awssdk"></a>

If you need to manage AWS resources from within your application, install the AWS SDK for JavaScript in Node.js. Install the SDK with npm:

```
$ npm install aws-sdk
```

Visit the [AWS SDK for JavaScript in Node.js](https://aws.amazon.com/sdk-for-node-js/) homepage for more information.

## Install the Express generator
<a name="nodejs-devenv-express"></a>

Express is a web application framework that runs on Node.js. To use it, first install the Express generator command line application. Once the Express generator is installed, you can run the **express** command to generate a base project structure for your web application. Once the base project, files, and dependencies are installed you can start up a local Express server on your development machine.

 

**Note**  
These steps walk you through installing the Express generator on a Linux operating system.
For Linux, depending on your permission level to system directories, you might need to prefix some of these commands with `sudo`.

**To install the Express generator on your development environment**

1. Create a working directory for your Express framework and server. 

   ```
   ~$ mkdir node-express
   ~$ cd node-express
   ```

1. Install Express globally so that you have access to the `express` command.

   ```
   ~/node-express$ npm install -g express-generator
   ```

1. Depending on your operating system, you may need to set your path to run the `express` command. The output from the previous step provides information if you need to set your path variable. The following is an example for Linux.

   ```
   ~/node-express$ export PATH=$PATH:/usr/local/share/npm/bin/express
   ```

   When you follow the tutorials in this chapter, you'll need to run the **express** command from different directories. Each tutorial sets up a base Express project structure in it's own directory.

You have now installed the Express command line generator. You can use it to create a framework directory for your web application, set up dependencies, and start up the web app server. Next, we'll go through the steps to accomplish this in the `node-express` directory that we created.

## Set up an Express framework and server
<a name="nodejs-devenv-express-framework"></a>

Follow these steps to create the base Express framework directories and contents. The tutorials in this chapter also include these steps to set up the base Express framework in each of the tutorial's application directories.

**To set up an Express framework and server**

1. Run the `express` command. This generates `package.json`, `app.js`, and a few directories.

   ```
   ~/node-express$ express
   ```

   When prompted, type **y** if you want to continue.

1. Set up local dependencies.

   ```
   ~/node-express$ npm install
   ```

1. Verify the web app server starts up.

   ```
   ~/node-express$ npm start
   ```

   You should see output similar to the following:

   ```
   > nodejs@0.0.0 start /home/local/user/node-express
   > node ./bin/www
   ```

   The server runs on port 3000 by default. To test it, run `curl http://localhost:3000` in another terminal, or open a browser on the local computer and enter URL address `http://localhost:3000`.

   Press **Ctrl\$1C** to stop the server.

# Using the Elastic Beanstalk Node.js platform
<a name="create_deploy_nodejs.container"></a>

This topic describes how to configure, build, and run your Node.js applications on Elastic Beanstalk.

AWS Elastic Beanstalk supports a number of platform branches for different versions of the Node.js programming language. See [Node.js](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs) in the *AWS Elastic Beanstalk Platforms* document for a full list.

Elastic Beanstalk provides [configuration options](command-options.md) that you can use to customize the software that runs on the EC2 instances in your Elastic Beanstalk environment. You can [configure environment variables](environments-cfg-softwaresettings.md#environments-cfg-softwaresettings-console) required by your application, enable log rotation to Amazon S3, and map folders in your application source that contain static files to paths served by the proxy server.

Configuration options are available in the Elastic Beanstalk console for [modifying the configuration of a running environment](environment-configuration-methods-after.md). To avoid losing your environment's configuration when you terminate it, you can use [saved configurations](environment-configuration-savedconfig.md) to save your settings and later apply them to another environment.

To save settings in your source code, you can include [configuration files](ebextensions.md). Settings in configuration files are applied every time you create an environment or deploy your application. You can also use configuration files to install packages, run scripts, and perform other instance customization operations during deployments.

You can [include a `Package.json` file](nodejs-platform-dependencies.md#nodejs-platform-packagejson) in your source bundle to install packages during deployment, to provide a start command, and to specify the Node.js version that you want your application to use. You can include an [`npm-shrinkwrap.json` file](nodejs-platform-shrinkwrap.md) to lock down dependency versions.

The Node.js platform includes a proxy server to serve static assets, forward traffic to your application, and compress responses. You can [extend or override the default proxy configuration](nodejs-platform-proxy.md) for advanced scenarios.

There are several options to start your application. You can add a [Procfile](nodejs-configuration-procfile.md) to your source bundle to specify the command that starts your application. If you don't provide a `Procfile` but provide a `package.json` file, Elastic Beanstalk runs `npm start`. If you don't provide that either, Elastic Beanstalk looks for the `app.js` or `server.js` file, in this order, and runs the script.

Settings applied in the Elastic Beanstalk console override the same settings in configuration files, if they exist. This lets you have default settings in configuration files, and override them with environment-specific settings in the console. For more information about precedence, and other methods of changing settings, see [Configuration options](command-options.md).

For details about the various ways you can extend an Elastic Beanstalk Linux-based platform, see [Extending Elastic Beanstalk Linux platforms](platforms-linux-extend.md).

## Configuring your Node.js environment
<a name="nodejs-platform-console"></a>

You can use the Node.js platform settings to fine-tune the behavior of your Amazon EC2 instances. You can edit the Amazon EC2 instance configuration for your Elastic Beanstalk environment using the Elastic Beanstalk console.

Use the Elastic Beanstalk console to enable log rotation to Amazon S3 and configure variables that your application can read from the environment.

**To configure your Node.js environment in the Elastic Beanstalk console**

1. Open the [Elastic Beanstalk console](https://console.aws.amazon.com/elasticbeanstalk), and in the **Regions** list, select your AWS Region.

1. In the navigation pane, choose **Environments**, and then choose the name of your environment from the list.

1. In the navigation pane, choose **Configuration**.

1. In the **Updates, monitoring, and logging** configuration category, choose **Edit**.

### Container options
<a name="nodejs-platform-console-settings"></a>

You can specify these platform-specific options:
+ **Proxy server** – The proxy server to use on your environment instances. By default, NGINX is used.

### Log options
<a name="nodejs-platform-console-logging"></a>

The **Log Options** section has two settings:
+ **Instance profile** – Specifies the instance profile that has permission to access the Amazon S3 bucket that's associated with your application.
+ **Enable log file rotation to Amazon S3** – Specifies whether log files for your application's Amazon EC2 instances are copied to the Amazon S3 bucket associated with your application.

### Static files
<a name="nodejs-platform-console-staticfiles"></a>

To improve performance, you can use the **Static files** section to configure the proxy server to serve static files (for example, HTML or images) from a set of directories inside your web application. For each directory, you set the virtual path to directory mapping. When the proxy server receives a request for a file under the specified path, it serves the file directly instead of routing the request to your application.

For details about configuring static files using configuration files or the Elastic Beanstalk console, see [Serving static files](environment-cfg-staticfiles.md).

### Environment properties
<a name="nodejs-platform-console-envprops"></a>

Use the **Environment Properties** section to specify environment configuration settings on the Amazon EC2 instances that are running your application. These settings are passed in as key-value pairs to the application.

Inside the Node.js environment that runs in AWS Elastic Beanstalk, you can access the environment variables by running `process.env.ENV_VARIABLE`.

```
var endpoint = process.env.API_ENDPOINT
```

The Node.js platform sets the PORT environment variable to the port that the proxy server passes traffic to. For more information, see [Configuring the proxy server](nodejs-platform-proxy.md).

See [Environment variables and other software settings](environments-cfg-softwaresettings.md) for more information.

### Configuring an Amazon Linux AMI (preceding Amazon Linux 2) Node.js environment
<a name="nodejs-platform-console.alami"></a>

The following console software configuration categories are supported only on an Elastic Beanstalk Node.js environment that uses an Amazon Linux AMI platform version (preceding Amazon Linux 2).

**Notes**  
The information in this topic only applies to platform branches based on Amazon Linux AMI (AL1). AL2023/AL2 platform branches are incompatible with previous Amazon Linux AMI (AL1) platform versions and *require different configuration settings*.
 On [July 18, 2022](https://docs.aws.amazon.com/elasticbeanstalk/latest/relnotes/release-2022-07-18-linux-al1-retire.html), Elastic Beanstalk set the status of all platform branches based on Amazon Linux AMI (AL1) to **retired**. For more information about migrating to a current and fully supported Amazon Linux 2023 platform branch, see [Migrating your Elastic Beanstalk Linux application to Amazon Linux 2023 or Amazon Linux 2](using-features.migration-al.md).

#### Container options — Amazon Linux AMI (AL1)
<a name="nodejs-platform-console-settings"></a>

On the configuration page, specify the following:
+ **Proxy server** – Specifies which web server to use to proxy connections to Node.js. By default, NGINX is used. If you select **none**, static file mappings don't take effect, and GZIP compression is disabled.
+ **Node.js version** – Specifies the version of Node.js. For a list of supported Node.js versions, see [https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs) in the *AWS Elastic Beanstalk Platforms* guide.
+ **GZIP compression** – Specifies whether GZIP compression is enabled. By default, GZIP compression is enabled.
+ **Node command** – Lets you enter the command used to start the Node.js application. An empty string (the default) means Elastic Beanstalk uses `app.js`, then `server.js`, and then `npm start`.

## Node.js configuration namespace
<a name="nodejs-namespaces"></a>

You can use a [configuration file](ebextensions.md) to set configuration options and perform other instance configuration tasks during deployments. Configuration options can be [platform specific](command-options-specific.md) or apply to [all platforms](command-options-general.md) in the Elastic Beanstalk service as a whole. Configuration options are organized into *namespaces*.

You can choose the proxy to use on the instances for your environment by using the `aws:elasticbeanstalk:environment:proxy` namespace. The following example configures your environment to use the Apache HTTPD proxy server.

**Example .ebextensions/nodejs-settings.config**  

```
option_settings:
  aws:elasticbeanstalk:environment:proxy:
    ProxyServer: apache
```

You can configure the proxy to serve static files by using the `aws:elasticbeanstalk:environment:proxy:staticfiles` namespace. For more information and an example, see [Serving static files](environment-cfg-staticfiles.md).

Elastic Beanstalk provides many configuration options for customizing your environment. In addition to configuration files, you can also set configuration options using the console, saved configurations, the EB CLI, or the AWS CLI. See [Configuration options](command-options.md) for more information.

## The Amazon Linux AMI (preceding Amazon Linux 2) Node.js platform
<a name="nodejs.alami"></a>

If your Elastic Beanstalk Node.js environment uses an Amazon Linux AMI platform version (preceding Amazon Linux 2), consider the specific configurations and recommendations in this section.

**Notes**  
The information in this topic only applies to platform branches based on Amazon Linux AMI (AL1). AL2023/AL2 platform branches are incompatible with previous Amazon Linux AMI (AL1) platform versions and *require different configuration settings*.
 On [July 18, 2022](https://docs.aws.amazon.com/elasticbeanstalk/latest/relnotes/release-2022-07-18-linux-al1-retire.html), Elastic Beanstalk set the status of all platform branches based on Amazon Linux AMI (AL1) to **retired**. For more information about migrating to a current and fully supported Amazon Linux 2023 platform branch, see [Migrating your Elastic Beanstalk Linux application to Amazon Linux 2023 or Amazon Linux 2](using-features.migration-al.md).

### Node.js platform-specific configuration options — Amazon Linux AMI (AL1)
<a name="nodejs.alami.options"></a>

Elastic Beanstalk supports some platform-specific configurations options for Amazon Linux AMI Node.js platform versions. You can choose which proxy server to run in front of your application, choose a specific version of Node.js to run, and choose the command used to run your application.

For proxy server, you can use an NGINX or Apache proxy server. You can set the `none` value to the `ProxyServer` option. With this setting, Elastic Beanstalk runs your application as standalone, not behind any proxy server. If your environment runs a standalone application, update your code to listen to the port that NGINX forwards traffic to.

```
var port = process.env.PORT || 8080;

app.listen(port, function() {
  console.log('Server running at http://127.0.0.1:%s', port);
});
```

### Node.js language versions — Amazon Linux AMI (AL1)
<a name="nodejs.alami.versions"></a>

In terms of supported language version, the Node.js Amazon Linux AMI platform is different to other Elastic Beanstalk managed platforms. This is because each Node.js platform version supports only a few Node.js language versions. For a list of supported Node.js versions, see [https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs) in the *AWS Elastic Beanstalk Platforms* guide.

You can use a platform-specific configuration option to set the language version. For instructions, see [Configuring your Node.js environment](#nodejs-platform-console). Alternatively, use the Elastic Beanstalk console to update the Node.js version that your environment uses as part of updating your platform version.

**Note**  
When support for the version of Node.js that you are using is removed from the platform, you must change or remove the version setting prior to doing a [platform update](using-features.platform.upgrade.md). This might occur when a security vulnerability is identified for one or more versions of Node.js.  
When this happens, attempting to update to a new version of the platform that doesn't support the configured [NodeVersion](command-options-specific.md#command-options-nodejs) fails. To avoid needing to create a new environment, change the *NodeVersion* configuration option to a Node.js version that is supported by both the old platform version and the new one, or [remove the option setting](environment-configuration-methods-after.md), and then perform the platform update.

**To configure your environment's Node.js version in the Elastic Beanstalk console**

1. Open the [Elastic Beanstalk console](https://console.aws.amazon.com/elasticbeanstalk), and in the **Regions** list, select your AWS Region.

1. In the navigation pane, choose **Environments**, and then choose the name of your environment from the list.

1. On the environment overview page, under **Platform**, choose **Change**.

1. On the **Update platform version** dialog box, select a Node.js version.  
![\[Elastic Beanstalk update platform version confirmation\]](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/images/platform-nodejs-update-node-version.png)

1. Choose **Save**.

### Node.js configuration namespaces — Amazon Linux AMI (AL1)
<a name="nodejs.alami.namespaces"></a>

The Node.js Amazon Linux AMI platform defines additional options in the `aws:elasticbeanstalk:container:nodejs:staticfiles` and `aws:elasticbeanstalk:container:nodejs` namespaces.

The following configuration file tells Elastic Beanstalk to use `npm start` to run the application. It also sets the proxy type to Apache and enables compression. Last, it configures the proxy to serve static files from two source directories. One source is HTML files at the `html` path under the website's root from the `statichtml` source directory. The other source is image files at the `images` path under the website's root from the `staticimages` source directory.

**Example .ebextensions/node-settings.config**  

```
option_settings:
  aws:elasticbeanstalk:container:nodejs: 
    NodeCommand: "npm start"
    ProxyServer: apache
    GzipCompression: true
  aws:elasticbeanstalk:container:nodejs:staticfiles:
    /html: statichtml
    /images: staticimages
```

Elastic Beanstalk provides many configuration options for customizing your environment. In addition to configuration files, you can also set configuration options using the console, saved configurations, the EB CLI, or the AWS CLI. See [Configuration options](command-options.md) for more information.

# Configuring custom start commands with a Procfileon Elastic Beanstalk
<a name="nodejs-configuration-procfile"></a>

You can include a file that's called `Procfile` at the root of your source bundle to specify the command that starts your application.

**Example Procfile**  

```
web: node index.js
```

For information about `Procfile` usage see [Buildfile and Procfile](platforms-linux-extend.build-proc.md).

**Note**  
This feature replaces the legacy `NodeCommand` option in the `aws:elasticbeanstalk:container:nodejs` namespace.

# Configuring your application's dependencies on Elastic Beanstalk
<a name="nodejs-platform-dependencies"></a>

Your application might have dependencies on some Node.js modules, such as the ones you specify in `require()` statements. These modules are stored in a `node_modules` directory. When your application runs, Node.js loads the modules from this directory. For more information, see [Loading from node\$1modules folders](https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders) in the Node.js documentation.

You can specify these module dependencies using a `package.json` file. If Elastic Beanstalk detects this file and a `node_modules` directory isn't present, Elastic Beanstalk runs `npm install` as the *webapp* user. The `npm install` command installs the dependencies in the `node_modules` directory, which Elastic Beanstalk creates beforehand. The `npm install` command accesses the packages listed in the `package.json` file from the public npm registry or other locations. For more information, see the [npm Docs](https://docs.npmjs.com/about-the-public-npm-registry) website. 

If Elastic Beanstalk detects the `node_modules` directory, Elastic Beanstalk doesn't run `npm install`, even if a `package.json` file exists. Elastic Beanstalk assumes that the dependency packages are available in the `node_modules` directory for Node.js to access and load.

The following sections provide more information about establishing your Node.js module dependencies for your application.

**Note**  
If you experience any deployment issues when Elastic Beanstalk is running `npm install`, consider an alternate approach. Include the `node_modules` directory with the dependency modules in your application source bundle. Doing so can circumvent issues with installing dependencies from the public npm registry while you investigate the issue. Because the dependency modules are sourced from a local directory, dong this might also help reduce deployment time. For more information, see [Including Node.js dependencies in a node\$1modules directory](#nodejs-platform-nodemodules)

## Specifying Node.js dependencies with a package.json file
<a name="nodejs-platform-packagejson"></a>

Include a `package.json` file in the root of your project source to specify dependency packages and to provide a start command. When a `package.json` file is present, and a `node_modules` directory isn't present in the root of your project source, Elastic Beanstalk runs `npm install` as the *webapp* user to install dependencies from the public npm registry. Elastic Beanstalk also uses the `start` command to start your application. For more information about the `package.json` file, see [Specifying dependencies in a `package.json` file](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file) in the *npm Docs* website. 

Use the `scripts` keyword to provide a start command. Currently, the `scripts` keyword is used instead of the legacy `NodeCommand` option in the `aws:elasticbeanstalk:container:nodejs` namespace.

**Example package.json – Express**  

```
{
    "name": "my-app",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
      "ejs": "latest",
      "aws-sdk": "latest",
      "express": "latest",
      "body-parser": "latest"
    },
    "scripts": {
      "start": "node app.js"
    }
  }
```

**Production mode and dev dependencies**  
To specify your dependencies in the `package.json` file use the *dependencies* and *devDependencies* attributes. The *dependencies* attribute designates packages required by your application in production. The *devDependencies* attribute designates packages that are only needed for local development and testing.

If you need to install the *devDependencies* packages, set the NPM\$1USE\$1PRODUCTION environment property to `false`. With this setting we will not use the above options when running npm install. This will result in the *devDependencies* packages being installed.

## Including Node.js dependencies in a node\$1modules directory
<a name="nodejs-platform-nodemodules"></a>

To deploy dependency packages to environment instances together with your application code, include them in a directory that's named `node_modules` in the root of your project source. For more information, see [Downloading and installing packages locally](https://docs.npmjs.com/downloading-and-installing-packages-locally) in the *npm Docs* website. 

When you deploy a `node_modules` directory to an AL2023/AL2 Node.js platform version, Elastic Beanstalk assumes that you're providing your own dependency packages, and avoids installing dependencies that are specified in a [package.json](#nodejs-platform-packagejson) file. Node.js looks for dependencies in the `node_modules` directory. For more information, see [Loading from node\$1modules Folders](https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders) in the Node.js documentation.

**Note**  
If you experience any deployment issues when Elastic Beanstalk is running `npm install`, consider using the approach described in this topic as a workaround while you investigate the issue.   
 

### Considerations for Node.js on Amazon Linux 2
<a name="nodejs-al2-considerations"></a>

Read this section if you're using a *Node.js* platform branch running on *Amazon Linux 2*.

#### Considerations for Node.js on Amazon Linux 2
<a name="nodejs-al2-considerations-detail"></a>

**Note**  
The information in this topic applies to Node.js platform branches running on Amazon Linux 2. Content here describes AL2-specific features and behaviors that differ from AL2023.

**Command variations**  
The command options vary depending on the npm version included on the Amazon Linux 2 platform branch that your application runs on.
+ npm v6 — Elastic Beanstalk installs dependencies in production mode by default. It uses the command `npm install --production`. 
+ npm v7 or greater — Elastic Beanstalk omits the *devDependencies*. It uses the command `npm install --omit=dev`.

Both of the commands listed above do not install the packages that are *devDependencies*. 

**SSH and HTTPS protocols for Git dependencies**  
Starting with the March 7, 2023 Amazon Linux 2 platform release, you can use the SSH and HTTPS protocols to retrieve packages from a Git repository. Platform branch Node.js 16 supports both the SSH and HTTPS protocols. Node.js 14 only supports the HTTPS protocol.

**Example package.json – Node.js 16 supports both HTTPS and SSH**  

```
    ...
    "dependencies": {
      "aws-sdk": "https://github.com/aws/aws-sdk-js.git",
      "aws-chime": "git+ssh://git@github.com:aws/amazon-chime-sdk-js.git"
    }
```

**Versions and version ranges**  
Use the `engines` keyword in the `package.json` file to specify the Node.js version that you want your application to use. You can also specify a version range using npm notation. For more information about the syntax for version ranges, see [Semantic Versioning using npm](https://nodejs.dev/learn/semantic-versioning-using-npm) on the Node.js website. The `engines` keyword in the Node.js `package.json` file replaces the legacy `NodeVersion` option in the `aws:elasticbeanstalk:container:nodejs` namespace.

**Important**  
The feature to specify version ranges is not available for Node.js platform branches running on AL2023. We only support one Node.js version within a specific Node.js branch on AL2023. If your `package.json` file specifies a version range, we'll ignore it and default to the platform branch version of Node.js.

**Example `package.json` – Single Node.js version**  

```
{
    ...
    "engines": { "node" : "14.16.0" }
  }
```

**Example `package.json` – Node.js version range**  

```
{
    ...
    "engines": { "node" : ">=10 <11" }
  }
```

When a version range is indicated, Elastic Beanstalk installs the latest Node.js version that the platform has available within the range. In this example, the range indicates that the version must be greater than or equal to version 10, but less than version 11. As a result, Elastic Beanstalk installs the latest Node.js version 10.x.y, which is available on the [supported platform](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs).

Be aware that you can only specify a Node.js version that corresponds with your platform branch. For example, if you're using the Node.js 16 platform branch, you can only specify a 16.x.y Node.js version. You can use the version range options supported by npm to allow for more flexibility. For valid Node.js versions for each platform branch, see [https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs](https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platforms-supported.html#platforms-supported.nodejs) in the *AWS Elastic Beanstalk Platforms* guide.

**Note**  
When support for the version of Node.js that you are using is removed from the platform, you must change or remove the Node.js version setting prior to doing a [platform update](using-features.platform.upgrade.md). This might occur when a security vulnerability is identified for one or more versions of Node.js.  
When this happens, attempting to update to a new version of the platform that doesn't support the configured Node.js version fails. To avoid needing to create a new environment, change the Node.js version setting in `package.json` to a Node.js version that is supported by both the old platform version and the new one. You have the option to specify a Node.js version range that includes a supported version, as described earlier in this topic. You also have the option to remove the setting, and then deploy the new source bundle.

# Locking dependencies with npm shrinkwrap on Elastic Beanstalk
<a name="nodejs-platform-shrinkwrap"></a>

The Node.js platform runs `npm install` as the *webapp* user each time you deploy. When new versions of your dependencies are available, they're installed when you deploy your application, potentially causing the deployment to take a long time.

You can avoid upgrading dependencies by creating an `npm-shrinkwrap.json` file that locks down your application's dependencies to the current version.

```
$ npm install
$ npm shrinkwrap
wrote npm-shrinkwrap.json
```

Include this file in your source bundle to ensure that dependencies are only installed once.

# Configuring the proxy server
<a name="nodejs-platform-proxy"></a>

Elastic Beanstalk can use NGINX or Apache HTTPD as the reverse proxy to map your application to your Elastic Load Balancing load balancer on port 80. The default is NGINX. Elastic Beanstalk provides a default proxy configuration that you can either extend or completely override with your own configuration.

By default, Elastic Beanstalk configures the proxy to forward requests to your application on port 5000. You can override the default port by setting the `PORT` [environment property](create_deploy_nodejs.container.md#nodejs-platform-console) to the port that your main application listens on.

**Note**  
The port that your application listens on doesn't affect the port that the NGINX server listens to receive requests from the load balancer.

**Configuring the proxy server on your platform version**  
All AL2023/AL2 platforms support a uniform proxy configuration feature. For more information about configuring the proxy server on your platform versions running AL2023/AL2, see [Reverse proxy configuration](platforms-linux-extend.proxy.md). 

## Configuring the proxy on Amazon Linux AMI (preceding Amazon Linux 2)
<a name="nodejs-platform-proxy.alami"></a>

If your Elastic Beanstalk Node.js environment uses an Amazon Linux AMI platform version (preceding Amazon Linux 2), read the information in this section.

**Notes**  
The information in this topic only applies to platform branches based on Amazon Linux AMI (AL1). AL2023/AL2 platform branches are incompatible with previous Amazon Linux AMI (AL1) platform versions and *require different configuration settings*.
 On [July 18, 2022](https://docs.aws.amazon.com/elasticbeanstalk/latest/relnotes/release-2022-07-18-linux-al1-retire.html), Elastic Beanstalk set the status of all platform branches based on Amazon Linux AMI (AL1) to **retired**. For more information about migrating to a current and fully supported Amazon Linux 2023 platform branch, see [Migrating your Elastic Beanstalk Linux application to Amazon Linux 2023 or Amazon Linux 2](using-features.migration-al.md).

### Extending and overriding the default proxy configuration — Amazon Linux AMI (AL1)
<a name="nodejs-platform-proxy.alami.extending"></a>

The Node.js platform uses a reverse proxy to relay requests from port 80 on the instance to your application that's listening on port 8081. Elastic Beanstalk provides a default proxy configuration that you can either extend or completely override with your own configuration.

To extend the default configuration, add `.conf` files to `/etc/nginx/conf.d` with a configuration file. For a specific example, see [Terminating HTTPS on EC2 instances running Node.js](https-singleinstance-nodejs.md).

The Node.js platform sets the PORT environment variable to the port that the proxy server passes traffic to. Read this variable in your code to configure the port for your application.

```
    var port = process.env.PORT || 3000;

    var server = app.listen(port, function () {
        console.log('Server running at http://127.0.0.1:' + port + '/');
    });
```

The default NGINX configuration forwards traffic to an upstream server that's named `nodejs` at `127.0.0.1:8081`. It's possible to remove the default configuration and provide your own in a [configuration file](ebextensions.md).

**Example .ebextensions/proxy.config**  
The following example removes the default configuration and adds a custom configuration that forwards traffic to port 5000, instead of 8081.  

```
files:
  /etc/nginx/conf.d/proxy.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      upstream nodejs {
        server 127.0.0.1:5000;
        keepalive 256;
      }

      server {
        listen 8080;

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
        }
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
        access_log  /var/log/nginx/access.log  main;

        location / {
            proxy_pass  http://nodejs;
            proxy_set_header   Connection "";
            proxy_http_version 1.1;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location /static {
            alias /var/app/current/static;
        }

      }

  /opt/elasticbeanstalk/hooks/configdeploy/post/99_kill_default_nginx.sh:
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash -xe
      rm -f /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
      service nginx stop 
      service nginx start

container_commands:
  removeconfig:
    command: "rm -f /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf"
```
The example configuration (`/etc/nginx/conf.d/proxy.conf`) uses the default configuration at `/etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf` as a base to include the default server block with compression and log settings, and a static file mapping.  
The `removeconfig` command removes the default configuration for the container so that the proxy server uses the custom configuration. Elastic Beanstalk recreates the default configuration when each configuration is deployed. To account for this, in the following example, a post-configuration-deployment hook (`/opt/elasticbeanstalk/hooks/configdeploy/post/99_kill_default_nginx.sh`) is added. This removes the default configuration and restarts the proxy server.

**Note**  
The default configuration might change in future versions of the Node.js platform. Use the latest version of the configuration as a base for your customizations to ensure compatibility.

If you override the default configuration, you must define any static file mappings and GZIP compression. This is because the platform can't apply the [standard settings](create_deploy_nodejs.container.md#nodejs-namespaces).

# More Elastic Beanstalk example applications and tutorials for Node.js
<a name="nodejs-getstarted"></a>

This section provides additional applications and tutorials. The [QuickStart for Node.js](nodejs-quickstart.md) topic located previously in this topic walks you through launching the sample Node.js application with the EB CLI.

 To get started with Node.js applications on AWS Elastic Beanstalk, all you need is an application [source bundle](applications-sourcebundle.md) to upload as your first application version and to deploy to an environment. 

## Launching an environment with a sample Node.js application
<a name="nodejs-getstarted-samples"></a>

Elastic Beanstalk provides single page sample applications for each platform as well as more complex examples that show the use of additional AWS resources such as Amazon RDS and language or platform-specific features and APIs.

**Note**  
Follow the steps in the source bundle `README.md` file to deploy it. 


**Samples**  

|  Environment type  |  Source bundle  |  Description  | 
| --- | --- | --- | 
|  Web Server  |   [nodejs.zip](samples/nodejs.zip)   |  Single page application. To launch the sample application with the EB CLI, see [QuickStart for Node.js](nodejs-quickstart.md). You can also use the Elastic Beanstalk console to launch the sample application. For detailed steps, see [Create an example application](GettingStarted.md#GettingStarted.CreateApp) in the *Getting started* chapter of this guide.  | 
|  Web Server with Amazon RDS  |  [nodejs-example-express-rds.zip](samples/nodejs-example-express-rds.zip)  |  Hiking log application that uses the Express framework and an Amazon Relational Database Service (RDS). [Tutorial](create_deploy_nodejs_express.md)  | 
|  Web Server with Amazon ElastiCache  |  [nodejs-example-express-elasticache.zip](samples/nodejs-example-express-elasticache.zip)  |  Express web application that uses Amazon ElastiCache for clustering. Clustering enhances your web application's high availability, performance, and security. [Tutorial](nodejs-express-clustering.md)  | 
|  Web Server with DynamoDB, Amazon SNS and Amazon SQS  |  [nodejs-example-dynamo.zip](samples/nodejs-example-dynamo.zip)  |  Express web site that collects user contact information for a new company's marketing campaign. Uses the AWS SDK for JavaScript in Node.js to write entries to a DynamoDB table, and Elastic Beanstalk configuration files to create resources in DynamoDB, Amazon SNS and Amazon SQS. [Tutorial](nodejs-dynamodb-tutorial.md)  | 

## Next steps
<a name="nodejs-getstarted-next"></a>

After you have an environment running an application, you can deploy a new version of the application or a completely different application at any time. Deploying a new application version is very quick because it doesn't require provisioning or restarting EC2 instances. For details about application deployment, see [Deploy a New Version of Your Application](GettingStarted.md#GettingStarted.DeployApp).

After you've deployed a sample application or two and are ready to start developing and running Node.js applications locally, see [Setting up your Node.js development environment for Elastic Beanstalk](nodejs-devenv.md) to set up a Node.js development environment with all of the tools that you will need.

# Deploying a Node.js Express application to Elastic Beanstalk
<a name="create_deploy_nodejs_express"></a>

This section walks you through deploying a sample application to Elastic Beanstalk using the Elastic Beanstalk Command Line Interface (EB CLI) and then updating the application to use the [Express](http://expressjs.com/) framework. 

## Prerequisites
<a name="create_deploy_nodejs_express.prerequisites"></a>

This tutorial requires the following prerequisites:
+ The Node.js runtimes
+ The default Node.js package manager software, npm
+ The Express command line generator
+ The Elastic Beanstalk Command Line Interface (EB CLI)

For details about installing the first three listed components and setting up your local development environment, see [Setting up your Node.js development environment for Elastic Beanstalk](nodejs-devenv.md). For this tutorial, you don't need to install the AWS SDK for Node.js, which is also mentioned in the referenced topic.

For details about installing and configuring the EB CLI, see [Install EB CLI with setup script (recommended)](eb-cli3.md#eb-cli3-install) and [Configure the EB CLI](eb-cli3-configuration.md).

## Create an Elastic Beanstalk environment
<a name="create_deploy_nodejs_express.eb_init-rds"></a>

**Your application directory**  
This tutorial uses a directory called `nodejs-example-express-rds` for the application source bundle. Create the `nodejs-example-express-rds` directory for this tutorial.

```
~$ mkdir nodejs-example-express-rds
```

**Note**  
Each tutorial in this chapter uses it's own directory for the application source bundle. The directory name matches the name of the sample application used by the tutorial.

Change your current working directory to `nodejs-example-express-rds`.

```
~$ cd nodejs-example-express-rds
```

Now, let's set up an Elastic Beanstalk environment running the Node.js platform and the sample application. We'll use the Elastic Beanstalk command line interface (EB CLI).

**To configure an EB CLI repository for your application and create an Elastic Beanstalk environment running the Node.js platform**

1. Create a repository with the **[**eb init**](eb3-init.md)** command.

   ```
   ~/nodejs-example-express-rds$ eb init --platform node.js --region <region>
   ```

   This command creates a configuration file in a folder named `.elasticbeanstalk` that specifies settings for creating environments for your application, and creates an Elastic Beanstalk application named after the current folder.

1. Create an environment running a sample application with the **[**eb create**](eb3-create.md)** command.

   ```
   ~/nodejs-example-express-rds$ eb create --sample nodejs-example-express-rds
   ```

   This command creates a load-balanced environment with the default settings for the Node.js platform and the following resources:
   + **EC2 instance** – An Amazon Elastic Compute Cloud (Amazon EC2) virtual machine configured to run web apps on the platform that you choose.

     Each platform runs a specific set of software, configuration files, and scripts to support a specific language version, framework, web container, or combination of these. Most platforms use either Apache or NGINX as a reverse proxy that sits in front of your web app, forwards requests to it, serves static assets, and generates access and error logs.
   + **Instance security group** – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the load balancer reach the EC2 instance running your web app. By default, traffic isn't allowed on other ports.
   + **Load balancer** – An Elastic Load Balancing load balancer configured to distribute requests to the instances running your application. A load balancer also eliminates the need to expose your instances directly to the internet.
   + **Load balancer security group** – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the internet reach the load balancer. By default, traffic isn't allowed on other ports.
   + **Auto Scaling group** – An Auto Scaling group configured to replace an instance if it is terminated or becomes unavailable.
   + **Amazon S3 bucket** – A storage location for your source code, logs, and other artifacts that are created when you use Elastic Beanstalk.
   + **Amazon CloudWatch alarms** – Two CloudWatch alarms that monitor the load on the instances in your environment and that are triggered if the load is too high or too low. When an alarm is triggered, your Auto Scaling group scales up or down in response.
   + **CloudFormation stack** – Elastic Beanstalk uses CloudFormation to launch the resources in your environment and propagate configuration changes. The resources are defined in a template that you can view in the [CloudFormation console](https://console.aws.amazon.com/cloudformation).
   + **Domain name** – A domain name that routes to your web app in the form **subdomain*.*region*.elasticbeanstalk.com*.
**Domain security**  
To augment the security of your Elastic Beanstalk applications, the *elasticbeanstalk.com* domain is registered in the [Public Suffix List (PSL)](https://publicsuffix.org/).  
If you ever need to set sensitive cookies in the default domain name for your Elastic Beanstalk applications, we recommend that you use cookies with a `__Host-` prefix for increased security. This practice defends your domain against cross-site request forgery attempts (CSRF). For more information see the [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) page in the Mozilla Developer Network.

1. When environment creation completes, use the [**eb open**](eb3-open.md) command to open the environment's URL in the default browser.

   ```
   ~/nodejs-example-express-rds$ eb open
   ```

You have now created a Node.js Elastic Beanstalk environment with a sample application. You can update it with your own application. Next, we update the sample application to use the Express framework.

## Update the application to use Express
<a name="create_deploy_nodejs_express.update"></a>

After you've created an environment with a sample application, you can update it with your own application. In this procedure, we first run the **express** and **npm install** commands to set up the Express framework in your application directory. Then we use the EB CLI to update your Elastic Beanstalk environment with the updated application.

**To update your application to use Express**

1. Run the `express` command. This generates `package.json`, `app.js`, and a few directories.

   ```
   ~/nodejs-example-express-rds$ express
   ```

   When prompted, type **y** if you want to continue.
**Note**  
If the **express** command doesn't work, you may not have installed the Express command line generator as described in the earlier *Prerequisites* section. Or the directory path setting for your local machine may need to be set up to run the **express** command. See the *Prerequisites* section for detailed steps about setting up your development environment, so you can proceed with this tutorial. 

1. Set up local dependencies.

   ```
   ~/nodejs-example-express-rds$ npm install
   ```

1. (Optional) Verify the web app server starts up.

   ```
   ~/nodejs-example-express-rds$ npm start
   ```

   You should see output similar to the following:

   ```
   > nodejs@0.0.0 start /home/local/user/node-express
   > node ./bin/www
   ```

   The server runs on port 3000 by default. To test it, run `curl http://localhost:3000` in another terminal, or open a browser on the local computer and enter URL address `http://localhost:3000`.

   Press **Ctrl\$1C** to stop the server.

1. Deploy the changes to your Elastic Beanstalk environment with the [**eb deploy**](eb3-deploy.md) command.

   ```
   ~/nodejs-example-express-rds$ eb deploy
   ```

1. 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 serve static files and add a new page.

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

1. Add a second configuration file in the [`.ebextensions`](ebextensions.md) folder with the following content:

   **`nodejs-example-express-rds/.ebextensions/staticfiles.config`**

   ```
   option_settings:
       aws:elasticbeanstalk:environment:proxy:staticfiles:
           /stylesheets: public/stylesheets
   ```

   This setting configures the proxy server to serve files in the `public` folder at the `/public` path of the application. Serving files statically from the proxy server reduces the load on your application. For more information, see [Static files](create_deploy_nodejs.container.md#nodejs-platform-console-staticfiles) earlier in this chapter.

1. (Optional) To confirm that static mappings are configured correctly, comment out the static mapping configuration in `nodejs-example-express-rds/app.js`. This removes the mapping from the node application.

   ```
   //  app.use(express.static(path.join(__dirname, 'public'))); 
   ```

   The static file mappings in the `staticfiles.config` file from the previous step should still load the stylesheet successfully, even after you comment this line out. To verify that the static file mappings are loaded through the proxy static file configuration, rather than the express application, remove the values following `option_settings:`. After it has been removed from both the static file configuration and the node application, the stylesheet will fail to load.

   Remember to reset the contents of both the `nodejs-example-express-rds/app.js` and `staticfiles.config` when you're done testing.

1. Add `nodejs-example-express-rds/routes/hike.js`. Type the following:

   ```
   exports.index = function(req, res) {
    res.render('hike', {title: 'My Hiking Log'});
   };
   
   exports.add_hike = function(req, res) {
   };
   ```

1. Update `nodejs-example-express-rds/app.js` to include three new lines.

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

   ```
   var hike = require('./routes/hike');
   ```

   Your file should look similar to the following snippet:

   ```
   var express = require('express');
   var path = require('path');
   var hike = require('./routes/hike');
   ```

   Then, add the following two lines to `nodejs-example-express-rds/app.js` after `var app = express();`

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

   Your file should look similar to the following snippet:

   ```
   var app = express();
   app.get('/hikes', hike.index);
   app.post('/add_hike', hike.add_hike);
   ```

1. Copy `nodejs-example-express-rds/views/index.jade` to `nodejs-example-express-rds/views/hike.jade`. 

   ```
   ~/nodejs-example-express-rds$ cp views/index.jade views/hike.jade
   ```

1. Deploy the changes with the [**eb deploy**](eb3-deploy.md) command.

   ```
   ~/nodejs-example-express-rds$ eb deploy
   ```

1. 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**.

You have now created a web application that uses the Express framework. In the next section, we'll modify the application to use an Amazon Relational Database Service (RDS) to store a hiking log.

## Update the application to use Amazon RDS
<a name="create_deploy_nodejs_express.add_rds"></a>

In this next step we update the application to use Amazon RDS for MySQL.

**To update your application to use RDS for MySQL**

1. To create an RDS for MySQL database coupled to your Elastic Beanstalk environment, follow the instructions in the [Adding a database](create-deploy-nodejs.rds.md) topic included later in this chapter. Adding a database instance takes about 10 minutes.

1.  Update the dependencies section in the `package.json` with the following contents: 

   ```
   "dependencies": {
       "async": "^3.2.4",
       "express": "4.18.2",
       "jade": "1.11.0",
       "mysql": "2.18.1",
       "node-uuid": "^1.4.8",
       "body-parser": "^1.20.1",
       "method-override": "^3.0.0",
       "morgan": "^1.10.0",
       "errorhandler": "^1.5.1"
     }
   ```

1. Run **npm install**.

   ```
   ~/nodejs-example-express-rds$ npm install
   ```

1. Update `app.js` to connect to the database, create a table, and insert a single default hiking log. Every time this app is deployed it will drop the previous hikes table and recreate it.

   ```
   /**
    * Module dependencies.
    */
   
    const express = require('express')
    , routes = require('./routes')
    , hike = require('./routes/hike')
    , http = require('http')
    , path = require('path')
    , mysql = require('mysql')
    , async = require('async')
    , bodyParser = require('body-parser')
    , methodOverride = require('method-override')
    , morgan = require('morgan')
    , errorhandler = require('errorhandler');
   
   const { connect } = require('http2');
   
   const app = express()
   
   app.set('views', __dirname + '/views')
   app.set('view engine', 'jade')
   app.use(methodOverride())
   app.use(bodyParser.json())
   app.use(bodyParser.urlencoded({ extended: true }))
   app.use(express.static(path.join(__dirname, 'public')))
   
   
   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('/hikes', hike.index);
    app.post('/add_hike', hike.add_hike);
   }
   
   const client = app.get('connection');
   async.series([
    function connect(callback) {
      client.connect(callback);
      console.log('Connected!');
    },
    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) {
      const hike = {HIKE_DATE: new Date(), NAME: 'Hazard Stevens',
            LOCATION: 'Mt Rainier', DISTANCE: '4,027m vertical', WEATHER:'Bad', ID: '12345'};
      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();
    }
   });
   
   module.exports = app
   ```

1. Add the following content to `routes/hike.js`. This will enable the routes to insert new hiking logs into the *HIKES* database.

   ```
   const 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){
     const input = req.body.hike;
     const 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');
         }
      });
   };
   ```

1. Replace the content of `routes/index.js` with the following:

   ```
   /*
    * GET home page.
    */
   
   exports.index = function(req, res){
     res.render('index', { title: 'Express' });
   };
   ```

1. Add the following jade template to `views/hike.jade` to provide the user interface for adding hiking logs.

   ```
   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}
   ```

1. Deploy the changes with the [**eb deploy**](eb3-deploy.md) command.

   ```
   ~/nodejs-example-express-rds$ eb deploy
   ```

## Clean up
<a name="create_deploy_nodejs_express.delete"></a>

If you're done working with Elastic Beanstalk, you can terminate your environment.

Use the **eb terminate** command to terminate your environment and all of the resources that it contains.

```
~/nodejs-example-express-rds$ eb terminate
The environment "nodejs-example-express-rds-env" and all associated instances will be terminated.
To confirm, type the environment name: nodejs-example-express-rds-env
INFO: terminateEnvironment is starting.
...
```

# Deploying a Node.js Express application with clustering to Elastic Beanstalk
<a name="nodejs-express-clustering"></a>

This tutorial walks you through deploying a sample application to Elastic Beanstalk using the Elastic Beanstalk Command Line Interface (EB CLI), and then updating the application to use the [Express](http://expressjs.com/) framework, [Amazon ElastiCache](https://aws.amazon.com/elasticache/), and clustering. Clustering enhances your web application's high availability, performance, and security. To learn more about Amazon ElastiCache, go to [What Is Amazon ElastiCache (Memcached)?](https://docs.aws.amazon.com/AmazonElastiCache/latest/mem-ug/Introduction.html) in the *Amazon ElastiCache (Memcached) User Guide*.

**Note**  
This example creates AWS resources, which you might be charged for. For more information about AWS pricing, see [https://aws.amazon.com/pricing/](https://aws.amazon.com/pricing/). Some services are part of the AWS Free Usage Tier. If you are a new customer, you can test drive these services for free. See [https://aws.amazon.com/free/](https://aws.amazon.com/free/) for more information.

## Prerequisites
<a name="nodejs-express-clustering.prereq"></a>

This tutorial requires the following prerequisites:
+ The Node.js runtimes
+ The default Node.js package manager software, npm
+ The Express command line generator
+ The Elastic Beanstalk Command Line Interface (EB CLI)

For details about installing the first three listed components and setting up your local development environment, see [Setting up your Node.js development environment for Elastic Beanstalk](nodejs-devenv.md). For this tutorial, you don't need to install the AWS SDK for Node.js, which is also mentioned in the referenced topic.

For details about installing and configuring the EB CLI, see [Install EB CLI with setup script (recommended)](eb-cli3.md#eb-cli3-install) and [Configure the EB CLI](eb-cli3-configuration.md).

## Create an Elastic Beanstalk environment
<a name="nodejs-express-clustering.create"></a>

**Your application directory**  
This tutorial uses a directory called `nodejs-example-express-elasticache` for the application source bundle. Create the `nodejs-example-express-elasticache` directory for this tutorial.

```
~$ mkdir nodejs-example-express-elasticache
```

**Note**  
Each tutorial in this chapter uses it's own directory for the application source bundle. The directory name matches the name of the sample application used by the tutorial.

Change your current working directory to `nodejs-example-express-elasticache`.

```
~$ cd nodejs-example-express-elasticache
```

Now, let's set up an Elastic Beanstalk environment running the Node.js platform and the sample application. We'll use the Elastic Beanstalk command line interface (EB CLI).

**To configure an EB CLI repository for your application and create an Elastic Beanstalk environment running the Node.js platform**

1. Create a repository with the **[**eb init**](eb3-init.md)** command.

   ```
   ~/nodejs-example-express-elasticache$ eb init --platform node.js --region <region>
   ```

   This command creates a configuration file in a folder named `.elasticbeanstalk` that specifies settings for creating environments for your application, and creates an Elastic Beanstalk application named after the current folder.

1. Create an environment running a sample application with the **[**eb create**](eb3-create.md)** command.

   ```
   ~/nodejs-example-express-elasticache$ eb create --sample nodejs-example-express-elasticache
   ```

   This command creates a load-balanced environment with the default settings for the Node.js platform and the following resources:
   + **EC2 instance** – An Amazon Elastic Compute Cloud (Amazon EC2) virtual machine configured to run web apps on the platform that you choose.

     Each platform runs a specific set of software, configuration files, and scripts to support a specific language version, framework, web container, or combination of these. Most platforms use either Apache or NGINX as a reverse proxy that sits in front of your web app, forwards requests to it, serves static assets, and generates access and error logs.
   + **Instance security group** – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the load balancer reach the EC2 instance running your web app. By default, traffic isn't allowed on other ports.
   + **Load balancer** – An Elastic Load Balancing load balancer configured to distribute requests to the instances running your application. A load balancer also eliminates the need to expose your instances directly to the internet.
   + **Load balancer security group** – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the internet reach the load balancer. By default, traffic isn't allowed on other ports.
   + **Auto Scaling group** – An Auto Scaling group configured to replace an instance if it is terminated or becomes unavailable.
   + **Amazon S3 bucket** – A storage location for your source code, logs, and other artifacts that are created when you use Elastic Beanstalk.
   + **Amazon CloudWatch alarms** – Two CloudWatch alarms that monitor the load on the instances in your environment and that are triggered if the load is too high or too low. When an alarm is triggered, your Auto Scaling group scales up or down in response.
   + **CloudFormation stack** – Elastic Beanstalk uses CloudFormation to launch the resources in your environment and propagate configuration changes. The resources are defined in a template that you can view in the [CloudFormation console](https://console.aws.amazon.com/cloudformation).
   + **Domain name** – A domain name that routes to your web app in the form **subdomain*.*region*.elasticbeanstalk.com*.
**Domain security**  
To augment the security of your Elastic Beanstalk applications, the *elasticbeanstalk.com* domain is registered in the [Public Suffix List (PSL)](https://publicsuffix.org/).  
If you ever need to set sensitive cookies in the default domain name for your Elastic Beanstalk applications, we recommend that you use cookies with a `__Host-` prefix for increased security. This practice defends your domain against cross-site request forgery attempts (CSRF). For more information see the [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) page in the Mozilla Developer Network.

1. When environment creation completes, use the [**eb open**](eb3-open.md) command to open the environment's URL in the default browser.

   ```
   ~/nodejs-example-express-elasticache$ eb open
   ```

You have now created a Node.js Elastic Beanstalk environment with a sample application. You can update it with your own application. Next, we update the sample application to use the Express framework.

## Update the application to use Express
<a name="nodejs-express-clustering.update"></a>

Update the sample application in the Elastic Beanstalk environment to use the Express framework.

You can download the final source code from [nodejs-example-express-elasticache.zip](samples/nodejs-example-express-elasticache.zip).

**To update your application to use Express**

After you've created an environment with a sample application, you can update it with your own application. In this procedure, we first run the **express** and **npm install** commands to set up the Express framework in your application directory.

1. Run the `express` command. This generates `package.json`, `app.js`, and a few directories.

   ```
   ~/nodejs-example-express-elasticache$ express
   ```

   When prompted, type **y** if you want to continue.
**Note**  
If the **express** command doesn't work, you may not have installed the Express command line generator as described in the earlier *Prerequisites* section. Or the directory path setting for your local machine may need to be set up to run the **express** command. See the *Prerequisites* section for detailed steps about setting up your development environment, so you can proceed with this tutorial. 

1. Set up local dependencies.

   ```
   ~/nodejs-example-express-elasticache$ npm install
   ```

1. (Optional) Verify the web app server starts up.

   ```
   ~/nodejs-example-express-elasticache$ npm start
   ```

   You should see output similar to the following:

   ```
   > nodejs@0.0.0 start /home/local/user/node-express
   > node ./bin/www
   ```

   The server runs on port 3000 by default. To test it, run `curl http://localhost:3000` in another terminal, or open a browser on the local computer and enter URL address `http://localhost:3000`.

   Press **Ctrl\$1C** to stop the server.

1. Rename `nodejs-example-express-elasticache/app.js` to `nodejs-example-express-elasticache/express-app.js`.

   ```
   ~/nodejs-example-express-elasticache$ mv app.js express-app.js
   ```

1. Update the line `var app = express();` in `nodejs-example-express-elasticache/express-app.js` to the following:

   ```
   var app = module.exports = express();
   ```

1. On your local computer, create a file named `nodejs-example-express-elasticache/app.js` with the following code.

   ```
   /**
    * Module dependencies.
    */
   
    const express = require('express'),
    session = require('express-session'),
    bodyParser = require('body-parser'),
    methodOverride = require('method-override'),
    cookieParser = require('cookie-parser'),
    fs = require('fs'),
    filename = '/var/nodelist',
    app = express();
   
   let MemcachedStore = require('connect-memcached')(session);
   
   function setup(cacheNodes) {
    app.use(bodyParser.raw());
    app.use(methodOverride());
    if (cacheNodes.length > 0) {
      app.use(cookieParser());
   
      console.log('Using memcached store nodes:');
      console.log(cacheNodes);
   
      app.use(session({
        secret: 'your secret here',
        resave: false,
        saveUninitialized: false,
        store: new MemcachedStore({ 'hosts': cacheNodes })
      }));
    } else {
      console.log('Not using memcached store.');
      app.use(session({
        resave: false,
        saveUninitialized: false, secret: 'your secret here'
      }));
    }
   
    app.get('/', function (req, resp) {
      if (req.session.views) {
        req.session.views++
        resp.setHeader('Content-Type', 'text/html')
        resp.send(`You are session: ${req.session.id}. Views: ${req.session.views}`)
      } else {
        req.session.views = 1
        resp.send(`You are session: ${req.session.id}. No views yet, refresh the page!`)
      }
    });
   
    if (!module.parent) {
      console.log('Running express without cluster. Listening on port %d', process.env.PORT || 5000)
      app.listen(process.env.PORT || 5000)
    }
   }
   
   console.log("Reading elastic cache configuration")
   // Load elasticache configuration.
   fs.readFile(filename, 'UTF8', function (err, data) {
    if (err) throw err;
   
    let cacheNodes = []
    if (data) {
      let lines = data.split('\n');
      for (let i = 0; i < lines.length; i++) {
        if (lines[i].length > 0) {
          cacheNodes.push(lines[i])
        }
      }
    }
   
    setup(cacheNodes)
   });
   
   module.exports = app;
   ```

1. Replace the contents of the `nodejs-example-express-elasticache/bin/www` file with the following:

   ```
   #!/usr/bin/env node
   
   /**
    * Module dependencies.
    */
   
   const app = require('../app');
   const cluster = require('cluster');
   const debug = require('debug')('nodejs-example-express-elasticache:server');
   const http = require('http');
   const workers = {},
     count = require('os').cpus().length;
   
   function spawn() {
     const worker = cluster.fork();
     workers[worker.pid] = worker;
     return worker;
   }
   
   
   /**
    * Get port from environment and store in Express.
    */
   
   const port = normalizePort(process.env.PORT || '3000');
   app.set('port', port);
   
   if (cluster.isMaster) {
     for (let i = 0; i < count; i++) {
       spawn();
     }
   
     // If a worker dies, log it to the console and start another worker.
     cluster.on('exit', function (worker, code, signal) {
       console.log('Worker ' + worker.process.pid + ' died.');
       cluster.fork();
     });
   
     // Log when a worker starts listening
     cluster.on('listening', function (worker, address) {
       console.log('Worker started with PID ' + worker.process.pid + '.');
     });
   
   } else {
     /**
      * Create HTTP server.
      */
   
     let server = http.createServer(app);
   
     /**
      * Event listener for HTTP server "error" event.
      */
   
     function onError(error) {
       if (error.syscall !== 'listen') {
         throw error;
       }
   
       const bind = typeof port === 'string'
         ? 'Pipe ' + port
         : 'Port ' + port;
   
       // handle specific listen errors with friendly messages
       switch (error.code) {
         case 'EACCES':
           console.error(bind + ' requires elevated privileges');
           process.exit(1);
           break;
         case 'EADDRINUSE':
           console.error(bind + ' is already in use');
           process.exit(1);
           break;
         default:
           throw error;
       }
     }
   
     /**
      * Event listener for HTTP server "listening" event.
      */
   
     function onListening() {
       const addr = server.address();
       const bind = typeof addr === 'string'
         ? 'pipe ' + addr
         : 'port ' + addr.port;
       debug('Listening on ' + bind);
     }
   
     /**
      * Listen on provided port, on all network interfaces.
      */
   
     server.listen(port);
     server.on('error', onError);
     server.on('listening', onListening);
   }
   
   /**
    * Normalize a port into a number, string, or false.
    */
   
   function normalizePort(val) {
     const port = parseInt(val, 10);
   
     if (isNaN(port)) {
       // named pipe
       return val;
     }
   
     if (port >= 0) {
       // port number
       return port;
     }
   
     return false;
   }
   ```

1. Deploy the changes to your Elastic Beanstalk environment with the [**eb deploy**](eb3-deploy.md) command.

   ```
   ~/nodejs-example-express-elasticache$ eb deploy
   ```

1. Your environment will be updated after a few minutes. 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".

You can access the logs for your EC2 instances running your application. For instructions on accessing your logs, see [Viewing logs from Amazon EC2 instances in your Elastic Beanstalk environment](using-features.logging.md).

Next, let's update the Express application to use Amazon ElastiCache.

**To update your Express application to use Amazon ElastiCache**

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

1. Create a configuration file `nodejs-example-express-elasticache/.ebextensions/elasticache-iam-with-script.config` with the following snippet. For more information about the configuration file, see [Node.js configuration namespace](create_deploy_nodejs.container.md#nodejs-namespaces). This creates an IAM user with the permissions required to discover the elasticache nodes and writes to a file anytime the cache changes. You can also copy the file from [nodejs-example-express-elasticache.zip](samples/nodejs-example-express-elasticache.zip). For more information on the ElastiCache properties, see [Example: ElastiCache](customize-environment-resources-elasticache.md).
**Note**  
YAML relies on consistent indentation. Match the indentation level when replacing content in an example configuration file and ensure that your text editor uses spaces, not tab characters, to indent.

   ```
   Resources:
     MyCacheSecurityGroup:
       Type: 'AWS::EC2::SecurityGroup'
       Properties:
         GroupDescription: "Lock cache down to webserver access only"
         SecurityGroupIngress:
           - IpProtocol: tcp
             FromPort:
               Fn::GetOptionSetting:
                 OptionName: CachePort
                 DefaultValue: 11211
             ToPort:
               Fn::GetOptionSetting:
                 OptionName: CachePort
                 DefaultValue: 11211
             SourceSecurityGroupName:
               Ref: AWSEBSecurityGroup
     MyElastiCache:
       Type: 'AWS::ElastiCache::CacheCluster'
       Properties:
         CacheNodeType:
           Fn::GetOptionSetting:
             OptionName: CacheNodeType
             DefaultValue: cache.t2.micro
         NumCacheNodes:
           Fn::GetOptionSetting:
             OptionName: NumCacheNodes
             DefaultValue: 1
         Engine:
           Fn::GetOptionSetting:
             OptionName: Engine
             DefaultValue: redis
         VpcSecurityGroupIds:
           -
             Fn::GetAtt:
               - MyCacheSecurityGroup
               - GroupId
     AWSEBAutoScalingGroup :
       Metadata :
         ElastiCacheConfig :
           CacheName :
             Ref : MyElastiCache
           CacheSize :
              Fn::GetOptionSetting:
                OptionName : NumCacheNodes
                DefaultValue: 1
     WebServerUser : 
       Type : AWS::IAM::User
       Properties :
         Path : "/"
         Policies:
           -
             PolicyName: root
             PolicyDocument :
               Statement :
                 -
                   Effect : Allow
                   Action : 
                     - cloudformation:DescribeStackResource
                     - cloudformation:ListStackResources
                     - elasticache:DescribeCacheClusters
                   Resource : "*"
     WebServerKeys :
       Type : AWS::IAM::AccessKey
       Properties :
         UserName :
           Ref: WebServerUser
   
   Outputs:
     WebsiteURL:
       Description: sample output only here to show inline string function parsing
       Value: |
         http://`{ "Fn::GetAtt" : [ "AWSEBLoadBalancer", "DNSName" ] }`
     MyElastiCacheName:
       Description: Name of the elasticache
       Value:
         Ref : MyElastiCache
     NumCacheNodes:
       Description: Number of cache nodes in MyElastiCache
       Value:
         Fn::GetOptionSetting:
           OptionName : NumCacheNodes
           DefaultValue: 1
   
   files:
     "/etc/cfn/cfn-credentials" :
       content : |
         AWSAccessKeyId=`{ "Ref" : "WebServerKeys" }`
         AWSSecretKey=`{ "Fn::GetAtt" : ["WebServerKeys", "SecretAccessKey"] }`
       mode : "000400"
       owner : root
       group : root
   
     "/etc/cfn/get-cache-nodes" :
       content : |
         # Define environment variables for command line tools
         export AWS_ELASTICACHE_HOME="/home/ec2-user/elasticache/$(ls /home/ec2-user/elasticache/)"
         export AWS_CLOUDFORMATION_HOME=/opt/aws/apitools/cfn
         export PATH=$AWS_CLOUDFORMATION_HOME/bin:$AWS_ELASTICACHE_HOME/bin:$PATH
         export AWS_CREDENTIAL_FILE=/etc/cfn/cfn-credentials
         export JAVA_HOME=/usr/lib/jvm/jre
   
         # Grab the Cache node names and configure the PHP page
         aws cloudformation list-stack-resources --stack `{ "Ref" : "AWS::StackName" }` --region `{ "Ref" : "AWS::Region" }` --output text | grep MyElastiCache | awk '{print $4}' | xargs -I {} aws elasticache describe-cache-clusters --cache-cluster-id {} --region `{ "Ref" : "AWS::Region" }` --show-cache-node-info --output text | grep '^ENDPOINT' | awk '{print $2 ":" $3}' > `{ "Fn::GetOptionSetting" : { "OptionName" : "NodeListPath", "DefaultValue" : "/var/www/html/nodelist" } }`
       mode : "000500"
       owner : root
       group : root
   
     "/etc/cfn/hooks.d/cfn-cache-change.conf" :
       "content": |
         [cfn-cache-size-change]
         triggers=post.update
         path=Resources.AWSEBAutoScalingGroup.Metadata.ElastiCacheConfig
         action=/etc/cfn/get-cache-nodes
         runas=root
   
   sources :
     "/home/ec2-user/elasticache" : "https://elasticache-downloads.s3.amazonaws.com/AmazonElastiCacheCli-latest.zip"
   
   commands: 
     make-elasticache-executable:
       command: chmod -R ugo+x /home/ec2-user/elasticache/*/bin/*
   
   packages : 
     "yum" :
       "aws-apitools-cfn"  : []
   
   container_commands:
     initial_cache_nodes:
       command: /etc/cfn/get-cache-nodes
   ```

1. On your local computer, create a configuration file `nodejs-example-express-elasticache/.ebextensions/elasticache_settings.config` with the following snippet to configure ElastiCache.

   ```
   option_settings:
     "aws:elasticbeanstalk:customoption":
        CacheNodeType: cache.t2.micro
        NumCacheNodes: 1
        Engine: memcached
        NodeListPath: /var/nodelist
   ```

1. On your local computer, replace `nodejs-example-express-elasticache/express-app.js` with the following snippet. This file reads the nodes list from disk (`/var/nodelist`) and configures express to use `memcached` as a session store if nodes are present. Your file should look like the following.

   ```
   /**
    * Module dependencies.
    */
   
   var express = require('express'),
       session = require('express-session'),
       bodyParser = require('body-parser'),
       methodOverride = require('method-override'),
       cookieParser = require('cookie-parser'),
       fs = require('fs'),
       filename = '/var/nodelist',
       app = module.exports = express();
   
   var MemcachedStore = require('connect-memcached')(session);
   
   function setup(cacheNodes) {
     app.use(bodyParser.raw());
     app.use(methodOverride());
     if (cacheNodes) {
         app.use(cookieParser());
   
         console.log('Using memcached store nodes:');
         console.log(cacheNodes);
   
         app.use(session({
             secret: 'your secret here',
             resave: false,
             saveUninitialized: false,
             store: new MemcachedStore({'hosts': cacheNodes})
         }));
     } else {
       console.log('Not using memcached store.');
       app.use(cookieParser('your secret here'));
       app.use(session());
     }
   
     app.get('/', function(req, resp){
     if (req.session.views) {
         req.session.views++
         resp.setHeader('Content-Type', 'text/html')
         resp.write('Views: ' + req.session.views)
         resp.end()
      } else {
         req.session.views = 1
         resp.end('Refresh the page!')
       }
     });
   
     if (!module.parent) {
         console.log('Running express without cluster.');
         app.listen(process.env.PORT || 5000);
     }
   }
   
   // Load elasticache configuration.
   fs.readFile(filename, 'UTF8', function(err, data) {
       if (err) throw err;
   
       var cacheNodes = [];
       if (data) {
           var lines = data.split('\n');
           for (var i = 0 ; i < lines.length ; i++) {
               if (lines[i].length > 0) {
                   cacheNodes.push(lines[i]);
               }
           }
       }
       setup(cacheNodes);
   });
   ```

1. On your local computer, update `package.json` with the following contents:

   ```
     "dependencies": {
       "cookie-parser": "~1.4.4",
       "debug": "~2.6.9",
       "express": "~4.16.1",
       "http-errors": "~1.6.3",
       "jade": "~1.11.0",
       "morgan": "~1.9.1",
       "connect-memcached": "*",
       "express-session": "*",
       "body-parser": "*",
       "method-override": "*"   
     }
   ```

1. Run **npm install**.

   ```
   ~/nodejs-example-express-elasticache$ npm install
   ```

1. Deploy the updated application.

   ```
   ~/nodejs-example-express-elasticache$ eb deploy
   ```

1. Your environment will be updated after a few minutes. After your environment is green and ready, verify that the code worked.

   1. Check the [Amazon CloudWatch console](https://console.aws.amazon.com/cloudwatch/home) to view your ElastiCache metrics. To view your ElastiCache metrics, select **Metrics** in the left pane, and then search for **CurrItems**. Select **ElastiCache > Cache Node Metrics**, and then select your cache node to view the number of items in the cache.  
![\[CloudWatch dashboard showing CurrItems metric for an ElastiCache node over time.\]](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/images/elasticache-express.png)
**Note**  
Make sure you are looking at the same region that you deployed your application to.

      If you copy and paste your application URL into another web browser and refresh the page, you should see your CurrItem count go up after 5 minutes.

   1. Take a snapshot of your logs. For more information about retrieving logs, see [Viewing logs from Amazon EC2 instances in your Elastic Beanstalk environment](using-features.logging.md).

   1. Check the file `/var/log/nodejs/nodejs.log` in the log bundle. You should see something similar to the following:

      ```
      Using memcached store nodes:
      [ 'aws-my-1oys9co8zt1uo.1iwtrn.0001.use1.cache.amazonaws.com:11211' ]
      ```

## Clean up
<a name="nodejs-express-clustering.delete"></a>

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

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

**To terminate your environment**

From the directory where you created your local repository, run `eb terminate`.

```
$ eb terminate
```

This process can take a few minutes. Elastic Beanstalk displays a message once the environment is successfully terminated. 

# Deploying a Node.js application with DynamoDB to Elastic Beanstalk
<a name="nodejs-dynamodb-tutorial"></a>

This tutorial and its example application [nodejs-example-dynamo.zip](samples/nodejs-example-dynamo.zip) walks you through the process of deploying a Node.js application that uses the AWS SDK for JavaScript in Node.js to interact with the Amazon DynamoDB service. You'll create a DynamoDB table that's in a database that's decoupled, or external, from the AWS Elastic Beanstalk environment. You'll also configure the application to use a decoupled database. In a production environment, it's best practice to use a database that's decoupled from the Elastic Beanstalk environment so that it's independent from the environment's life cycle. This practice also enables you to perform [blue/green deployments](using-features.CNAMESwap.md).

The example application illustrates the following:
+ A DynamoDB table that stores user-provided text data.
+ The [configuration files](ebextensions.md) to create the table.
+ An Amazon Simple Notification Service topic.
+  Use of a [package.json file](nodejs-platform-dependencies.md#nodejs-platform-packagejson) to install packages during deployment.

**Topics**
+ [Prerequisites](#nodejs-dynamodb-tutorial-prereqs)
+ [Create an Elastic Beanstalk environment](#nodejs-dynamodb-tutorial-launch)
+ [Add permissions to your environment's instances](#nodejs-dynamodb-tutorial-role)
+ [Deploy the example application](#nodejs-dynamodb-tutorial-deploy)
+ [Create a DynamoDB table](#nodejs-dynamodb-tutorial-database)
+ [Update the application's configuration files](#nodejs-dynamodb-tutorial-update)
+ [Configure your environment for high availability](#nodejs-dynamodb-tutorial-configure)
+ [Cleanup](#nodejs-dynamodb-tutorial-cleanup)
+ [Next steps](#nodejs-dynamodb-tutorial-nextsteps)

## Prerequisites
<a name="nodejs-dynamodb-tutorial-prereqs"></a>

This tutorial requires the following prerequisites:
+ The Node.js runtimes
+ The default Node.js package manager software, npm
+ The Express command line generator
+ The Elastic Beanstalk Command Line Interface (EB CLI)

For details about installing the first three listed components and setting up your local development environment, see [Setting up your Node.js development environment for Elastic Beanstalk](nodejs-devenv.md). For this tutorial, you don't need to install the AWS SDK for Node.js, which is also mentioned in the referenced topic.

For details about installing and configuring the EB CLI, see [Install EB CLI with setup script (recommended)](eb-cli3.md#eb-cli3-install) and [Configure the EB CLI](eb-cli3-configuration.md).

## Create an Elastic Beanstalk environment
<a name="nodejs-dynamodb-tutorial-launch"></a>

**Your application directory**  
This tutorial uses a directory called `nodejs-example-dynamo` for the application source bundle. Create the `nodejs-example-dynamo` directory for this tutorial.

```
~$ mkdir nodejs-example-dynamo
```

**Note**  
Each tutorial in this chapter uses it's own directory for the application source bundle. The directory name matches the name of the sample application used by the tutorial.

Change your current working directory to `nodejs-example-dynamo`.

```
~$ cd nodejs-example-dynamo
```

Now, let's set up an Elastic Beanstalk environment running the Node.js platform and the sample application. We'll use the Elastic Beanstalk command line interface (EB CLI).

**To configure an EB CLI repository for your application and create an Elastic Beanstalk environment running the Node.js platform**

1. Create a repository with the **[**eb init**](eb3-init.md)** command.

   ```
   ~/nodejs-example-dynamo$ eb init --platform node.js --region <region>
   ```

   This command creates a configuration file in a folder named `.elasticbeanstalk` that specifies settings for creating environments for your application, and creates an Elastic Beanstalk application named after the current folder.

1. Create an environment running a sample application with the **[**eb create**](eb3-create.md)** command.

   ```
   ~/nodejs-example-dynamo$ eb create --sample nodejs-example-dynamo
   ```

   This command creates a load-balanced environment with the default settings for the Node.js platform and the following resources:
   + **EC2 instance** – An Amazon Elastic Compute Cloud (Amazon EC2) virtual machine configured to run web apps on the platform that you choose.

     Each platform runs a specific set of software, configuration files, and scripts to support a specific language version, framework, web container, or combination of these. Most platforms use either Apache or NGINX as a reverse proxy that sits in front of your web app, forwards requests to it, serves static assets, and generates access and error logs.
   + **Instance security group** – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the load balancer reach the EC2 instance running your web app. By default, traffic isn't allowed on other ports.
   + **Load balancer** – An Elastic Load Balancing load balancer configured to distribute requests to the instances running your application. A load balancer also eliminates the need to expose your instances directly to the internet.
   + **Load balancer security group** – An Amazon EC2 security group configured to allow inbound traffic on port 80. This resource lets HTTP traffic from the internet reach the load balancer. By default, traffic isn't allowed on other ports.
   + **Auto Scaling group** – An Auto Scaling group configured to replace an instance if it is terminated or becomes unavailable.
   + **Amazon S3 bucket** – A storage location for your source code, logs, and other artifacts that are created when you use Elastic Beanstalk.
   + **Amazon CloudWatch alarms** – Two CloudWatch alarms that monitor the load on the instances in your environment and that are triggered if the load is too high or too low. When an alarm is triggered, your Auto Scaling group scales up or down in response.
   + **CloudFormation stack** – Elastic Beanstalk uses CloudFormation to launch the resources in your environment and propagate configuration changes. The resources are defined in a template that you can view in the [CloudFormation console](https://console.aws.amazon.com/cloudformation).
   + **Domain name** – A domain name that routes to your web app in the form **subdomain*.*region*.elasticbeanstalk.com*.
**Domain security**  
To augment the security of your Elastic Beanstalk applications, the *elasticbeanstalk.com* domain is registered in the [Public Suffix List (PSL)](https://publicsuffix.org/).  
If you ever need to set sensitive cookies in the default domain name for your Elastic Beanstalk applications, we recommend that you use cookies with a `__Host-` prefix for increased security. This practice defends your domain against cross-site request forgery attempts (CSRF). For more information see the [Set-Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) page in the Mozilla Developer Network.

1. When environment creation completes, use the [**eb open**](eb3-open.md) command to open the environment's URL in the default browser.

   ```
   ~/nodejs-example-dynamo$ eb open
   ```

You have now created a Node.js Elastic Beanstalk environment with a sample application. You can update it with your own application. Next, we update the sample application to use the Express framework.

## Add permissions to your environment's instances
<a name="nodejs-dynamodb-tutorial-role"></a>

Your application runs on one or more EC2 instances behind a load balancer, serving HTTP requests from the Internet. When it receives a request that requires it to use AWS services, the application uses the permissions of the instance it runs on to access those services.

The sample application uses instance permissions to write data to a DynamoDB table, and to send notifications to an Amazon SNS topic with the SDK for JavaScript in Node.js. Add the following managed policies to the default [instance profile](concepts-roles-instance.md) to grant the EC2 instances in your environment permission to access DynamoDB and Amazon SNS:
+ **AmazonDynamoDBFullAccess**
+ **AmazonSNSFullAccess**

**To add policies to the default instance profile**

1. Open the [Roles page](https://console.aws.amazon.com/iam/home#roles) in the IAM console.

1. Choose **aws-elasticbeanstalk-ec2-role**.

1. On the **Permissions** tab, choose **Attach policies**.

1. Select the managed policy for the additional services that your application uses. For this tutorial, select `AmazonSNSFullAccess` and `AmazonDynamoDBFullAccess`.

1. Choose **Attach policy**.

See [Managing Elastic Beanstalk instance profiles](iam-instanceprofile.md) for more on managing instance profiles.

## Deploy the example application
<a name="nodejs-dynamodb-tutorial-deploy"></a>

Now your environment is ready for you to deploy and run the example application for this tutorial: [nodejs-example-dynamo.zip](samples/nodejs-example-dynamo.zip) .

**To deploy and run the tutorial example application**

1. Change your current working directory to the application directory `nodejs-example-dynamo`.

   ```
   ~$ cd nodejs-example-dynamo
   ```

1. Download and extract the contents of the example application source bundle [nodejs-example-dynamo.zip](samples/nodejs-example-dynamo.zip) to the application directory `nodejs-example-dynamo`.

1. Deploy the example application to your Elastic Beanstalk environment with the [**eb deploy**](eb3-deploy.md) command.

   ```
   ~/nodejs-example-dynamo$ eb deploy
   ```
**Note**  
By default, the `eb deploy` command creates a ZIP file of your project folder. You can configure the EB CLI to deploy an artifact from your build process instead of creating a ZIP file of your project folder. For more information, see [Deploying an artifact instead of the project folder](eb-cli3-configuration.md#eb-cli3-artifact).

1. When environment creation completes, use the [**eb open**](eb3-open.md) command to open the environment's URL in the default browser.

   ```
   ~/nodejs-example-dynamo$ eb open
   ```

The site collects user contact information and uses a DynamoDB table to store the data. To add an entry, choose **Sign up today**, enter a name and email address, and then choose **Sign Up\$1**. The web app writes the form contents to the table and triggers an Amazon SNS email notification.

![\[Startup landing page with teaser message and sign-up button for upcoming product launch.\]](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/images/nodejs-dynamodb-tutorial-app.png)


Right now, the Amazon SNS topic is configured with a placeholder email for notifications. You will update the configuration soon, but in the meantime you can verify the DynamoDB table and Amazon SNS topic in the AWS Management Console.

**To view the table**

1. Open the [Tables page](https://console.aws.amazon.com/dynamodb/home?#tables:) in the DynamoDB console.

1. Find the table that the application created. The name starts with **awseb** and contains **StartupSignupsTable**.

1. Select the table, choose **Items**, and then choose **Start search** to view all items in the table.

The table contains an entry for every email address submitted on the signup site. In addition to writing to the table, the application sends a message to an Amazon SNS topic that has two subscriptions, one for email notifications to you, and another for an Amazon Simple Queue Service queue that a worker application can read from to process requests and send emails to interested customers.

**To view the topic**

1. Open the [Topics page](https://console.aws.amazon.com/sns/v2/home?#/topics) in the Amazon SNS console.

1. Find the topic that the application created. The name starts with **awseb** and contains **NewSignupTopic**.

1. Choose the topic to view its subscriptions.

The application (`[app.js](https://github.com/awslabs/eb-node-express-sample/blob/master/app.js)`) defines two routes. The root path (`/`) returns a webpage rendered from an Embedded JavaScript (EJS) template with a form that the user fills out to register their name and email address. Submitting the form sends a POST request with the form data to the `/signup` route, which writes an entry to the DynamoDB table and publishes a message to the Amazon SNS topic to notify the owner of the signup.

The sample application includes [configuration files](ebextensions.md) that create the DynamoDB table, Amazon SNS topic, and Amazon SQS queue used by the application. This lets you create a new environment and test the functionality immediately, but has the drawback of tying the DynamoDB table to the environment. For a production environment, you should create the DynamoDB table outside of your environment to avoid losing it when you terminate the environment or update its configuration.

## Create a DynamoDB table
<a name="nodejs-dynamodb-tutorial-database"></a>

To use an external DynamoDB table with an application running in Elastic Beanstalk, first create a table in DynamoDB. When you create a table outside of Elastic Beanstalk, it is completely independent of Elastic Beanstalk and your Elastic Beanstalk environments, and will not be terminated by Elastic Beanstalk.

Create a table with the following settings:
+ **Table name** – **nodejs-tutorial**
+ **Primary key** – **email**
+ Primary key type – **String**

**To create a DynamoDB table**

1. Open the [Tables page](https://console.aws.amazon.com/dynamodb/home?#tables:) in the DynamoDB management console.

1. Choose **Create table**.

1. Type a **Table name** and **Primary key**.

1. Choose the primary key type.

1. Choose **Create**.

## Update the application's configuration files
<a name="nodejs-dynamodb-tutorial-update"></a>

Update the [configuration files](ebextensions.md) in the application source to use the **nodejs-tutorial** table instead of creating a new one.

**To update the example application for production use**

1. Change your current working directory to the application directory `nodejs-example-dynamo`.

   ```
   ~$ cd nodejs-example-dynamo
   ```

1. Open `.ebextensions/options.config` and change the values of the following settings:
   + **NewSignupEmail** – Your email address.
   + **STARTUP\$1SIGNUP\$1TABLE** – **nodejs-tutorial**

     
**Example .ebextensions/options.config**  

   ```
   option_settings:
     aws:elasticbeanstalk:customoption:
       NewSignupEmail: you@example.com
     aws:elasticbeanstalk:application:environment:
       THEME: "flatly"
       AWS_REGION: '`{"Ref" : "AWS::Region"}`'
       STARTUP_SIGNUP_TABLE: nodejs-tutorial
       NEW_SIGNUP_TOPIC: '`{"Ref" : "NewSignupTopic"}`'
     aws:elasticbeanstalk:container:nodejs:
       ProxyServer: nginx
     aws:elasticbeanstalk:container:nodejs:staticfiles:
       /static: /static
     aws:autoscaling:asg:
       Cooldown: "120"
     aws:autoscaling:trigger:
       Unit: "Percent"
       Period: "1"
       BreachDuration: "2"
       UpperThreshold: "75"
       LowerThreshold: "30"
       MeasureName: "CPUUtilization"
   ```

   This applies the following configurations for the application:
   + The email address that the Amazon SNS topic uses for notifications is set to your address, or the one you enter in the `options.config` file.
   + The **nodejs-tutorial** table will be used instead of the one created by `.ebextensions/create-dynamodb-table.config`.

1. Remove `.ebextensions/create-dynamodb-table.config`.

   ```
   ~/nodejs-tutorial$ rm .ebextensions/create-dynamodb-table.config
   ```

   The next time you deploy the application, the table created by this configuration file will be deleted.

1. Deploy the updated application to your Elastic Beanstalk environment with the [**eb deploy**](eb3-deploy.md) command.

   ```
   ~/nodejs-example-dynamo$ eb deploy
   ```

1. When environment creation completes, use the [**eb open**](eb3-open.md) command to open the environment's URL in the default browser.

   ```
   ~/nodejs-example-dynamo$ eb open
   ```

When you deploy, Elastic Beanstalk updates the configuration of the Amazon SNS topic and deletes the DynamoDB table that it created when you deployed the first version of the application.

Now, when you terminate the environment, the **nodejs-tutorial** table will not be deleted. This lets you perform blue/green deployments, modify configuration files, or take down your website without risking data loss.

Open your site in a browser and verify that the form works as you expect. Create a few entries, and then check the DynamoDB console to verify the table.

**To view the table**

1. Open the [Tables page](https://console.aws.amazon.com/dynamodb/home?#tables:) in the DynamoDB console.

1. Find the **nodejs-tutorial** table.

1. Select the table, choose **Items**, and then choose **Start search** to view all items in the table.

You can also see that Elastic Beanstalk deleted the table that it created previously.

## Configure your environment for high availability
<a name="nodejs-dynamodb-tutorial-configure"></a>

Finally, configure your environment's Auto Scaling group with a higher minimum instance count. Run at least two instances at all times to prevent the web servers in your environment from being a single point of failure, and to allow you to deploy changes without taking your site out of service.

**To configure your environment's Auto Scaling group for high availability**

1. Open the [Elastic Beanstalk console](https://console.aws.amazon.com/elasticbeanstalk), and in the **Regions** list, select your AWS Region.

1. In the navigation pane, choose **Environments**, and then choose the name of your environment from the list.

1. In the navigation pane, choose **Configuration**.

1. In the **Capacity** configuration category, choose **Edit**.

1. In the **Auto Scaling group** section, set **Min instances** to **2**.

1. To save the changes choose **Apply** at the bottom of the page.

## Cleanup
<a name="nodejs-dynamodb-tutorial-cleanup"></a>

After you finish working with the demo code, you can terminate your environment. Elastic Beanstalk deletes all related AWS resources, such as [Amazon EC2 instances](using-features.managing.ec2.md), [database instances](using-features.managing.db.md), [load balancers](using-features.managing.elb.md), security groups, and [alarms](using-features.alarms.md#using-features.alarms.title). 

Removing resources does not delete the Elastic Beanstalk application, so you can create new environments for your application at any time.

**To terminate your Elastic Beanstalk environment from the console**

1. Open the [Elastic Beanstalk console](https://console.aws.amazon.com/elasticbeanstalk), and in the **Regions** list, select your AWS Region.

1. In the navigation pane, choose **Environments**, and then choose the name of your environment from the list.

1. Choose **Actions**, and then choose **Terminate environment**.

1. Use the on-screen dialog box to confirm environment termination.

You can also delete the external DynamoDB tables that you created.

**To delete a DynamoDB table**

1. Open the [Tables page](https://console.aws.amazon.com/dynamodb/home?#tables:) in the DynamoDB console.

1. Select a table.

1. Choose **Actions**, and then choose **Delete table**.

1. Choose **Delete**.

## Next steps
<a name="nodejs-dynamodb-tutorial-nextsteps"></a>

The example application uses configuration files to configure software settings and create AWS resources as part of your environment. See [Advanced environment customization with configuration files (`.ebextensions`)](ebextensions.md) for more information about configuration files and their use.

The example application for this tutorial uses the Express web framework for Node.js. For more information about Express, see the official documentation at [expressjs.com](https://expressjs.com).

Finally, if you plan on using your application in a production environment, [configure a custom domain name](customdomains.md) for your environment and [enable HTTPS](configuring-https.md) for secure connections.

# Adding an Amazon RDS DB instance to your Node.js Elastic Beanstalk environment
<a name="create-deploy-nodejs.rds"></a>

This topic provides instructions to create an Amazon RDS using the Elastic Beanstalk console. You can use an Amazon Relational Database Service (Amazon RDS) DB instance to store data gathered and modified by your application. The database can be coupled to your environment and managed by Elastic Beanstalk, or it can be created as decoupled and managed externally by another service. In these instructions the database is coupled to your environment and managed by Elastic Beanstalk. For more information about integrating an Amazon RDS with Elastic Beanstalk, see [Adding a database to your Elastic Beanstalk environment](using-features.managing.db.md).

**Topics**
+ [Adding a DB instance to your environment](#nodejs-rds-create)
+ [Downloading a driver](#nodejs-rds-drivers)
+ [Connecting to a database](#nodejs-rds-connect)

## Adding a DB instance to your environment
<a name="nodejs-rds-create"></a>

**To add a DB instance to your environment**

1. Open the [Elastic Beanstalk console](https://console.aws.amazon.com/elasticbeanstalk), and in the **Regions** list, select your AWS Region.

1. In the navigation pane, choose **Environments**, and then choose the name of your environment from the list.

1. In the navigation pane, choose **Configuration**.

1. In the **Database** configuration category, choose **Edit**.

1. Choose a DB engine, and enter a user name and password.

1. To save the changes choose **Apply** at the bottom of the page.

Adding a DB instance takes about 10 minutes. When the environment update is complete, the DB instance's hostname and other connection information are available to your application through the following environment properties:


| Property name | Description | Property value | 
| --- | --- | --- | 
|  `RDS_HOSTNAME`  |  The hostname of the DB instance.  |  On the **Connectivity & security** tab on the Amazon RDS console: **Endpoint**.  | 
|  `RDS_PORT`  |  The port where the DB instance accepts connections. The default value varies among DB engines.  |  On the **Connectivity & security** tab on the Amazon RDS console: **Port**.  | 
|  `RDS_DB_NAME`  |  The database name, **ebdb**.  |  On the **Configuration** tab on the Amazon RDS console: **DB Name**.  | 
|  `RDS_USERNAME`  |  The username that you configured for your database.  |  On the **Configuration** tab on the Amazon RDS console: **Master username**.  | 
|  `RDS_PASSWORD`  |  The password that you configured for your database.  |  Not available for reference in the Amazon RDS console.  | 

For more information about configuring a database instance coupled with an Elastic Beanstalk environment, see [Adding a database to your Elastic Beanstalk environment](using-features.managing.db.md).

## Downloading a driver
<a name="nodejs-rds-drivers"></a>

Add the database driver to your project's [`package.json` file](nodejs-platform-dependencies.md#nodejs-platform-packagejson) under `dependencies`.

**Example `package.json` – Express with MySQL**  

```
{
  "name": "my-app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "ejs": "latest",
    "aws-sdk": "latest",
    "express": "latest",
    "body-parser": "latest",
    "mysql": "latest"
  },
  "scripts": {
    "start": "node app.js"
  }
}
```

**Common driver packages for Node.js**
+ **MySQL** – [mysql](https://www.npmjs.com/package/mysql)
+ **PostgreSQL** – [node-postgres](https://www.npmjs.com/package/pg)
+ **SQL Server** – [node-mssql](https://www.npmjs.com/package/mssql)
+ **Oracle** – [node-oracledb](https://www.npmjs.com/package/oracledb)

## Connecting to a database
<a name="nodejs-rds-connect"></a>

Elastic Beanstalk provides connection information for attached DB instances in environment properties. Use `process.env.VARIABLE` to read the properties and configure a database connection.

**Example app.js – MySQL database connection**  

```
var mysql = require('mysql');

var connection = mysql.createConnection({
  host     : process.env.RDS_HOSTNAME,
  user     : process.env.RDS_USERNAME,
  password : process.env.RDS_PASSWORD,
  port     : process.env.RDS_PORT
});

connection.connect(function(err) {
  if (err) {
    console.error('Database connection failed: ' + err.stack);
    return;
  }

  console.log('Connected to database.');
});

connection.end();
```
For more information about constructing a connection string using node-mysql, see [npmjs.org/package/mysql](https://npmjs.org/package/mysql).

# Node.js tools and resources
<a name="create_deploy_nodejs.resources"></a>

There are several places you can go to get additional help when developing your Node.js applications: 


****  

|  Resource  |  Description  | 
| --- | --- | 
|  [GitHub](https://github.com/aws/aws-sdk-js)  | Install the AWS SDK for Node.js using GitHub.  | 
|  [AWS SDK for Node.js (Developer Preview)](https://aws.amazon.com/sdkfornodejs/)  | One-stop shop for sample code, documentation, tools, and additional resources. | 