Serious Node.js Deployments using Capistrano & Forever

Posted on October 14, 2014 in tutorial, capistrano, node, javascript

Deploying with Capistrano is actually quite easy. The problem isn't so much with the software, but rather finding an updated guide for Capistrano 3. In this guide I hope to set you up with Capistrano on your local environment, explain a bit about SSH, and show you how to setup your server.

This guide assumes a very basic understanding of the command line and assumes you have a remote server with sudo or root access.

Security Note: The following guide is meant for demonstration purposes. Please read and research proper file permissions, group policies, and other security topics for your production server.

Installing Capistrano

In a fresh Terminal or Command Prompt, type:

gem install capistrano

Note for Windows Users: Unless you've done Ruby development, you're most likely going to need to install Ruby and RubyGems. The easiest way to do so is to use the RubyInstaller for Windows.

Configuring Your Local Environment

First, let's create a new SSH key to use your server. On your local environment, run the following commands.

# Navigate to your .ssh folder
cd ~/.ssh

# Generate a new RSA key, follow instructions on screen
# It's best to name your key something like 'deploy_rsa'
ssh-keygen -t rsa -C ''

Now, create ~/.ssh/config and paste in the following:

Host my.ip.address
    HostName my.ip.address
    User deploy
    IdentityFile ~/.ssh/deploy_rsa

Finally, copy the EXACT output of your new public key, you can use cat to print the key to Terminal.


Now that we have an SSH key to use, let's configure our server to use it.

Configuring Your Server

In order to run a Node.js application in a production environment, we're going to need to need a process to boot it up with.

Generally, when you develop on your local machine, you start your application by running npm start or node server.js. The preferred way to do this on production, however, is through some sort of script manager, such as Forever.

Note on Servers: Setting up your server should generally be the same across most nix systems. In this setup, I'm using a Digital Ocean droplet running Ubuntu 14.04.1 however, some instrustions may vary.*

Start by logging into your server, it's best to use root until we setup our deploy user.

# SSH into the server
ssh root@my.ip.address

Let's get some basic packages out of the way. Start by installing Node.js, NPM, and Forever.

# Install Node.js and NPM
apt-get install nodejs npm

# Install forever
npm install -g forever

Cool, now let's setup a new user to securely deploy with. For the sake of simplicity, we're going to call our new user deploy. The only job of this user will be to SSH into the server, grab the latest copy of our code and run any necessary commands to start or restart our application.

# Add a new 'deploy' user, follow instructions on screen
adduser deploy

# Lock the new user's password, forcing us to use SSH
passwd -l deploy

# Create the deploy user's .ssh/ folder
mkdir -p /home/deploy/.ssh

Let's create an authorized_keys file for the deploy user and paste in our public SSH key.

Create /home/deploy/.ssh/authorized_keys using your favorite editor.

vim /home/deploy/.ssh/authorized_keys

Now, paste in the contents of your public key. I've appreviated the below for simplicity and security.

ssh-rsa AAA...........a/cV deploy@my.ip.address

Great! One last thing to fix. We need to make sure that our authorized_keys file is set to permission 0600 and our .ssh/ directory is permission 0700. We can easily do this by running:

# Change the owner for the .ssh/ directory
chown deploy:deploy -R /home/deploy/.ssh

# Change the .ssh/ permission
chmod 0700 /home/deploy/.ssh

# Change the authorized_keys permission
chmod 0600 /home/deploy/.ssh/authorized_keys

At this point, we should be able to SSH into our server using our new deploy user. To test this out, exit the server and try to login.

# Logout of the server
# Login as deploy
ssh deploy@my.ip.address

If all goes well, you should now be logged in!

That's it for now. Let's jump back to our local machine and begin configuring our application. We'll come back to our server in a bit to finish up.

Setup Your Application

Let's get your application ready for deployments. For this example, I'm going to setup and deploy the code for Node-Capistrano. Feel free to clone and follow along with the source code.

# Navigate to our application
cd /path/to/my/project

# Init Capistrano
cap install

This should create a bunch of files in your project directory, most notably Capfile and a config/ folder. Let's begin by opening up config/deploy.rb and changing some key variables.

# config/deploy.rb

# Change the application name
set :application, 'node-capistrano'

# Change the repo url, must use ssh
set :repo_url, ''

# Uncomment deploy_to and change to the correct path
set :deploy_to, '/var/www/node-capistrano'

# Change the restart function to run "forever"
desc 'Restart application'
task :restart do
  on roles(:app), in: :sequence, wait: 5 do
    execute "forever start #{release_path.join('server.js')}"

Let's keep it simple for now. We'll tackle configuration in a bit but for now, let's move onto config/deploy folder.

The deploy folder contains two files by default, production.rb and staging.rb. These should both serve as boilerplates should you decide to add more servers or environments to test on. For now, paste the contents below into config/deploy/production.rb.

role :app, %w{deploy@my.ip.address}
server 'my.ip.address', user: 'deploy', roles: %w{web}

And that's it!

To test out our deploy mechanism, try running the following on your local machine.

# Deploy using Capistrano
cap production deploy

Success! You can see a working demo of this in action by visiting

Thoughts on Git

As the rule goes, since the Capfile and config/ folder contain no real sensitive information, feel free to commit them to Git as there is nothing potentially harmful in them. If you decide to store plaintext passwords or anything else that could compromise your server, then it is recommended that you leave these files outside of your repository.

Further Reading

This article should have covered the basics for deploying a web application using Capistrano and Node.js.

While we covered a lot, there is still a LOT of information we did not such as setting up configuration, databases, shared files, linked folders, and more.

Stay tuned for my next article which should cover such topics, in the meantime post a comment below for any thoughts or questions you might have.


Thomas Lackemann :)


Tom is the founder of Astral TableTop. He's a homebrewer, hiker, and has an about page. Follow @tlackemann on Twitter for more discussions like this.