Server times out after RoR app installation with Capistrano and NGinx

I followed this guide : to setup a RoR application with Nginx+Puma+Capistrano

I was able to setup everything and got capistrano deployments working, but when I access my IP, it keeps loading the page and nothing shows up. The connection basically times out.

Neither the nginx logs, nor the Puma logs (access+error) show anything. both Puma and nginx are running, though.

Ping shows that the server IP is reachable, so I think it has got to do with the webserver running on this droplet

What could be the cause, and how to debug it?

Here’s the nginx configuration:

upstream puma {
  server unix:/home/deployer/apps/<my-app>/shared/tmp/sockets/<my-app>-puma.sock;

server {
  listen 80 default_server deferred;
  # server_name;

  root /home/deployer/apps/<my-app>/current/public;
  access_log /home/deployer/apps/<my-app>/current/log/nginx.access.log;
  error_log /home/deployer/apps/<my-app>/current/log/nginx.error.log info;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;

  try_files $uri/index.html $uri @puma;
  location @puma {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    proxy_pass http://puma;

  error_page 500 502 503 504 /500.html;
  client_max_body_size 10M;
  keepalive_timeout 10;

And here is the deploy.rb file:

# Change these
server 'XX.XXX.XX.XX', port: 22, roles: [:web, :app, :db], primary: true

set :repo_url,        '<my-repo>/<my-app>.git'
set :application,     '<my-app>'
set :user,            'deployer'
set :puma_threads,    [4, 16]
set :puma_workers,    0

# Don't change these unless you know what you're doing
set :pty,             true
set :use_sudo,        false
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/"
set :puma_access_log, "#{release_path}/log/puma.access.log"
set :puma_error_log,  "#{release_path}/log/puma.error.log"
set :ssh_options,     { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/ }
# set :ssh_options,     {:forward_agent => true}
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true  # Change to false when not using ActiveRecord
set :rvm_type, :system

## Defaults:
# set :scm,           :git
# set :branch,        :master
# set :format,        :pretty
# set :log_level,     :debug
# set :keep_releases, 5

## Linked Files & Directories (Default None):
# set :linked_files, %w{config/database.yml}
# set :linked_dirs,  %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

namespace :puma do
  desc 'Create Directories for Puma Pids and Socket'
  task :make_dirs do
    on roles(:app) do
      execute "mkdir #{shared_path}/tmp/sockets -p"
      execute "mkdir #{shared_path}/tmp/pids -p"

  before :start, :make_dirs

namespace :deploy do
  desc "Make sure local git is in sync with remote."
  task :check_revision do
    on roles(:app) do
      unless `git rev-parse HEAD` == `git rev-parse origin/master`
        puts "WARNING: HEAD is not the same as origin/master"
        puts "Run `git push` to sync changes."

  desc 'Initial Deploy'
  task :initial do
    on roles(:app) do
      before 'deploy:restart', 'puma:start'
      invoke 'deploy'

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'

  before :starting,     :check_revision
  after  :finishing,    :compile_assets
  after  :finishing,    :cleanup
# after  :finishing,    :restart

# ps aux | grep puma    # Get puma pid
# kill -s SIGUSR2 pid   # Restart puma
# kill -s SIGTERM pid   # Stop puma

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in Q&A, subscribe to topics of interest, and get courses and tools that will help you grow as a developer and scale your project or business.


I’m far from an expert on this software stack but I’m hoping that I can offer advice that might at least help you to move in the right direction. Perhaps fresh perspective since I’m not in the trenches with you on this issue.

First let’s rule out anything blocking the traffic above the Nginx layer. Doubtful that it is, but you’d hate to dig deeper and find out later that the problem existed at the front door. Run a curl to the server and confirm that headers are received:

curl -I {droplet_ip}

You should get headers from Nginx back confirming what we already suspect, that you can reach Nginx without issue. If not, investigate firewall configuration.

Since you’re not getting an immediate Bad Gateway error, we can reasonably assume that Puma is also up and listening to requests. This combined with no logged Puma errors means that most likely the problem exists beyond Puma. This should leave your Rails application as the last remaining piece for troubleshooting.

So now we have to ask, what is it about the rails application that would cause it to not respond to requests? I would assume that it’s trying to do something which is not working, but not reporting back an error in any meaningful way. From there, I would question if there is a way to enable more detailed logging in the rails app to force it to output what it’s doing and when, so that you can gauge where it might be hanging. Perhaps it’s on an external call that is timing out, for example.

If all else fails, you’re going to have to see if you can capture the PID of a running process of your application and try to strace it. It’s a tough read, but when an application isn’t logging it’s issues then you’re pretty well stuck to trying to debug it in live execution:

Hope that helps :)