{"id":1951,"date":"2019-07-11T10:55:31","date_gmt":"2019-07-11T10:55:31","guid":{"rendered":"https:\/\/www.folio3.com\/mobile\/?p=1951"},"modified":"2020-03-26T17:13:09","modified_gmt":"2020-03-26T17:13:09","slug":"how-to-deploy-a-microservice-architecture-using-pm2","status":"publish","type":"post","link":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/","title":{"rendered":"How to deploy a microservice architecture using PM2"},"content":{"rendered":"\n<p>PM2 is a  process manager for Node.js, although not limited to it, and it gives us  many possibilities to setup a deployment pipeline which later on we can  use to automate the deployment process.<\/p>\n\n\n\n<p>In this tutorial, we are going to create the distributed architecture of a Javascript application and deploy it under a few commands.<\/p>\n\n\n\n<p>Basic Requirements:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Basic Knowledge of JavaScript and its technologies<\/li><li>Beginner level knowledge of Linux commands and scripting<\/li><li>Cloud\/local hosted server with SSH access. (or any Linux machine to play around with having SSH access, VM etc.)<\/li><li>Tutorial would be carried out on Linux environment, you can use git-SCM console (<a rel=\"noreferrer noopener\" href=\"https:\/\/git-scm.com\/\" target=\"_blank\">https:\/\/git-scm.com\/<\/a>) for windows<\/li><li>The tutorial assumes you have <strong>NodeJS (<\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-node-js-on-ubuntu-18-04\" target=\"_blank\"><strong>18.04<\/strong><\/a><strong>, <\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-node-js-on-ubuntu-16-04\" target=\"_blank\"><strong>16.04<\/strong><\/a><strong>) <\/strong>and <strong>MongoDB (<\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-mongodb-on-ubuntu-18-04\" target=\"_blank\"><strong>18.04<\/strong><\/a><strong>, <\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/how-to-install-and-secure-mongodb-on-ubuntu-16-04\" target=\"_blank\"><strong>16.04<\/strong><\/a><strong>)<\/strong> pre-installed on there remote server.<\/li><\/ul>\n\n\n\n<p>Tools we are going to use:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>NodeJS 10<\/li><li>ExpressJS 4<\/li><li>MongoDB 3.6\/4<\/li><li>PM2<\/li><\/ul>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"47a4\">Part 1. Project&nbsp;Setup:<\/h3>\n\n\n\n<p>We will have 3 services in our PM2 to keep things simple.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>pm2-auth<\/li><li>pm2-api<\/li><li>pm2-mongodb<\/li><\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>The\n architecture of the application can be very complex as well, but it is \nrecommended to move to more reliable infrastructure options, such as \ncontainers (docker). But up to mid-level applications, this architecture\n could be utilized very smoothly.<\/p><\/blockquote>\n\n\n\n<p>We\n will build 2 services namely pm2-api and pm2-auth, the prefix \u201cpm2-\u201d is\n to identify that our services are related. And we will also have a \nmongodb provisioning process inside pm2 as well named pm2-mongodb.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"1566\">Quick start:<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>If you are going for quick start please skip the following steps and move forward to <a href=\"https:\/\/medium.com\/@imixtron\/microservice-architecture-with-pm2-deploy-4d5f2245f011#b961\">step#2<\/a><\/p><\/blockquote>\n\n\n\n<p>If  you have a good grasp on creating the services on node js you can skip  their creation and jump right to the deployment process, you will have  to <strong>fork<\/strong> this repository <code><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/imixtron\/pm2-microservices.git\" target=\"_blank\">https:\/\/github.com\/imixtron\/pm2-microservices.git<\/a><\/code>. Then go ahead and Clone that repository for a quick start:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>git clone <\/strong><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/imixtron\/pm2-microservices.git\" target=\"_blank\"><strong>https:\/\/github.com\/&lt;your_username&gt;\/pm2-microservices.gi<\/strong><\/a><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"dcda\">Detailed:<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>If you are new to JavaScript and Node Scene, i would recommend this <a href=\"https:\/\/scotch.io\/tutorials\/build-a-restful-api-using-node-and-express-4\" rel=\"noreferrer noopener\" target=\"_blank\">Beginner level tutorial<\/a> that will get you started.<\/p><\/blockquote>\n\n\n\n<p>Lets start by creating a folder where our codebase is going to be<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>mkdir pm2-microservices<\/strong><br>$ <strong>cd pm2-microservices<\/strong><\/pre>\n\n\n\n<p>Now,  we will be creating separate folders for each service having prefix  \u2018pm2-\u2019, with the following folder structure, so go ahead and create the files and folders.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\u2022<br>\u251c\u2500\u2500 pm2-api<br>\u2502   \u251c\u2500\u2500 .env<br>\u2502   \u251c\u2500\u2500 index.js<br>\u2502   \u2514\u2500\u2500 package.json<br>\u2502<br>\u251c\u2500\u2500 pm2-auth<br>\u2502   \u251c\u2500\u2500 .env<br>\u2502   \u251c\u2500\u2500 index.js<br>\u2502   \u2514\u2500\u2500 package.json<br>\u2502<br>\u2514\u2500\u2500 pm2-mongodb<br>    \u251c\u2500\u2500 .gitkeep<\/pre>\n\n\n\n<p>We will leave pm2-mongodb folder empty as it will contain our data files,  we can also later on mount this to a persistent storage, so it is independent of our application server or completely change the location as we require. Since the projects are similar, we will go ahead and  populate the package.json with following content:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ pm2-api\/package.json<br>{<br>  \"name\": \"pm2-api\",<br>  \"version\": \"1.0.0\",<br>  \"main\": \"index.js\",<br>  \"scripts\": {<br>    \"build\": \"npm install &amp;&amp; npm start\",<br>    \"start\": \"node index.js\",<br>  },<br>  \"dependencies\": {<br>    \"body-parser\": \"^1.19.0\",<br>    \"dotenv\": \"^8.0.0\",<br>    \"express\": \"^4.17.0\",<br>    \"mongoose\": \"^5.5.11\"<br>  }<br>}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ pm2-auth\/package.json<br>{<br>  \"name\": \"pm2-auth\",<br>  \"version\": \"1.0.0\",<br>  \"main\": \"index.js\",<br>  \"scripts\": {<br>    \"build\": \"npm install &amp;&amp; npm start\",<br>    \"start\": \"node index.js\",<br>  },<br>  \"dependencies\": {<br>    \"body-parser\": \"^1.19.0\",<br>    \"dotenv\": \"^8.0.0\",<br>    \"express\": \"^4.17.0\",<br>    \"mongoose\": \"^5.5.11\"<br>  }<br>}<\/pre>\n\n\n\n<p>Now that we have our dependencies in order, we can go ahead and hit <code>npm install<\/code> in our main folders <code>pm2-api<\/code> and <code>pm2-auth.<\/code> Our&nbsp;<code>.env<\/code> file will be similar having common contents with a tiny change of PORT, for pm2-api we will be using <code>9999<\/code> whereas for pm2-auth we will be using port<code>4000.<\/code><\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"9eb3\">.env<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\">PORT = 9999<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"># global environment<br>MONGO_URI = 'mongodb:\/\/localhost:27017'<br>MONGO_DB_NAME = 'serviceDB'<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"a7a6\">pm2-api (index.js)<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\">const dotenv      = require('dotenv').config();<br>const express     = require('express');<br>const app         = express();<br>const bodyParser  = require('body-parser');<br>const mongoose    = require('mongoose');<br>const Schema      = mongoose.Schema;<br>const mongoUri    = process.env.MONGO_URI;<br>const mongoDbName = process.env.MONGO_DB_NAME;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ connect to mongoose instance (default config)<br>mongoose.connect(`${mongoUri}\/${mongoDbName}`, { useNewUrlParser: true });<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ user model<br>const userSchema = new Schema({<br>  name: String,<br>  email: String,<br>  password: String<br>});<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">const User = mongoose.model('users', userSchema);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ configuring bodyParser for POST data<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">app.use(bodyParser.urlencoded({ extended: true }));<br>app.use(bodyParser.json());<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">const port = process.env.PORT || 9999;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ API Routes<br>const router = express.Router();<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">router.post('\/user', (req, res) =&gt; {<br>  const userData = req.body;<br>  const user = new User(userData);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">  user.save((error) =&gt; {<br>    if (!!error)<br>      return res.status(500).send({error: error});<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">    return res.status(500).send({<br>      message: 'user created successfully'<br>    });<br>  });<br>});<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">app.use('\/api', router);<br>app.listen(port);<br>console.log(`port ${port}`);<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"3ec5\">pm2-auth (index.js)<\/h4>\n\n\n\n<pre class=\"wp-block-preformatted\">const dotenv      = require('dotenv').config();<br>const express     = require('express');<br>const app         = express();<br>const bodyParser  = require('body-parser');<br>const mongoose    = require('mongoose');<br>const Schema      = mongoose.Schema;<br>const mongoUri    = process.env.MONGO_URI;<br>const mongoDbName = process.env.MONGO_DB_NAME;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ connect to mongoose instance (default config)<br>mongoose.connect(`${mongoUri}\/${mongoDbName}`, { useNewUrlParser: true });<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ user model<br>const userSchema = new Schema({<br>  name: String,<br>  email: String,<br>  password: String<br>});<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">const User = mongoose.model('users', userSchema);<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ configuring bodyParser for POST data<br>app.use(bodyParser.urlencoded({ extended: true }));<br>app.use(bodyParser.json());<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">const port = process.env.PORT || 4000;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ API Routes<br>const router = express.Router();<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">router.post('\/login', (req, res) =&gt; {<br>  const {email, password} = req.body;<br>  User.findOne({ email: email}, (error, user) =&gt; {<br>    if (error)<br>      return res.status(500).send({ <br>        error: true, <br>        message: 'Invalid credentials' <br>      });<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">    if (user.password === password)<br>      return res.status(200).send({<br>        token: Buffer.from(user.password).toString('base64'),<br>        ...user.toObject()<br>      });<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">    return res.status(200).send({<br>      message: 'Invalid Credentials'<br>    });<br>  });<br>});<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">app.use('\/auth', router);<br>app.listen(port);<br>console.log(`port ${port}`);<\/pre>\n\n\n\n<p>As\n you can clearly see, to keep the tutorial simple, both of our services \nare exactly similar except for the endpoint functionality. We can have \nmultiple services that work independently from each other.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Do note that we are using <a rel=\"noreferrer noopener\" href=\"https:\/\/www.npmjs.com\/package\/dotenv\" target=\"_blank\"><strong>dotenv<\/strong><\/a>  to parse .env file for local development. When we deploy this to server  naturally we will have our own environment variables set via pm2 for each process.<\/p><\/blockquote>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"918f\">pm2-mongodb<\/h4>\n\n\n\n<p>We are going to leave this folder empty for now, and create an empty file <code>.gitkeep<\/code><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"b961\">Part 2. PM2 Ecosystem setup:<\/h3>\n\n\n\n<p>Now, over to the deployment magic, we are going to create a process file  containing the execution of our applications. In order to do so, in the  main folder ( <code>pm2-microservices<\/code> ), run the following command to init an ecosystem file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>pm2 ecosystem<\/strong><\/pre>\n\n\n\n<p>A file, <code>ecosystem.config.js<\/code> with following content should be generated by pm2, having more content then below (showing less content):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">module.exports = {<br>  apps : [{...}],<br>  deploy : {<br>    production : {...}<br>  }<br>};<\/pre>\n\n\n\n<p>Lets discuss the applications first, the json will contain the configuration of our process that will be running our respective application. Consider pm2-api as an example, pm2-auth will be exactly similar:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{<br>  cwd: 'pm2-api',<br>  name: 'pm2-api',<br>  script: 'npm',<br>  args: 'run build',<br>  restartDelay: 1000,<br>  instances: 1,<br>  autorestart: true,<br>  watch: false,<br>  max_memory_restart: '200M',<br>  env: {<br>    SERVICE_NAME: 'pm2-api',<br>    PORT: 9999,<br>    NODE_ENV: 'development'<br>  },<br>  env_production: {<br>    SERVICE_NAME: 'pm2-api',<br>    PORT: 9999,<br>    NODE_ENV: 'production'<br>  }<br>}<\/pre>\n\n\n\n<p>Some important attributes to note are <code>cwd<\/code>&nbsp;, <code>script<\/code>&nbsp;, <code>args<\/code>&nbsp;.<\/p>\n\n\n\n<p><code>cwd<\/code>\n is the current working directory which will determine the file location\n from our main file, it is recommended to keep it same as the project \nfolder unless you know what you\u2019re doing.<\/p>\n\n\n\n<p><code>script<\/code>\n can be the bash file or a command that we\u2019re executing, in our case we \nare using npm run-script to start our server when it runs from our \necosystem.<\/p>\n\n\n\n<p><code>args<\/code> are there to supply arguments to our script. So, for instance we have to run the command <code>npm run build<\/code> which will install dependencies and the start the server. so we would split <code>npm<\/code> and place it in our script attribute, and <code>run build<\/code> in our <code>args<\/code> attribute.<\/p>\n\n\n\n<p>You can find further details about the attributes in the <a href=\"http:\/\/pm2.keymetrics.io\/docs\/usage\/application-declaration\/#general\" rel=\"noreferrer noopener\" target=\"_blank\">main documentation<\/a>.<\/p>\n\n\n\n<p>And for pm2-mongodb we will only have our process execute a bash command, <code>monogod --dbpath pm2-mongodb<\/code> (<em>given that mongodb is already installed on our server and present in our path variables).<\/em><\/p>\n\n\n\n<p>Compiling everything we will have the following structure, copy this inside of your <code>ecosystem.config.js<\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ global environment<br>const commonEnv = {<br>  dev: {<br>    MONGO_URI: 'mongodb:\/\/localhost:27017',<br>    MONGO_DB_NAME: 'serviceDB'<br>  },<br>  prod: {<br>    MONGO_URI: 'mongodb:\/\/localhost:27017',<br>    MONGO_DB_NAME: 'serviceDB'<br>  }<br>}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">module.exports = {<br>  apps: [{<br>    cwd: 'pm2-api',<br>    name: 'pm2-api',<br>    script: 'npm',<br>    args: 'run build',<br>    restartDelay: 1000,<br>    instances: 1,<br>    autorestart: true,<br>    watch: false,<br>    max_memory_restart: '200M',<br>    env: {<br>      ...commonEnv.dev,<br>      SERVICE_NAME: 'pm2-api',<br>      PORT: 9999,<br>      NODE_ENV: 'development'<br>    },<br>    env_production: {<br>      ...commonEnv.prod,<br>      SERVICE_NAME: 'pm2-api',<br>      PORT: 9999,<br>      NODE_ENV: 'production'<br>    }<br>  },<br>  {<br>    cwd: 'pm2-auth',<br>    name: 'pm2-auth',<br>    script: 'npm',<br>    args: 'run build',<br>    restartDelay: 1000,<br>    instances: 1,<br>    autorestart: true,<br>    watch: false,<br>    max_memory_restart: '200M',<br>    env: {<br>      ...commonEnv.dev,<br>       SERVICE_NAME: 'pm2-auth',<br>      PORT: 4000,<br>      NODE_ENV: 'development'<br>    },<br>    env_production: {<br>      ...commonEnv.prod,<br>      SERVICE_NAME: 'pm2-auth',<br>      PORT: 4000,<br>      NODE_ENV: 'production'<br>    }<br>  },<br>  {<br>    name: 'pm2-mongodb',<br>    script: 'mongod',<br>    args: '--dbpath pm2-mongodb',<br>    instances: 1,<br>    autorestart: true,<br>    watch: false<br>  }]<br>};<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>As you can see we have a variable <code>commonEnv<\/code> which has the common environment variables shared between apps, in our case MongoDB Uri string.<\/p><\/blockquote>\n\n\n\n<p>Now that we have our process file in order, hit the following command to check if everything is working:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$<strong> pm2 start ecosystem.config.js<\/strong><\/pre>\n\n\n\n<p>If everything is in order we are going to commit this change and push it to our repository<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>git add ecosystem.config.js<\/strong><br>$ <strong>git commit -a -m \"add ecosystem file <\/strong><strong>for<\/strong><strong> pm2\"<\/strong><br>$ <strong>git push<\/strong><\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ad8c\">Part 3. Deployment:<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"acef\">Server Setup:<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>For ease, lets consider the server\u2019s hostname to be <strong>pm2-microservices, <\/strong>you can replace it with the ip and the we are going to use <strong>root<\/strong> as our user. It is not recommended to use root for deployments.<\/p><\/blockquote>\n\n\n\n<p>All  the major cloud providers offer a limited amount of resources for free,  which will be enough to get going with this tutorial. You can use any, I  personally prefer Digital Ocean and for this tutorial i have a $5 Droplet up and running. <a rel=\"noreferrer noopener\" href=\"https:\/\/m.do.co\/c\/92a0a7c8d6ae\" target=\"_blank\">You can use my referral link to get $10 in credit when you signup<\/a>.<\/p>\n\n\n\n<p>For server setup, you can follow this <a rel=\"noreferrer noopener\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/initial-server-setup-with-ubuntu-18-04\" target=\"_blank\"><strong>Digital Ocean tutorial<\/strong><\/a> which will guide u to setup a ssh keys on the server and your GitHub account for a smooth and hassle free deployment.<\/p>\n\n\n\n<p>Firstly  we are going to generate a SSH key and copy it over to our server. If  you already have a SSH key that you use, ignore this bit. If you don\u2019t then go ahead and run the following command in your bash terminal:  (enter email in &lt;email&gt;)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>ssh-keygen -t rsa -b 4096 -C \"&lt;email&gt;\"<\/strong><\/pre>\n\n\n\n<p>Assuming you have the server ready to go, run the following command to copy your public key onto the server:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>ssh-copy-id -i ~\/.ssh\/id_rsa.pub &lt;username&gt;@&lt;ip_address&gt;<\/strong><\/pre>\n\n\n\n<p>After this is done we will also need to generate SSH key on our server which we will copy on our GitHub account so it is recognized when our server  pulls the repository onto the server. Here, let the email be same as our <strong>Github<\/strong> account so their are no conflicts.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>ssh root@&lt;hostname&gt;<br>...<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">root@pm2-microservices:~# <strong>ssh-keygen -t rsa -b 4096 -C \"&lt;email&gt;\"<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">Generating public\/private rsa key pair.<br>Enter file in which to save the key (\/root\/.ssh\/id_rsa):<br>Enter passphrase (empty for no passphrase):<br>Enter same passphrase again:<br>Your identification has been saved in \/root\/.ssh\/id_rsa.<br>Your public key has been saved in \/root\/.ssh\/id_rsa.pub.<br>The key fingerprint is:<br>SHA256:f+Z2fzSC\/Y4BD+1xHXtvpAzKGvtHA7a5ErMFXLS6wUQ &lt;email&gt;<br>The key's randomart image is:<br>+---[RSA 4096]----+<br>|        E..      |<br>|       .  ..     |<br>|       ....    . |<br>|       oo.o .   +|<br>|        So *+o o+|<br>|        o=+oB=o++|<br>|        o=+oo==.+|<br>|        o+.+o +o.|<br>|        oo.o.o.oo|<br>+----[SHA256]-----+<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">root@pm2-microservices:~# <strong>cat ~\/.ssh\/id_rsa.pub<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">ssh-rsa AAAAB3AAADAQABAAACAQCqOPsoWFJkNwahquJx6mr\/H0TPEBqcaZKqGkB7wIHTB2gvJ36aZhfTFg5dSfknluMZa6nt1KOSVIhCBciEaRvObLxI2NwRYdtYP3zEl3SjwCNg1G0gFUJ8+uIobD2AIM1g9WURMRDDmuPZTakyyPsu5qqS2TvoezzzsJUBu\/1Ul3grZ8am0SAeJYGjm1l\/ajgRdlemn3m\/GQMJTxMyR0Q\/yPrvXmC\/Z3jhs24km9n9b+\/2gXmzeQdXpxYyl\/R7iM52cZNC7cFukYcZL8Zw6JZ5fs9zv0mxOK4uQEeIrUldxAezaD9IsFWtYtVr9QpjxTRnZRJ7CrsBSnZttQgVig0FjlDkYSFmkfeQkfJe9BvrYYi3VO1piaAdRjlxTwud74GZK3vwz9TIN7MbF7kVOvxnwXW19n6ZJe9xsnrDBRaFHvjjd6tXTUn4p0fz1BIuHQPGPFOvW\/I+\/IKAtNBpxAumGZ6JMAvYBwacP8sKalROzmSe2Z8BQt8nJKBDeLHJbDPAQn4ghyqcsR0s0UH+NV3Oci1h3JkMV9310VSdytpjRQKOl98uniaOZWXINzaC1yc2EABdHBsdKh7cMSBbM1BDb5dcwuy76OJn\/SXQy8VY39a6AqHMS19IjHDhr1zzNuhLI9HrxIooBOtof9egthyU5gRBLi8rUNauD5Bgfscp+ZT+Dufdbxew== &lt;email&gt;<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">root@pm2-microservices:~#<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>By\n now the certificate and server would have been deleted, the shell \noutput is just to give you guys the idea of how it\u2019s going to look. You \nwill have all that information unique to ur system when u generate it.<\/p><\/blockquote>\n\n\n\n<p>When u have your SSH public key on the console, as seen above, carefully <strong>copy<\/strong> it. On Github navigate to Settings &gt; <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/settings\/keys\" target=\"_blank\">SSH and GPG keys<\/a> and click on New SSH key. You should have the following screen in front of you:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Also, do note that you will be generating the SSH key on your server (not on local machine) that would be set inside the Github account<\/p><\/blockquote>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*Xwc7dSTdQQHd9R8k6Pg1Zw.png\" alt=\"\"\/><figcaption><br><\/figcaption><\/figure>\n\n\n\n<p>Give a title to your key so you can recognize the it later on and inside the  Key textbox paste the key that we copied earlier from the console.<\/p>\n\n\n\n<p>While you are connected to the server, you should also add Github.com to your known hosts so when pm2 is deploying it wont have any problem pulling the repo from Github.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@pm2-microservices:~# <strong>ssh-keyscan -H github.com &gt;&gt; ~\/.ssh\/known_hosts<\/strong><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"24c4\">Deployment details in Ecosystem file:<\/h4>\n\n\n\n<p>Now,  that it\u2019s done, we can securely connect to our server &amp; repository  without worrying about passwords. It is necessary to do so since deploying on the server is only supported via SSH key. We will add the only thing that is missing in our ecosystem.config.js, the deployment  instructions. We will be adding the following content to the <code>module.exports<\/code><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">...<br>module.exports = {<br>  apps: [...],<br>  deploy: {<br>    development: {<br>      user: 'root',<br>      host: '<strong>&lt;remote host ip&gt;<\/strong>',<br>      ref: 'origin\/master', \/\/ branch to be deployed could be diff<br>      ssh_options: \"StrictHostKeyChecking=no\",<br>      repo: '<a href=\"mailto:git@github.com\" rel=\"noreferrer noopener\" target=\"_blank\">git@github.com<\/a>:<strong>&lt;github_user&gt;<\/strong>\/pm2-microservices.git',<br>      path: '\/opt\/pm2-microservices\/production',<br>      'pre-setup': 'npm install -g pm2',<br>      'post-deploy': 'npm install &amp;&amp; pm2 reload ecosystem.config.js --env development'<br>    }<br>  }<br>}<\/pre>\n\n\n\n<p>Finally our <code>ecosystem.config.js<\/code> would look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ ecosystem.config.js<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">\/\/ global environment<br>const commonEnv = {<br>  dev: {<br>    MONGO_URI: 'mongodb:\/\/localhost:27017',<br>    MONGO_DB_NAME: 'serviceDB'<br>  },<br>  prod: {<br>    MONGO_URI: 'mongodb:\/\/localhost:27017',<br>    MONGO_DB_NAME: 'serviceDB'<br>  }<br>}<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">module.exports = {<br>  apps: [<br>    {<br>      cwd: 'pm2-api',<br>      name: 'pm2-api',<br>      script: 'index.js',<br>      restartDelay: 1000,<br>      instances: 1,<br>      autorestart: true,<br>      watch: false,<br>      max_memory_restart: '200M',<br>      env: {<br>        ...commonEnv.dev,<br>        SERVICE_NAME: 'pm2-api',<br>        PORT: 9999,<br>        NODE_ENV: 'development'<br>      },<br>      env_production: {<br>        ...commonEnv.prod,<br>        SERVICE_NAME: 'pm2-api',<br>        PORT: 9999,<br>        NODE_ENV: 'production'<br>      }<br>    },<br>    {<br>      cwd: 'pm2-auth',<br>      name: 'pm2-auth',<br>      script: 'index.js',<br>      restartDelay: 1000,<br>      instances: 1,<br>      autorestart: true,<br>      watch: false,<br>      max_memory_restart: '200M',<br>      env: {<br>        ...commonEnv.dev,<br>        SERVICE_NAME: 'pm2-auth',<br>        PORT: 4000,<br>        NODE_ENV: 'development'<br>      },<br>      env_production: {<br>        ...commonEnv.prod,<br>        SERVICE_NAME: 'pm2-auth',<br>        PORT: 4000,<br>        NODE_ENV: 'production'<br>      }<br>    },<br>    {<br>       name: 'pm2-mongodb',<br>       script: 'mongod',<br>       args: '--dbpath pm2-mongodb',<br>       instances: 1,<br>       autorestart: true,<br>       watch: false,<br>    }],<br>  deploy: {<br>    development: {<br>      user: 'root',<br>      host: '<strong>&lt;hostname&gt;<\/strong>',<br>      ref: 'origin\/master',<br>      ssh_options: \"StrictHostKeyChecking=no\",<br>      repo: 'git@github.com:<strong>&lt;github_user&gt;<\/strong>\/pm2-microservices.git',<br>      path: '\/opt\/pm2-microservices\/production',<br>      'pre-setup': 'npm install pm2',<br>      'post-deploy': 'npm install &amp;&amp; pm2 reload ecosystem.config.js --env production'<br>    }<br>  }<br>};<\/pre>\n\n\n\n<p>Finally, we are 2 steps away from deploying our application. First we need to  setup the environment over to the server, since we have configured all  the certificates and we have proper access from our local to server to  Github, we are good to go. On our local project workspace, run:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>pm2 deploy development setup<\/strong><br>--&gt; Deploying to development environment<br>--&gt; on host <strong>\/\/\/\/\/hostip\/\/\/\/\/<\/strong><br>  \u25cb executing pre-setup `npm install pm2`<br>...<br>\u25cb running setup<br>  \u25cb cloning <a href=\"mailto:git@github.com\" rel=\"noreferrer noopener\" target=\"_blank\">git@github.com<\/a>:imixtron\/pm2-microservices.git<br>  \u25cb full fetch<br>Cloning into '\/opt\/pm2-microservices\/production\/source'...<br>Warning: Permanently added the RSA host key for IP address '13.229.188.59' to the list of known hosts.<br>  \u25cb hook post-setup<br>  \u25cb setup complete<br>--&gt; Success<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>pm2 deploy development --force<\/strong><br>--&gt; Deploying to development environment<br>--&gt; on host <strong>\/\/\/\/\/hostip\/\/\/\/\/<\/strong><br>  \u25cb deploying origin\/complete<br>  \u25cb executing pre-deploy-local<br>  \u25cb hook pre-deploy<br>  \u25cb fast forward complete<br>Your branch is up to date with 'origin\/complete'.<br>Already on 'complete'<br>From github.com:imixtron\/pm2-microservices<br> * branch            complete   -&gt; FETCH_HEAD<br>Already up to date.<br>  \u25cb executing post-deploy `npm install &amp;&amp; pm2 reload ecosystem.config.js --env production`<br>npm WARN saveError ENOENT: no such file or directory, open '\/opt\/pm2-microservices\/production\/source\/package.json'<br>npm WARN enoent ENOENT: no such file or directory, open '\/opt\/pm2-microservices\/production\/source\/package.json'<br>npm WARN source No description<br>npm WARN source No repository field.<br>npm WARN source No README data<br>npm WARN source No license field.<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">up to date in 0.586s<br>found 0 vulnerabilities<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">[PM2] Spawning PM2 daemon with pm2_home=\/root\/.pm2<br>[PM2] PM2 Successfully daemonized<br>[PM2][WARN] Applications pm2-api, pm2-auth, pm2-mongodb not running, starting...<br>[PM2] App [pm2-api] launched (1 instances)<br>[PM2][WARN] Environment [production] is not defined in process file<br>[PM2] App [pm2-auth] launched (1 instances)<br>[PM2] App [pm2-mongodb] launched (1 instances)<br>  \u25cb hook test<br>  \u25cb successfully deployed origin\/complete<br>--&gt; Success<\/pre>\n\n\n\n<p>And that&#8217;s about it, you have deployed all of your code base onto the  server. The build-up to this point took a while like Game of Thrones did, but the ending to this one is far more satisfying :). Next time you have to do a deployment, you will be needing to push your changes to the server and run a single command and no one needs to die:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ <strong>pm2 deploy development update<\/strong><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"># Pushed Bad Code? Revert in a single command<br>$ <code><strong>pm2 deploy production revert 1<\/strong><\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"5e65\">Testing Routes:<\/h4>\n\n\n\n<p>Use the following endpoints to test the routes, curl commands are attached for ease.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>- Create User<br>ENDPOINT<\/strong><br>  POST &lt;hostname&gt;:9999\/api\/user<br><strong>PAYLOAD<\/strong><br>  {<br>    \"name\": \"user1\",<br>    \"email\": \"<a href=\"mailto:imixtron@gmail.com\" rel=\"noreferrer noopener\" target=\"_blank\">user1@gmail.com<\/a>\",<br>    \"password\": \"password123\"<br>  }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"># curl<br>curl -X POST -H \"Content-type: application\/json\" -d '{ \"name\": \"user1\", \"email\": \"<a href=\"mailto:user1@gmail.com\" rel=\"noreferrer noopener\" target=\"_blank\">user1@gmail.com<\/a>\", \"password\": \"password123\" }' '&lt;hostname&gt;:9999\/api\/user'<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>- Login<br>ENDPOINT<br>  <\/strong>POST &lt;hostname&gt;:4000\/auth\/login<br><strong>PAYLOAD<\/strong><br>  {<br>    \"email\": \"<a href=\"mailto:imixtron@gmail.com\" rel=\"noreferrer noopener\" target=\"_blank\">user1@gmail.com<\/a>\",<br>    \"password\": \"password123\"<br>  }<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"># curl<br>curl -X POST -H \"Content-type: application\/json\" -d '{ \"email\": \"<a href=\"mailto:user1@gmail.com\" rel=\"noreferrer noopener\" target=\"_blank\">user1@gmail.com<\/a>\", \"password\": \"password123\" }' '&lt;hostname&gt;:4000\/auth\/login'<\/pre>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"> <br>Conclusion: <\/h2>\n\n\n\n<p>And that&#8217;s a wrap, for small to mid-level architecture i believe PM2 can  sustain good amount of load, given we are properly managing the  resources. We can further have multiple processes running our servers.<\/p>\n\n\n\n<p>Furthermore, with this architecture we can easily move to <strong>docker<\/strong> environment by creating <code>dockerfile<\/code> for each service and using <strong>kubernetes<\/strong> to orchestrate our deployment and scaling.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PM2 is a process manager for Node.js, although not limited to it, and it gives us many possibilities to setup a deployment pipeline which later on we can use to automate the deployment process. In this tutorial, we are going to create the distributed architecture of a Javascript application and deploy it under a few &hellip; <a href=\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How to deploy a microservice architecture using PM2&#8221;<\/span><\/a><\/p>\n","protected":false},"author":37,"featured_media":2410,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1951","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to Use Microservice Architecture with PM2<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Use Microservice Architecture with PM2\" \/>\n<meta property=\"og:description\" content=\"PM2 is a process manager for Node.js, although not limited to it, and it gives us many possibilities to setup a deployment pipeline which later on we can use to automate the deployment process. In this tutorial, we are going to create the distributed architecture of a Javascript application and deploy it under a few &hellip; Continue reading &quot;How to deploy a microservice architecture using PM2&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\" \/>\n<meta property=\"og:site_name\" content=\"Mobile App Development Services\" \/>\n<meta property=\"article:published_time\" content=\"2019-07-11T10:55:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-03-26T17:13:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"560\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Noc Folio3\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Noc Folio3\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\"},\"author\":{\"name\":\"Noc Folio3\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/0b6e4f68efbd12d222ac9422766c61eb\"},\"headline\":\"How to deploy a microservice architecture using PM2\",\"datePublished\":\"2019-07-11T10:55:31+00:00\",\"dateModified\":\"2020-03-26T17:13:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\"},\"wordCount\":1580,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\",\"url\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\",\"name\":\"How to Use Microservice Architecture with PM2\",\"isPartOf\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png\",\"datePublished\":\"2019-07-11T10:55:31+00:00\",\"dateModified\":\"2020-03-26T17:13:09+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage\",\"url\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png\",\"contentUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png\",\"width\":1024,\"height\":560,\"caption\":\"How-to-deploy-a-microservice-architecture-using-PM2\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.folio3.com\/mobile\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to deploy a microservice architecture using PM2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#website\",\"url\":\"https:\/\/www.folio3.com\/mobile\/\",\"name\":\"Mobile App Development Services\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.folio3.com\/mobile\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#organization\",\"name\":\"Mobile App Development Services\",\"url\":\"https:\/\/www.folio3.com\/mobile\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png\",\"contentUrl\":\"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png\",\"width\":210,\"height\":50,\"caption\":\"Mobile App Development Services\"},\"image\":{\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/0b6e4f68efbd12d222ac9422766c61eb\",\"name\":\"Noc Folio3\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/29f05a21b8db20048e7717694b024bbd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/29f05a21b8db20048e7717694b024bbd?s=96&d=mm&r=g\",\"caption\":\"Noc Folio3\"},\"url\":\"https:\/\/www.folio3.com\/mobile\/blog\/author\/noc\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Use Microservice Architecture with PM2","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/","og_locale":"en_US","og_type":"article","og_title":"How to Use Microservice Architecture with PM2","og_description":"PM2 is a process manager for Node.js, although not limited to it, and it gives us many possibilities to setup a deployment pipeline which later on we can use to automate the deployment process. In this tutorial, we are going to create the distributed architecture of a Javascript application and deploy it under a few &hellip; Continue reading \"How to deploy a microservice architecture using PM2\"","og_url":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/","og_site_name":"Mobile App Development Services","article_published_time":"2019-07-11T10:55:31+00:00","article_modified_time":"2020-03-26T17:13:09+00:00","og_image":[{"width":1024,"height":560,"url":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png","type":"image\/png"}],"author":"Noc Folio3","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Noc Folio3","Est. reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#article","isPartOf":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/"},"author":{"name":"Noc Folio3","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/0b6e4f68efbd12d222ac9422766c61eb"},"headline":"How to deploy a microservice architecture using PM2","datePublished":"2019-07-11T10:55:31+00:00","dateModified":"2020-03-26T17:13:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/"},"wordCount":1580,"commentCount":0,"publisher":{"@id":"https:\/\/www.folio3.com\/mobile\/#organization"},"image":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/","url":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/","name":"How to Use Microservice Architecture with PM2","isPartOf":{"@id":"https:\/\/www.folio3.com\/mobile\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage"},"image":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png","datePublished":"2019-07-11T10:55:31+00:00","dateModified":"2020-03-26T17:13:09+00:00","breadcrumb":{"@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#primaryimage","url":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png","contentUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2019\/07\/How-to-deploy-a-microservice-architecture-using-PM2.png","width":1024,"height":560,"caption":"How-to-deploy-a-microservice-architecture-using-PM2"},{"@type":"BreadcrumbList","@id":"https:\/\/www.folio3.com\/mobile\/blog\/how-to-deploy-a-microservice-architecture-using-pm2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.folio3.com\/mobile\/"},{"@type":"ListItem","position":2,"name":"How to deploy a microservice architecture using PM2"}]},{"@type":"WebSite","@id":"https:\/\/www.folio3.com\/mobile\/#website","url":"https:\/\/www.folio3.com\/mobile\/","name":"Mobile App Development Services","description":"","publisher":{"@id":"https:\/\/www.folio3.com\/mobile\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.folio3.com\/mobile\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.folio3.com\/mobile\/#organization","name":"Mobile App Development Services","url":"https:\/\/www.folio3.com\/mobile\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/","url":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png","contentUrl":"https:\/\/www.folio3.com\/mobile\/wp-content\/uploads\/2020\/12\/folio3-mobile.png","width":210,"height":50,"caption":"Mobile App Development Services"},"image":{"@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/0b6e4f68efbd12d222ac9422766c61eb","name":"Noc Folio3","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.folio3.com\/mobile\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/29f05a21b8db20048e7717694b024bbd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/29f05a21b8db20048e7717694b024bbd?s=96&d=mm&r=g","caption":"Noc Folio3"},"url":"https:\/\/www.folio3.com\/mobile\/blog\/author\/noc\/"}]}},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts\/1951"}],"collection":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/comments?post=1951"}],"version-history":[{"count":5,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts\/1951\/revisions"}],"predecessor-version":[{"id":2160,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/posts\/1951\/revisions\/2160"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/media\/2410"}],"wp:attachment":[{"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/media?parent=1951"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/categories?post=1951"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.folio3.com\/mobile\/wp-json\/wp\/v2\/tags?post=1951"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}