Setup auto deployment for Node.js application for production

setup server setup devops nodejs

First you have to have a cloud computer (VPS or Dedicated Server which you can hire one on DigitalOcean, Vultr, Amazon AWS,...)

After connected to it via SSH, you're good to go!

Setup NodeJS and deployment tools on server side

Update package list and install git and build-essential package

sudo apt-get update  
sudo apt-get install -y git build-essential  

Download and install NodeJS

You can go to https://nodejs.org/dist/ and choose the version of NodeJS you want. At the time writing this article, I will get the latest version is v5.8.0

cd ~  
wget https://nodejs.org/dist/v5.8.0/node-v5.8.0-linux-x64.tar.gz  
mkdir node  
tar xvf node-v*.tar.?z --strip-components=1 -C ./node  
cd ~  
rm -rf node-v*  
mkdir node/etc  
echo 'prefix=/usr/local' > node/etc/npmrc  
sudo mv node /opt/  
sudo chown -R root: /opt/node  
sudo ln -s /opt/node/bin/node /usr/local/bin/node  
sudo ln -s /opt/node/bin/npm /usr/local/bin/npm  

Verify node installation

node -v # => v5.8.0  

Create deploy user

useradd -s /bin/bash -m -d /home/deploy -c "deploy user" deploy  

Add password for deploy user

passwd deploy  

Give the safe user permission to use root level commands

usermod -aG sudo deploy  

Logout current user by Ctrl + D and log in as deploy user:

ssh [email protected]_SERVER_IP_ADDRESS  

Install PM2 by NPM

sudo npm install pm2 -g  

(You now may need to enter password to run command that needs root privileges)

On your Node application

Install PM2 on your computer the same as server:

sudo npm install pm2 -g  

Now in your Node project, generate configuration file

pm2 generate  

You will have ecosystem.json in the root of the project.
We have 2 important section to modify as your need.

The first one is the apps section

apps : [  
  {
    name      : "YOU APPLICATION NAME",
    script    : "app.js", // the entry point of your app
    env: {
      // ALL ENVIRONMENT VARIABLES THAT SHARED BETWEEN ALL ENVIRONMENT
      COMMON_VARIABLE: "true"
    },
    env_production : {
      // ENVIRONMENT VARIABLES FOR PRODUCTION
      NODE_ENV: "production"
    },
    env_staging : {
      // ENVIRONMENT VARIABLES FOR STAGING
    }
  }
]

And the second one is deploy section

deploy : {  
  production : {
    user : "deploy",
    host : "YOUR_PRODUCTION_SERVER_IP_ADDRESS/DOMAIN",
    ref  : "origin/master",
    repo : "[email protected]:repo.git", // YOUR APPLICATION REPO
    path : "/home/deploy/YOUR_APP_NAME",
    "post-deploy" : "npm install ; pm2 startOrRestart ecosystem.json --env production"
  },
  staging : {
    user : "deploy",
    host : "YOUR_STAGING_SERVER_IP_ADDRESS/DOMAIN",
    ref  : "origin/master",
    repo : "[email protected]:repo.git", // YOUR APPLICATION REPO
    path : "/home/deploy/YOUR_APP_NAME",
    "post-deploy" : "npm install ; pm2 startOrRestart ecosystem.json --env dev"
  }
}

In the configuration above I have two environments: staging and deployment. Pay attention to UPCASE text and modify it according to your project.

Commit all changes and push to remote before you can deploy it.

Let PM2 create folder structure on your production server by:

pm2 deploy production setup  

And if configurated correctly, you can start your first deployment right now

pm2 deploy production  

Take a cup of coffee and wait for the result:

┌──────────┬────┬──────┬──────┬────────┬───────────┬────────┬────────────┬──────────┐
│ App name │ id │ mode │ PID  │ status │ restarted │ uptime │     memory │ watching │
├──────────┼────┼──────┼──────┼────────┼───────────┼────────┼────────────┼──────────┤
│ app-name │ 0  │ fork │ 5871 │ online │         0 │ 0s     │ 9.012 MB   │ disabled │
└──────────┴────┴──────┴──────┴────────┴───────────┴────────┴────────────┴──────────┘

Auto start application at system boot

pm2 startup ubuntu  

You will see the output:

[PM2] You have to run this command as root. Execute the following command:
      sudo su -c "env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u deploy --hp /home/deploy"

And do what it said

sudo su -c "env PATH=$PATH:/opt/node/bin pm2 startup ubuntu -u deploy --hp /home/deploy"  

One more step, save the current process list (which include your current app, so next time, system startup, it will start current running app automatically)

pm2 save  

Now your application is production ready!
Happy coding!

Tips: you may want to setup nginx to proxy requests to your nodejs application.