Deployment

Heroku

Easy 5-Step Deployment Process

Step 1: Create a Procfile with the following line: web: npm run start:prod. We do this because Heroku runs npm run start by default, so we need this setting to override the default run command.

Step 2: Install the Node.js buildpack for your Heroku app by running the following command: heroku buildpacks:set https://github.com/heroku/heroku-buildpack-nodejs#v91 -a [your app name]. Make sure to replace #v91 with whatever the latest buildpack is, which you can find here.

Step 3: Add this line to your package.json file in the scripts area: "heroku-postbuild": "npm run build",. This is so Heroku can build your production assets when deploying (more of which you can read about here). Then, adjust the prebuild script in your package.json file so it looks like this: "prebuild": "npm run build:clean", to avoid having Heroku attempt to run Jest tests (which are unsupported with this buildpack).

Step 4: Run heroku config:set NPM_CONFIG_PRODUCTION=false so that Heroku can compile the NPM modules included in your devDependencies (since many of these packages are required for the build process).

Step 5: Follow the standard Heroku deploy process:

  1. git add .
  2. git commit -m 'Made some epic changes as per usual'
  3. git push heroku master

AWS S3

Easy 7-Step Deployment Process

Step 1: Run yarn to install dependencies, then npm run build to create the ./build folder.

Step 2: Navigate to AWS S3 and login (or sign up if you don't have an account). Click on Services followed by S3 in the dropdown.

Step 3: Click on Create Bucket and fill out both your Bucket Name and Region (for the USA we recommend US Standard). Click Create to create your bucket.

Step 4: Open the Permissions accordion on the right (under the Properties tab) after selecting your new bucket. Click Add more permissions, set the Grantee to Everyone (or whoever you want to be able to access the website), and give them View Permissions. Click Save.

Step 5: Click on the Static Website Hosting accordion where you should see the URL (or endpoint) of your website (ie. example.s3-website-us-east-1.amazonaws.com). Click Enable website hosting and fill in both the Index document and Error document input fields with index.html. Click Save.

Step 6: Click on your new S3 bucket on the left to open the bucket. Click Upload and select all the files within your ./build folder. Click Start Upload. Once the files are done, select all of the files, right-click on the selected files (or click on the Actions button) and select Make Public.

Step 7: Click on the Properties tab, open Static Website Hosting, and click on the Endpoint link. The app should be running on that URL.

Netlify

Easy 4-Step Deployment to Netlify

You can visit https://www.netlify.com/ for more information.

Step 1: Run yarn to install dependencies, then npm run build to create the ./build folder.

Step 2: Install netlify-cli globally.

npm install netlify-cli -g

or Yarn

yarn global add  netlify-cli

Step 3: Go to your static folder

cd ./build

Step 4: Run netlify deploy. This will ask you a few things and you just need login/create to deploy.

How To Set Up a Node.js Application for Production on Ubuntu 16.04

Introduction

we will cover setting up a production-ready Node.js environment on a single Ubuntu 16.04 server. This server will run a Node.js application managed by PM2, and provide users with secure access to the application through an Nginx reverse proxy. The Nginx server will offer HTTPS, using a free certificate provided by Let's Encrypt.

Server Requirements

  • CPU - 4 cores
  • Memory - 16gb (expandable)
  • Storage - 40gb (expandable)

Install Node.js

We will install the latest LTS release of Node.js, using the NodeSource package archives.

First, you need to install the NodeSource PPA in order to get access to its contents. Make sure you're in your home directory, and use curl to retrieve the installation script for the Node.js 7.x archives:

cd ~
curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh

You can inspect the contents of this script with nano (or your preferred text editor):

nano nodesource_setup.sh

And run the script under sudo:

sudo bash nodesource_setup.sh

The PPA will be added to your configuration and your local package cache will be updated automatically. After running the setup script from nodesource, you can install the Node.js package in the same way that you did above:

sudo apt-get install nodejs

The nodejs package contains the nodejs binary as well as npm, so you don't need to install npm separately. However, in order for some npm packages to work (such as those that require compiling code from source), you will need to install the build-essential package:

sudo apt-get install build-essential

The Node.js runtime is now installed, and ready to run an application!

Install PM2

Now we will install PM2, which is a process manager for Node.js applications. PM2 provides an easy way to manage and daemonize applications (run them in the background as a service).

We will use npm, a package manager for Node modules that installs with Node.js, to install PM2 on our server. Use this command to install PM2:

sudo npm install -g pm2

The -g option tells npm to install the module globally, so that it's available system-wide.

Manage Application with PM2

PM2 is simple and easy to use.

Start Application

The first thing you will want to do is use the pm2 start command to run your application, hello.js, in the background:

pm2 start hello.js

This also adds your application to PM2's process list, which is outputted every time you start an application:

Output
[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Starting hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid  │ status │ restart │ uptime │ memory      │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ hello    │ 0  │ fork │ 3524 │ online │ 0       │ 0s     │ 21.566 MB   │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

As you can see, PM2 automatically assigns an App name (based on the filename, without the .js extension) and a PM2 id. PM2 also maintains other information, such as the PID of the process, its current status, and memory usage.

Applications that are running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup (boot or reboot). Luckily, PM2 provides an easy way to do this, the startup subcommand.

The startup subcommand generates and configures a startup script to launch PM2 and its managed processes on server boots:

pm2 startup systemd

The last line of the resulting output will include a command that you must run with superuser privileges:

Output
[PM2] Init System found: systemd
[PM2] You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

Run the command that was generated (similar to the highlighted output above, but with your username instead of sammy) to set PM2 up to start on boot (use the command from your own output):

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u <username> --hp /home/<username>

This will create a systemd unit which runs pm2 for your user on boot. This pm2 instance, in turn, runs hello.js. You can check the status of the systemd unit with systemctl:

systemctl status pm2-<username>

For a detailed overview of systemd, see Systemd Essentials: Working with Services, Units, and the Journal.

Other PM2 Usage (Optional)

PM2 provides many subcommands that allow you to manage or look up information about your applications. Note that running pm2 without any arguments will display a help page, including example usage, that covers PM2 usage in more detail than this section of the tutorial.

Stop an application with this command (specify the PM2 App name or id):

pm2 stop app_name_or_id

Restart an application with this command (specify the PM2 App name or id):

pm2 restart app_name_or_id

The list of applications currently managed by PM2 can also be looked up with the list subcommand:

pm2 list

More information about a specific application can be found by using the info subcommand (specify the PM2 App name or id):

pm2 info example

The PM2 process monitor can be pulled up with the monit subcommand. This displays the application status, CPU, and memory usage:

pm2 monit

Now that your Node.js application is running, and managed by PM2, let's set up the reverse proxy.

Set Up Nginx as a Reverse Proxy Server

Now that your application is running, and listening on localhost, you need to set up a way for your users to access it. We will set up the Nginx web server as a reverse proxy for this purpose.

In the prerequisite tutorial, we set up our Nginx configuration in the /etc/nginx/sites-available/default file. Open the file for editing:

sudo nano /etc/nginx/sites-available/default

Within the server block you should have an existing location / block. Replace the contents of that block with the following configuration. If your application is set to listen on a different port, update the highlighted portion to the correct port number.

/etc/nginx/sites-available/default
. . .
    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

This configures the server to respond to requests at its root. Assuming our server is available at example.com, accessing https://example.com/ via a web browser would send the request to hello.js, listening on port 8080 at localhost.

You can add additional location blocks to the same server block to provide access to other applications on the same server. For example, if you were also running another Node.js application on port 8081, you could add this location block to allow access to it via http://example.com/app2:

/etc/nginx/sites-available/default — Optional
. . .
    location /app2 {
        proxy_pass http://localhost:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Once you are done adding the location blocks for your applications, save and exit.

Make sure you didn't introduce any syntax errors by typing:

sudo nginx -t

Next, restart Nginx:

sudo systemctl restart nginx

Assuming that your Node.js application is running, and your application and Nginx configurations are correct, you should now be able to access your application via the Nginx reverse proxy. Try it out by accessing your server's URL (its public IP address or domain name).