You have a Node.js project in your local machine but you don't know how to deploy it to your remote server or you use old fashioned way by copying the contents from your computer to the remote server using FTP?
Well, you can automate this process and make your life easier using PM2 *insert hooray gif here*
PM2 is a Process Manager for Node.js. It's like Task Manager in Windows and Activity Monitor in macOS.
You can -including but not limited to- manage your application, scale, start and stop. But the most important feature we want is deploying.
In this post, we will learn how to deploy our application to our remote server and run/build it with a single console command.
First, we obviously need a project.
We create a folder and cd into it.
mkdir pm2-deploy; cd pm2-deploy
Then we initialize the folder as a node project.
npm init -y
We can then go ahead and install
express to serve static files in node environment.
npm i express
And we need to create a JS file to write our code that will serve the folder
public which we also need to create.
I have created
index.js in the root directory. You can rename it whatever you want but don't forget that you need to change the
main field in the
package.json file also.
We also need an HTML file to be served in that public folder.
Here's my index.js
express is serving a static folder named
public and its contents in port 3000; Nothing fancy here.
index.html we do nothing special.
Now we can use
We should see the console.log output which is
PM2 Project is now live @ localhost:3000.
We can check if that's working by going to that port. Go to
localhost:3000 in the browser, If you see
YAY! that's great.
We need to install PM2 npm package globally. We can install it by using
npm i -g pm2
Now onto Step 3!
We cannot have a CI/CD without a version control system, right? So we need to push our project to a git service. I will use Github for that.
When you create a git repo you will see the necessary instructions on how to push an existing project.
But here are the necessary commands, just in case:
git init git remote add origin firstname.lastname@example.org:<your_github_username>/<your_repository_name>.git git add . git commit -m "Initial Commit" git branch -M main git push -u origin main
Note: I strongly recommend using SSH Connection instead of using HTTPS for Github. Your life will get better and securerer :)
In this step, I won't go into the details of how to create/reserve a virtual remote machine but keep in mind that I am using Ubuntu on an EC2 (AWS) machine.
First, we need to connect to the remote machine using SSH
ssh -i path_to_key_file remote_username@remote_ip
I assume you have already done nvm, npm installations, if not you can go ahead and check the nvm repo here: https://github.com/nvm-sh/nvm#installing-and-updating
One important thing to do here. We need to move the lines that were added by nvm to our .bashrc file to the top. Your system may be using .bash_profile or something else. Just pay attention to the output of the nvm installation.
These are the lines we need to move. Open your favorite editor and move them to the top of the file.
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
After saving and exiting the file we can install PM2 here too as we did in Step 2.
npm i -g pm2
After the installation
will give you a simple instruction on how to make PM2 start automatically every time your remote system reboots. I strongly recommend doing that.
Now that we installed PM2, we need to create an SSH key and add it to Github.
In the remote machine, you can go ahead and type
ssh-keygen -t ed25519 -C "<your_github_email>"
Further reading on how to create ssh key https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
The keygen will ask you the name of the key. If you want to change it (I strongly advise you not to do that) you need to give the full path here.
You may just hit Enter when asking for password.
After creating the key we need to copy the contents of the public key.
Go ahead and copy the text you see starting with
ssh- and ending with your e-mail (included).
Then go to https://github.com/settings/keys while logged in to Github then click
New SSH Key button. You can give a title and paste the copied text into the key field.
We now have given authorization to our remote machine to connect to our Github. But we need to connect to Github just once to mark the connection trusted in our remote machine. To do that we can clone the repository into the remote machine.
git clone email@example.com:T410/pm2-deploy.git
Of course, it will be your username and your repo name.
The console will ask you if you want to continue connecting. Type
yes end hit Enter.
Note: We cloned the repo into the user folder. /home/ubuntu for me. Now the full project path is
/home/ubuntu/pm2-deploy. We will use this path to update the
ecosystem.config.jsfile in the next step.
And now we are good to close the remote connection to the server.
Now that we have a remote server up&running and have already pushed the project into our repository, we need to properly configure the
ecosystem.config.js file to tell PM2 where our project is, what to do with that, and where to push that.
The file will look like this:
Notice there are 2 sections we are exporting:
name field in the
apps section is the name of our project which will be shown in PM2 process list.
script field is the script that PM2 will run when we deploy the project to the remote server. In this case, it will be the same as the
main field in the
The rest of the fields are pretty self-explanatory.
useris the username that you use to connect to the remote server using SSH
hostis the IP of the remote server
pathwhere do you want your project to be deployed in your remote server? Remember we already cloned the repo into our remote server. We can go ahead and write that path here
repois the repository URL in a format like
refis the reference branch. Which branch we want the remote server to pull
keyis the LOCAL PATH of the key that we use to connect our machine using SSH
"post-deploy"takes commands which will be run at the remote machine after pulling the repo from Github
We have configured our machine and PM2. We can now deploy our project to the remote machine.
Before deploying we need to commit and push the changes we have made. After that, for the first run, we need to tell PM2 that it needs to setup the project.
pm2 deploy ecosystem.config.js production setup
With this command PM2 connects to the remote, clones the repo from Github. We can now deploy the project.
pm2 deploy ecosystem.config.js production
Now you are asking yourself: Now what?
Well, we didn't set up a server like nginx but we can test if the project is working or not with
curl. Of course, we need to connect to the remote machine before doing that.
If you see the index.html output on the screen that's great news! You have done it!
And also you can list the apps PM2 running with this command
We made great progress here. We learned how to deploy our project with just one command.
Here's the sample Repo:
This is a sample project that demonstrates how to configure
ecosystem.config.js file for PM2 made for this tutorial
I know I didn't tell you how to install nginx and serve the port we are using for our project but I will definitely do that in the near future and update here.
If you have any issues with anything, feel free to tell me what's wrong on the comments section.