Deploy Ruby On Rails on
Ubuntu 16.04 Xenial Xerus

A guide to setting up a Ruby on Rails production environment

This will take about 45 minutes.

Skip all this work and let Hatchbox configure your servers and deploy Rails apps to it.

Check out Hatchbox!

We will be setting up a Ruby on Rails production environment on Ubuntu 16.04 LTS Xenial Xerus.

Since we setup Ubuntu for our development environment, we also want to use it in production. This keeps your application running consistently between development and production. We're using an LTS version of Ubuntu in production because it is supported for several years where a normal version of Ubuntu isn't.

Using Ubuntu LTS in production allows you to continue receiving security updates which is important for your production server(s).

We're going to be setting up a Droplet on Digital Ocean for our server. It costs $5/mo and is a great place to host your applications.

If you sign up with my Digital Ocean referral link, you'll get 2 months ($10) free credit to try it out.

You can use any cloud server hosting company you choose for your Rails application. I've had excellent experience with Digital Ocean and Linode with the servers I have used. If you're looking for alternatives outside the US or otherwise, just google "VPS hosting". A VPS is a virtual private server. It's just like a server you setup at home, only virtualize and running with a suite of other servers in a datacenter.

First, we need to choose which OS to use. We're going to be using Ubuntu 16.04 LTS x64. Your application may require a different OS or version, but if you're not sure this is generally what you should use.

Droplet Image

Since we're using Digital Ocean for our cloud server, the first thing we're going to do is configure a new one. I'm going with the Droplet with 1GB of RAM. You can setup whichever size server you prefer, keep in mind that if you choose a 512MB server you may run into some slowness with a low amount of RAM.

Droplet Size

The next step is to choose your location. Choose one close to you so that you can have better connection speeds.

Droplet Region

Optionally you can add your SSH key into the Droplet so you can SSH in and skip the ssh-copy-id step.

Once Digital Ocean has configured your server, check your email to get your password for the new cloud server.

You should follow the instructions in the email to login via SSH for the very first time and verify it is working.

The first thing we will do on our new server is create the user account we'll be using to run our applications and work from there.

sudo adduser deploy
sudo adduser deploy sudo
su deploy

Before we move forward is that we're going to setup SSH to authenticate via keys instead of having to use a password to login. It's more secure and will save you time in the long run.

We're going to use ssh-copy-id to do this. If you're on OSX you may need to run brew install ssh-copy-id but if you're following this tutorial on Linux desktop, you should already have it.

Once you've got ssh-copy-id installed, run the following and replace IPADDRESS with the one for your server:

Make sure you run ssh-copy-id on your computer, and NOT the server.

ssh-copy-id [email protected]

Now when you run ssh [email protected] you will be logged in automatically. Go ahead and SSH again and verify that it doesn't ask for your password before moving onto the next step.

For the next steps, make sure you are logged in as the deploy user on the server!

Choose the version of Ruby you want to install:

The first step is to install some dependencies for Ruby and Rails.

To make sure we have everything necessary for Webpacker support in Rails, we're first going to start by adding the Node.js and Yarn repositories to our system before installing them.

curl -sL | sudo -E bash -
curl -sS | sudo apt-key add -
echo "deb stable main" | sudo tee /etc/apt/sources.list.d/yarn.list

sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev nodejs yarn

Next we're going to be installing Ruby using one of three methods. Each have their own benefits, most people prefer using rbenv these days, but if you're familiar with rvm you can follow those steps as well. I've included instructions for installing from source as well, but in general, you'll want to choose either rbenv or rvm.

Choose one method. Some of these conflict with each other, so choose the one that sounds the most interesting to you, or go with my suggestion, rbenv.

Installing with rbenv is a simple two step process. First you install rbenv, and then ruby-build:

git clone ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

git clone ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL

rbenv install 2.5.3
rbenv global 2.5.3
ruby -v

The installation for rvm is pretty simple:

sudo apt-get install libgdbm-dev libncurses5-dev automake libtool bison libffi-dev
gpg --keyserver hkp:// --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -sSL | bash -s stable
source ~/.rvm/scripts/rvm
rvm install 2.5.3
rvm use 2.5.3 --default
ruby -v

Arguably the least useful Ruby setup for development is installing from source, but I thought I'd give you the steps anyways:

tar -xzvf ruby-2.5.3.tar.gz
cd ruby-2.5.3/
sudo make install
ruby -v

The last step is to install Bundler

gem install bundler

rbenv users need to run rbenv rehash after installing bundler.

Phusion is the company that develops Passenger and they recently put out an official Ubuntu package that ships with Nginx and Passenger pre-installed.

We'll be using that to setup our production server because it's very easy to setup.

sudo apt-key adv --keyserver hkp:// --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

# Add Passenger APT repository
sudo sh -c 'echo deb xenial main > /etc/apt/sources.list.d/passenger.list'
sudo apt-get update

# Install Passenger & Nginx
sudo apt-get install -y nginx-extras passenger

So now we have Nginx and passenger installed. We can manage the Nginx webserver by using the service command:

sudo service nginx start

Open up the server's IP address in your browser to make sure that nginx is up and running.

The service command also provides some other methods such as restart and stop that allow you to easily restart and stop your webserver.

Next, we need to update the Nginx configuration to point Passenger to the version of Ruby that we're using. You'll want to open up /etc/nginx/nginx.conf in your favorite editor. I like to use vim, so I'd run this command:

sudo vim /etc/nginx/nginx.conf

# You could also use nano if you don't like vim
# sudo nano /etc/nginx/nginx.conf

Find the following lines, and uncomment them:

# Phusion Passenger
# Uncomment it if you installed ruby-passenger or ruby-passenger-enterprise

include /etc/nginx/passenger.conf;

Save and close nginx.conf. Then open /etc/nginx/passenger.conf in your editor to modify the ruby line:

sudo vim /etc/nginx/passenger.conf

# You could also use nano if you don't like vim
# sudo nano /etc/nginx/passenger.conf

And change the passenger_ruby line to point to your ruby executable:

passenger_ruby /home/deploy/.rbenv/shims/ruby; # If you use rbenv
# passenger_ruby /home/deploy/.rvm/wrappers/ruby-2.1.2/ruby; # If use use rvm, be sure to change the version number
# passenger_ruby /usr/bin/ruby; # If you use ruby from source

The passenger_ruby is the important line here. Make sure you only set this once and use the line from the example that pertains to the version of Ruby you installed.

Once you've changed passenger_ruby to use the right version Ruby, you can run the following command to restart Nginx with the new Passenger configuration.

sudo service nginx restart

Now that we've restarted Nginx, the Rails application will be served up using the deploy user just how we want. In the Capistrano section we will talk about configuring Nginx to serve up your Rails application.

Setting up your production database is pretty easy. Make sure to keep in mind that you should use a different password for your production databases.

Depending on what database you want to use, follow the steps related to the database:

Installing MySQL

All you need to do in order to install MySQL is to run the following command:

sudo apt-get install mysql-server mysql-client libmysqlclient-dev

You can use the root user and password set during installation for your database or you can add a new user to MySQL.

Make sure you also create your app's database now. If you're not sure how to do this, follow this guide to create your mysql database. Take note of your database name and password so you can use this when we setup the database.yml file later on.

Installing PostgreSQL

Postgres 9.3 is available in the Ubuntu repositories and we can install it like so:

sudo apt-get install postgresql postgresql-contrib libpq-dev

Next we need to setup our postgres user (also named "deploy" but different from our linux user named "deploy") and database:

sudo su - postgres
createuser --pwprompt deploy
createdb -O deploy my_app_name_production # change "my_app_name" to your app's name which we'll also use later on

The password you type in here will be the one to put in your my_app/current/config/database.yml later when you deploy your app for the first time.

For Capistrano, make sure you do these steps on your development machine inside your Rails app.

The first step is to add Capistrano to your Gemfile:

gem 'capistrano', '~> 3.7', '>= 3.7.1'
gem 'capistrano-rails', '~> 1.2'
gem 'capistrano-passenger', '~> 0.2.0'

# Add this if you're using rbenv
# gem 'capistrano-rbenv', '~> 2.1'

# Add this if you're using rvm
# gem 'capistrano-rvm'

Once these are added, run the following command to generate your capistrano configuration.

cap install STAGES=production

Next we need to make some additions to our Capfile to include bundler, rails, and rbenv/rvm (if you're using them). Edit your Capfile and add these lines:

require 'capistrano/rails'
require 'capistrano/passenger'

# If you are using rbenv add these lines:
# require 'capistrano/rbenv'
# set :rbenv_type, :user
# set :rbenv_ruby, '2.5.3'

# If you are using rvm add these lines:
# require 'capistrano/rvm'
# set :rvm_type, :user
# set :rvm_ruby_version, '2.5.3'

After we've got Capistrano installed, we can configure the config/deploy.rb to setup our general configuration for our app. Edit that file and make it like the following replacing "myapp" with the name of your application and git repository:

set :application, "my_app_name"
set :repo_url, "[email protected]:me/my_repo.git"

set :deploy_to, '/home/deploy/my_app_name'

append :linked_files, "config/database.yml", "config/secrets.yml"
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "vendor/bundle", "public/system", "public/uploads"

Now we need to open up our config/deploy/production.rb file to set the server IP address that we want to deploy to:

# Replace with your server's IP address!
server '', user: 'deploy', roles: %w{app db web}

If you have any trouble with Capistrano or the extensions for it, check out Capistrano's Github page.

Thankfully there aren't a whole lot of things to do left!

Adding The Nginx Host

In order to get Nginx to respond with the Rails app, we need to modify it's sites-enabled.

Open up /etc/nginx/sites-enabled/default in your text editor and we will replace the file's contents with the following:

server {
        listen 80;
        listen [::]:80 ipv6only=on;

        passenger_enabled on;
        rails_env    production;
        root         /home/deploy/my_app_name/current/public;

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;

This is our Nginx configuration for a server listening on port 80. You need to change the server_name values to match the domain you want to use and in root replace "myapp" with the name of your application.

Connecting The Database

One optional thing I would recommend is to remove your config/database.yml and config/secrets.yml git and only store example copies in your git repo. This way we can easily copy the files for setting up development, but our production environment can symlink files on the server so that our production secrets and passwords are only stored on the production server.

First we'll move these files to their example names in the git repo.

echo "config/database.yml\nconfig/secrets.yml" >> .gitignore
git add .gitignore
git mv config/secrets.yml config/secrets.yml.example
git mv config/database.yml config/database.yml.example
git commit -m "Only store example secrets and database configs"
cp config/secrets.yml.example config/secrets.yml
cp config/database.yml.example config/database.yml

You can run cap production deploy to deploy your application, but it's going to fail this first time because we haven't created either of these files on the server which we will do in just a second.

linked file /home/deploy/ does not exist on IP_ADDRESS

One last time, ssh into your server as the deploy user and this time we need to create two files. First is the database.yml that uses the password for the postgres user you created earlier.

# /home/deploy/my_app_name/shared/config/database.yml
  adapter: postgresql
  database: my_app_name_production
  username: deploy
  encoding: unicode
  pool: 5

Now we create secrets.yml. We need to run rake secret on your development machine and take the secret key output of that and paste that in as YOUR_SECRET_KEY on the server.

# /home/deploy/my_app_name/shared/config/secrets.yml
  secret_key_base: YOUR_SECRET_KEY

You can run cap production deploy one last time to get your full deployment to run. This should completed successfully and you should see your new site live! You can just run Capistrano again to deploy any new changes you've pushed up to your Git repository.

Restarting The Site

One last thing you should know is that restarting just the Rails application with Passenger is very easy. If you ssh into the server, you can run touch my_app_name/current/tmp/restart.txt and Passenger will restart the application for you. It monitors the file's timestamp to determine if it should restart the app. This is helpful when you want to restart the app manually without deploying it.


And there you have it, a very long-winded explanation of all the different things you need to do while setting up an application to be deployed. There is a lot of system administration pieces that can expand upon this, but that's for another time. Please let me know if you have any questions, comments, or suggestions!



This is not working on Xenial Xerus because there is no packages for Ubuntu 16.04 in Phusion Passenger repositores yet.


You can try using the older trusty repository for now while they work up on updating their apt repository:

sudo sh -c 'echo deb trusty main > /etc/apt/sources.list.d/passenger.list'

nginx-extras require perlapi-5.20.2, libperl5.20 (>= 5.20.2), passenger (< 5.0.28) wich will not be installed


Yep, i got the same problem here


You guys can remove that passenger repository and install the version directly from Ubuntu. Should be good enough for now, and then once Phusion updates their repo, you can switch back to it so you can continue to get updates.§ion=all


We can't, because nginx from Ubuntus repositories does not have built-in passenger support.


any solution for this issue?


Unfortunetely no solution so far. I'm waiting too ;/


Unfortunately they haven't released a package for xenial yet. It's on their todo list, but they said by June at the latest. That's a long time from now.

Here's how you can install it manually: https://www.phusionpassenge...


Thanks, it's working for me now! :)


Do you remember what you did here? Having trouble getting past this.


Exactly by the instructions in tutorial


After changing database.yml and secrets.yml to examples, whenever I run Rails s for running server. I get error and it complains that it can't find the yml files and server will not get started. What can I do?


Chirs this video is great !!!
would you please publish a similar video with deploy rails on unicorn and nginx with good explain about the config!
thanks )


Edit /etc/nginx/nginx.conf file and uncomment #include /etc/nginx/passenger.conf;
For example, you may see this:
include /etc/nginx/passenger.conf;
after this:
sudo service nginx restart

and final check if passeger work:
sudo /usr/bin/passenger-config validate-install


do you see the message "Restarting nginx nginx" when you type "sudo service nginx restart" ? In my case I don't see it and Chris said that something gonna be wrong if you don't see it.


I see [ OK ]


strange! I am using ubuntu 16.04 and every thing is working correctly but I didn't saw anything like [ok] or "restarting nginx ... [ok]" like Chris does! weird :/


I'm on 14.04 but I enter here because your other question:
"Hi Chris, when I do sudo service nginx restart it doesn't show anything,
you say that this might be an error, I did sudo tail
/var/log/nginx/error.log but I can't see any error there! this is the
output :"


Hi Chris, when I do sudo service nginx restart it doesn't show anything, you say that this might be an error, I did sudo tail /var/log/nginx/error.log but I can't see any error there! this is the output :

[ 2016-07-09 12:46:04.5741 23679/7f3c412f4700 Ser/Server.h:464 ]: [UstRouter] Shutdown finished
[ 2016-07-09 12:46:04.5743 23679/7f3c47f47780 age/Ust/UstRouterMain.cpp:523 ]: Passenger UstRouter shutdown finished
[ 2016-07-09 12:46:04.5939 23674/7f3bb0d6f780 age/Cor/CoreMain.cpp:967 ]: Passenger core shutdown finished
2016/07/09 12:46:05 [info] 23783#23783: Using 32768KiB of shared memory for push module in /etc/nginx/nginx.conf:75
[ 2016-07-09 12:46:05.7251 23790/7f341ddf1780 age/Wat/WatchdogMain.cpp:1291 ]: Starting Passenger watchdog...
[ 2016-07-09 12:46:05.7624 23793/7fdc2184b780 age/Cor/CoreMain.cpp:982 ]: Starting Passenger core...
[ 2016-07-09 12:46:05.7625 23793/7fdc2184b780 age/Cor/CoreMain.cpp:235 ]: Passenger core running in multi-application mode.
[ 2016-07-09 12:46:05.7646 23793/7fdc2184b780 age/Cor/CoreMain.cpp:732 ]: Passenger core online, PID 23793
[ 2016-07-09 12:46:05.8046 23798/7f724a019780 age/Ust/UstRouterMain.cpp:529 ]: Starting Passenger UstRouter...
[ 2016-07-09 12:46:05.8060 23798/7f724a019780 age/Ust/UstRouterMain.cpp:342 ]: Passenger UstRouter online, PID 23798

by the way when I opened /etc/nginx/nginx.conf the first time, I haven't find the lines passenger_ruby and passenger_root


Hi, have the same issue can't find solution in any web.
Did you found something?


Hi! I had that same problem and the solution for me was to comment out this line in my /config/environments/production.rb file:

"config.force_ssl = true"

What was happening was that each time you connected, the rails application forced you to redirect to "https" for SSL but your SSL cert is not setup yet!


Chris, Thanks so much for this tutorial. I followed along and was able to get this all working on a VirtualBox setup. However a problem i encountered was a bundler error. i had to SSH into the server and use 'which bundler' and add that path into the :default_env in deploy.rb
set :default_env, { path: "/home/deploy/.rbenv/shims:~/.rbenv/bin:$PATH" }

My question after this...Is there an easy way to run custom rake tasks, once deployed?



After following this tutorial, I'm still getting the default "Welcome to nginx" page


You'll need to restart nginx again to get the site up and running.


The Capistrano part of this tutorial is quite out of date. See

I'd be happy to help rewrite that part if needed.


Thanks for this very helpful tutorial, everything works as expected, except for my assets... some of my images aren't showing up in the browser, but they get deployed... I´m not sure what to do... I've been googling around and don´t seem to find a solution


Make sure you're using these helpers for your static assets:


Thanks it worked :)

great tutorial btw!!


After installing NGinx it is necessary to set up and activate the firewall - otherwise you won't see even the Nginx start page. See


When I use rbenv and launch "cap production deploy" I get an error: "LoadError: cannot load such file -- capistrano/rbenv". On the local computer I use RVM and I want to set up rbenv on the remote one. Perhaps it is not possible? Do I have to have rbenv on the local computer installed?

Cristian Georgescu

Newbie question here. I followed the tutorial and I have the rails 5 app on server.
I bundle install everything but when trying to start rails (rails s -e production) I get the rails new prompt I need to create a new rails app. Any tips on how to start it or what I might be missing ?


You don't need to run Rails, Passenger will start the app for you automatically, that's why we set it up this way so you don't have to manage running scripts. It's automatic.


I had to Generate RSA SSH Keys to make things work. The command is "ssh-keygen". See


Hi there!

I have a issue here: No Rakefile found (looking for: capfile, Capfile, capfile.rb, Capfile.rb, /usr/lib/ruby/vendor_ruby/Capfile)

What should I do?


You should run it in local


Great tutorial. Everything went well, but when I do cap deploy production, I get the error below. Any ideas? Thank you!

cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as [email protected]: passenger-config exit status: 1
passenger-config stdout: Nothing written
passenger-config stderr: *** ERROR: Phusion Passenger doesn't seem to be running. If you are sure that it
is running, then the causes of this problem could be one of:

1. You customized the instance registry directory using Apache's
PassengerInstanceRegistryDir option, Nginx's
passenger_instance_registry_dir option, or Phusion Passenger Standalone's
--instance-registry-dir command line argument. If so, please set the
environment variable PASSENGER_INSTANCE_REGISTRY_DIR to that directory
and run this command again.
2. The instance directory has been removed by an operating system background
service. Please set a different instance registry directory using Apache's
PassengerInstanceRegistryDir option, Nginx's passenger_instance_registry_dir
option, or Phusion Passenger Standalone's --instance-registry-dir command
line argument.


I had the same issue, I had missed to uncomment "include /etc/nginx/passenger.conf;" and server_name was not proper. after fixing them its working


what is the server_name? ICan have any domain? Thanks


yes I had the same issue, any solutions?


Getting the same issue -- anyone solve?


I had the same issue , anyone knows please

Got same issue. Have tried in two different vps, just the same.


Almost there but when I run `cap production deploy` I get

00:00 rbenv:validate
rbenv: 2.3.1 is not installed or not found in $HOME/deploy/.rbenv/versions/2.3.1


Is cap checking this on my local machine or the server? I have changed the path to just `$HOME/.rbenv` and still get the same issue.


Also getting an error `There are no Phusion Passenger-served applications running whose paths begin with '/home/deploy/app_name'`. app_name is replaced with the name of my app.

Seems there is another user getting this problem as well.


hey Jay, did you end up solving this issue?

Did you end up solving this? Having the same issue.


Thanks Chris for this video! How do we setup password authentication, if we're using this tutorial to deploy a staging version of the site? I've setup everything via this site and yet it's not asking for passwords upon entering the site.


Hmmm, double check that you restarted nginx and that went correctly. If so, it should pick that up.


Maybe I missed it in the tutorial, but I had to authenticate the DigitalOcean server with GitHub (by creating a SSH key from the server). Capistrano deployment failed until I did that, as the server was denied access to the Git repository.


I get a 'Permission denied (publickey) fatal: could not read from remote repo' when I 'cap production deploy'. The same keys are on DigitalOcean and Github. Pushes to github works fine. I can ssh into the digitalocean server as root or deploy users fine too. Anyone know what I've missed?

I'm getting the same prob. Did you find a fix?
Fixed by running 'ssh-add' on local machine.


Hi Chris,
How I can set domain name to my server ip address to input my site domain instead of writing ip address?



Make sure you added yout domain name in /etc/nginx/sites-enabled/default.
After that, for digital ocean, follow these steps:

Hope it helps ;)

Edit: Don't forget to set up DO namespaces at your domain registrar panel. (tutorial link:


Just to confirm, firstly the domain need to buy in godaddy or some similar, correct? I don't think you can do this with Digital Ocean


Yes, correct. You should look for any domain registrar. Some are:
Network Solutions
A Small Orange
Google Domains beta


Hello Chris

I fixed the issue I initally posted about lol. But now when I visit the URL there's no site to visit, it says unable to connect

Great tutorial say I'm trying to deploy a rails 5 app with ubuntu 16.04 etc... On cap production deploy I get the following error on deploy:migrate

INFO [deploy:migrate] Run `rake db:migrate`
DEBUG [15816e11] Running if test ! -d /home/deploy/app/releases/20170313091718; then echo "Directory does not exist '/home/deploy/app/releases/20170313091718'" 1>&2; false; fi as [email protected]
DEBUG [15816e11] Command: if test ! -d /home/deploy/app/releases/20170313091718; then echo "Directory does not exist '/home/deploy/app/releases/20170313091718'" 1>&2; false; fi
DEBUG [15816e11] Finished in 0.306 seconds with exit status 0 (successful).
INFO [64a72276] Running ~/.rvm/bin/rvm default do bundle exec rake db:migrate as [email protected]
DEBUG [64a72276] Command: cd /home/deploy/app/releases/20170313091718 && ( export RAILS_ENV="production" ; ~/.rvm/bin/rvm default do bundle exec rake db:migrate )
DEBUG [64a72276] rake aborted!
DEBUG [64a72276] PG::ConnectionBad: could not connect to server: Connection refused
Is the server running on host "" and accepting
TCP/IP connections on port 5432?
DEBUG [64a72276] /home/deploy/app/shared/bundle/ruby/2.4.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:671:in `initialize'

Do you have any pointers? to make it work can't seem to find similar issue on deployment server

note i tried this it didn't work:



Hi Aziz, could you fix it? I'm running into the same problem =/


Hey! No not yet, does your passenger:restart say there is no "Passenger served application"?


I solved the issue by configuring my postgreSQL to accept TCP/IP connections from my server. Check /etc/postgresql/9.5/main for postgresql.conf and pg_hba.conf for configurantions about this.


Thanks for the tip! I must have a different problem because it's still bugging will figure sth out +1


Thanks for the tutorial Chris!!

I'm just having an issue when trying to set the branch for the repo, it always took master and I'm using the set branch but nothing happens


Hey @disqus_FdxDeiCXJb:disqus! I'm not sure how you've got it setup, but if you set the branch in your Capistrano config, that should do the trick. You can either do it in config/deploy.rb globally (it defaults to master) or inside each of the stages like config/deploy/production.rb. It's usually just set :branch, "mybranch"

All the other config options are listed here:


That's the way I'm doing it, in the config/deploy.rb but when I run cap production deploy, it gets the HEAD last commit on master


# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp } -- try this and ask for the branch, I typed develop, but neither worked
set :branch, 'develop'

0:02 git:check
01 git ls-remote [email protected]:altocustos/custos_api.git HEAD
01 a64ca2f22cfaeee296f994b1475d422b179ec94a -- this is the only commit on master branch
✔ 01 [email protected] 1.825s


Yep your code looks right. I think that git ls-remote is fine because Capistrano actually clones your full repo to the server (all the branches) and then when it does a "git archive branch | tar" command later to make the new release folder, it will grab the branch there. I don't think this step is gonna be the problem, so it might actually be using the right branch.


Gosh!! found the problem, the app was in a folder inside the main dir, and that causes it couldn't find the gemfile and that's why I was assuming that set branch didn't work.

Now I have another problem :( when it tries to precompile the assets it gives me an error, because mi app is a rails 5 api, how can I disable the assets:precompile?


Awesome! :)

I believe for that, you can either override the deploy:assets:precompile task with an empty task, or you can also possibly remove the web role from the server line in config/deploy/production.rb. That may also disable some other things that run on the web role, but I don't remember what those might be so it might be the best solution for an api-only app.


# config/deploy.rb

Did the trick, thanks so much for the help :)



you can create the database.yml same way as you did with secrets.yml. Create an empty file in same place where secrets.yml are and then copy the code from your local copy (ie development env). You have to set the credentials accordning to the ones you have set on production obviously :-)

To create the files (assuming you are connected on server) cd into your shared/config/ folder and then type touch database.yml and touch secrets.yml


i have the following error in the tutorial:

[email protected]:~/deploy_test$ cap install STAGES=production
/home/nicoara/.rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems/specification.rb:2112:in `raise_if_conflicts': Unable to activate capistrano-rails-1.2.3, because capistrano-2.15.9 conflicts with capistrano (~> 3.1) (Gem::ConflictError)
from /home/nicoara/.rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems/specification.rb:1280:in `activate'
from /home/nicoara/.rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems.rb:198:in `rescue in try_activate'
from /home/nicoara/.rbenv/versions/2.2.3/lib/ruby/2.2.0/rubygems.rb:195:in `try_activate'

my gemfile has:
group :development do
gem 'capistrano', '~> 3.7', '>= 3.7.1'
gem 'capistrano-rails', '~> 1.2'
gem 'capistrano-passenger', '~> 0.2.0'
gem 'capistrano-rbenv', '~> 2.1'

my capfile has:
# Capfile
require 'capistrano/rails'
require 'capistrano/passenger'

# If you are using rbenv add these lines:
require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_ruby, '2.4.0'

# Load DSL and set up stages
require "capistrano/setup"

# Include default deployment tasks
require "capistrano/deploy"

what to do?



I'm planning to do a fresh OS installation on my local machine, so I have a question: is there a way to backup my existing ssh keys that I use to login to the server or my repos, or do I have to generate and add a new key in this case? if thats the case I guess all I need to do is to generate the new key on my fresh install and ssh-copy-id to the server again??


Meant to reply sooner, but all your ssh keys are located in ~/.ssh so you can backup that folder and just replace it on your new install to use the same keys.


After getting through the process, when I tried to deploy my project, I kept getting: "Your Ruby version is 2.3.1, but your Gemfile specified 2.4.1"

Logged into the server as deploy, ruby version was 2.4.1. After a lot of troubleshooting, I su'd into root, and found that root had ruby 2.3.1 as it's version.

I figured i must have screwed something up, so I started fresh.... this time watching the output of each command closely.

It seems that the Passenger install (as deploy user) imported ruby 2.3.1... 2.4.1 was already set up under deploy... and this 2.3.1 did not seem to change anything for deploy. However, root, which had no ruby prior to passenger, was now set to 2.3.1.

I've updated root's ruby to be 2.4.1 using the rbenv method as root so that I could get something deployed to practice on... but...

I'm confused as to how and why 2.3.1 got there, and why it's interfering with the deploy command when i try to push an update...


Chris this tutorial is very helpful.
Can i deploy Worpress and Rails both in a server. Like - WordPress for blogging - ( http://blog.URL ) and rails application is deployed to - (http://URL).
Please help me.


Error 403

The passenger_ruby and passenger_root are configured conrrectly. :/

[EDIT] Seem that my passenger is not running correctly. Can anybody help me?


Have you ever find what is the cause of the 403?


Unfortunately, no. I'm using puma now.



Incredibly useful tutorial! For a small bit of extra config and command line hacking, I get to deploy my app to a server I control rather than an option like Heroku. Thanks for putting this together!


I ran into an issue installing this on nginx using rbenv. If you try to cap production deploy and get an error with passenger. Try opening /etc/nginx/passenger.conf and add this to the file.

passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;

to get your specific passenger root type

passenger-config --root


Lovely tutorial... how do you launch the rails console to make a few changes to the application...?


Thank you for this guide! One question I have is how do I load the ruby app if I am not able to use git? When I run cap production deploy it fails trying to read from remote repository because it is calling git and I am not using git. I am new to all of this so sorry for my ignorance.

INFO [01ba63f0] Running /usr/bin/env git ls-remote HEAD as [email protected]

DEBUG [01ba63f0] Command: ( export RBENV_ROOT="$HOME/.rbenv" RBENV_VERSION="2.4.1" GIT_ASKPASS="/bin/echo" GIT_SSH="/tmp/git-ssh-orderentry-producti..." ; /usr/bin/env git ls-remote HEAD )

DEBUG [01ba63f0] fatal: 'HEAD' does not appear to be a git repository

DEBUG [01ba63f0] fatal: Could not read from remote repository.

Diego Polido Santana

Thanks a lot for this post! Simply I use it every new project I have since long time ago. Perfect stack and everything works fine following the instructions.


Could someone help me , iv'e been at this for a week now i get this error when i do a cap production deploy
rbenv: bundle: command not found
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as [email protected]: bundle exit status: 127
bundle stdout: Nothing written
bundle stderr: rbenv: bundle: command not found

SSHKit::Command::Failed: bundle exit status: 127
bundle stdout: Nothing written
bundle stderr: rbenv: bundle: command not found

Tasks: TOP => deploy:updated => bundler:install
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as [email protected]: bundle exit status: 127
bundle stdout: Nothing written
bundle stderr: rbenv: bundle: command not found


Thank you very much for the tutorial. But..I have a problem (ruby 2.4.2, rails 5.1.4). When i run "cap production deploy".
I'm having an error:
00:09 deploy:assets:backup_manifest
01 mkdir -p /home/user/app/releases/20170925040319/assets_manifest_backup
✔ 01 [email protected] 0.047s
WARN Rails assets manifest file not found.
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as [email protected]: Rails assets manifest file not found.

Capistrano::FileNotFound: Rails assets manifest file not found.

Tasks: TOP => deploy:assets:backup_manifest
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as [email protected]: Rails assets manifest file not found.
Google did not help me. Can you help me? Thanks!


Hi Chris, thanks for brilliant tutorial. I followed it about an year ago and every thing worked smoothly. Until Today I saw that the production.log on the server side isn't updating. It seems to be stuck in 23/5 2017 :) and havn't updated since. So I was thinking, Is there maybe something in the production.rb setup or the sim-links that I could alter to get the production.log updated again? please see my question here about this problem:


Any plan on updating this for a webpacker setup? ruby 2.4.2, rails 5.1.4?


Thanks for this great tutorial and My cap deploy went fine without any error and I removed the default nginx page. After I restarted the nginx again I can't see my rails app running. I got This Site can't be reached. Can you help me on this please?

I got Connection refused is the error.


404 Not Found

Hi Chris! I have managed to make it work. But give this setup, how could I make rails db:migrate:reset and rails db:seed to restore a backup?
Hey Juan, I would probably just SSH in and run those commands on the server in the app's current directory. You probably could run Capistrano tasks to do that, but SSH is probably easier.
That was the first approach I tried but using 'deploy' user I don't have enough privileges, and if I switch to 'postgres' user I can't run bundle exec. How do you do that? Thanks

Thanks for the tutorial Chris! Its really help me a lot. But when I was in final step, --->cap production deploy, there is something wrong with it. Can you help me ?
[email protected]:~$ lsdeploy_test[email protected]:~$ cd deploy_test/[email protected]:~/deploy_test$ lsapp  Capfile  Gemfile       lib  public    README.rdoc  test  vendorbin  config   db         Gemfile.lock  log  Rakefile  shared       tmp[email protected]:~/deploy_test$ cap production [email protected]'s password:rvm 1.29.3 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin []ruby-2.5.0ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]00:00 git:wrapper      01 mkdir -p /tmp    ✔ 01 [email protected] 0.044s      Uploading /tmp/ 100.0%      02 chmod 700 /tmp/    ✔ 02 [email protected] 0.043s00:00 git:check      01 git ls-remote [email protected]:sunwenke/deploy_test.git HEAD      01 Warning: Permanently added the RSA host key for IP address '13.250.177…      01 Permission denied (publickey).      01 fatal: Could not read from remote repository.      01      01 Please make sure you have the correct access rights      01 and the repository exists.#<Thread:[email protected]/home/deploy/.rvm/gems/ruby-2.5.0/gems/sshkit-1.16.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):Traceback (most recent call last): 1: from /home/deploy/.rvm/gems/ruby-2.5.0/gems/sshkit-1.16.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'/home/deploy/.rvm/gems/ruby-2.5.0/gems/sshkit-1.16.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as [email protected]: git exit status: 128 (SSHKit::Runner::ExecuteError)git stdout: Nothing writtengit stderr: Warning: Permanently added the RSA host key for IP address '' to the list of known hosts.Permission denied (publickey).fatal: Could not read from remote repository.
Please make sure you have the correct access rightsand the repository exists.(Backtrace restricted to imported tasks)cap aborted!SSHKit::Runner::ExecuteError: Exception while executing as [email protected]: git exit status: 128git stdout: Nothing writtengit stderr: Warning: Permanently added the RSA host key for IP address '' to the list of known hosts.Permission denied (publickey).fatal: Could not read from remote repository.
Please make sure you have the correct access rightsand the repository exists.

Caused by:SSHKit::Command::Failed: git exit status: 128git stdout: Nothing writtengit stderr: Warning: Permanently added the RSA host key for IP address '' to the list of known hosts.Permission denied (publickey).fatal: Could not read from remote repository.
Please make sure you have the correct access rightsand the repository exists.
Tasks: TOP => deploy:check => git:check(See full trace by running task with --trace)The deploy has failed with an error: Exception while executing as [email protected]: git exit status: 128git stdout: Nothing writtengit stderr: Warning: Permanently added the RSA host key for IP address '' to the list of known hosts.Permission denied (publickey).fatal: Could not read from remote repository.
Please make sure you have the correct access rightsand the repository exists.

** DEPLOY FAILED** Refer to log/capistrano.log for details. Here are the last 20 lines:

 DEBUG [2c478043] Running ~/.rvm/bin/rvm default do ruby --version as [email protected]
 DEBUG [2c478043] Command: ~/.rvm/bin/rvm default do ruby --version
 DEBUG [2c478043] ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
 DEBUG [2c478043] Finished in 0.357 seconds with exit status 0 (successful).
  INFO [da9cbc88] Running /usr/bin/env mkdir -p /tmp as [email protected]
 DEBUG [da9cbc88] Command: /usr/bin/env mkdir -p /tmp
  INFO [da9cbc88] Finished in 0.044 seconds with exit status 0 (successful).
 DEBUG Uploading /tmp/ 0.0%
  INFO Uploading /tmp/ 100.0%
  INFO [940c98a2] Running /usr/bin/env chmod 700 /tmp/ as [email protected]
 DEBUG [940c98a2] Command: /usr/bin/env chmod 700 /tmp/
  INFO [940c98a2] Finished in 0.043 seconds with exit status 0 (successful).
  INFO [c7da163d] Running /usr/bin/env git ls-remote [email protected]:sunwenke/deploy_test.git HEAD as [email protected]
 DEBUG [c7da163d] Command: ( export GIT_ASKPASS="/bin/echo" GIT_SSH="/tmp/" ; /usr/bin/env git ls-remote [email protected]:sunwenke/deploy_test.git HEAD )
 DEBUG [c7da163d] Warning: Permanently added the RSA host key for IP address '' to the list of known hosts.
 DEBUG [c7da163d] Permission denied (publickey).
 DEBUG [c7da163d] fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

This isnt the first time here but the big chunk of the tutorial is missing.. Did you cut it out?

Login or create an account to join the conversation.