Server times out after RoR app installation with Capistrano and NGinx

Posted April 14, 2019 3.1k views
Ruby on RailsNginxUbuntu 18.04

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

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.

Submit an Answer
1 answer


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 :)


  • Thanks so much, @jarland !

    The curl gave me:

    curl: (7) Failed to connect to port 80: Operation timed out

    I wonder if it has to do with ufw firewall rules?
    I didn’t touch them, though