Reputation: 3802
I have a rails app running on puma and nginx. I launch nginx with sudo service nginx restart
then puma/rails with rvmsudo rails server -p 80
This is my error:
`initialize': Address already in use - bind(2) for "localhost" port 80 (Errno::EADDRINUSE)
This error only occurs when nginx is already running.
The full error is:
$rvmsudo rails server -p 80
=> Booting Puma
=> Rails 4.2.4 application starting in development on http://localhost:80
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma 2.14.0 starting...
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:80
Exiting
/home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/puma-2.14.0/lib/puma/binder.rb:233:in `initialize': Address already in use - bind(2) for "localhost" port 80 (Errno::EADDRINUSE)
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/puma-2.14.0/lib/puma/binder.rb:233:in `new'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/puma-2.14.0/lib/puma/binder.rb:233:in `add_tcp_listener'
from (eval):2:in `add_tcp_listener'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/puma-2.14.0/lib/rack/handler/puma.rb:33:in `run'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/rack-1.6.4/lib/rack/server.rb:286:in `start'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/railties-4.2.4/lib/rails/commands/server.rb:80:in `start'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:80:in `block in server'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:75:in `tap'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:75:in `server'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/railties-4.2.4/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /home/my-user-name/apps/my-web-app/shared/bundle/ruby/2.1.0/gems/railties-4.2.4/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Any help on how to get nginx to allow puma to talk to it would be very appreciated.
EDIT 1 nginx.conf
upstream puma {
server unix:///home/my-user-name/apps/my-web-app/shared/tmp/sockets/my-web-app-puma.sock;
}
server {
listen 80 default_server deferred;
listen 443 ssl;
# server_name example.com;
ssl_certificate /etc/ssl/mysite/mysite.com.chained.crt;
ssl_certificate_key /etc/ssl/mysite/mysite.key;
root /home/my-user-name/apps/my-web-app/current/public;
access_log /home/my-user-name/apps/my-web-app/current/log/nginx.access.log;
error_log /home/my-user-name/apps/my-web-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;
}
Upvotes: 1
Views: 1873
Reputation: 623
In your puma.rb file you should remove the line about the port. Since you are already using a sock in the configuration, there is no reason to run puma on a tcp port too.
When you start puma with:
puma -C config/puma.rb
you should only see "Listening on unix:", not on tcp:
In a nutshell, you should run puma on a unix socket and not on a tcp port too. Just comment the port directive.
Once you do that, it should work. And by the way, you should be permissive on selinux because selinux will disable the socket and you will end up seeing the message "403 Forbidden"
Upvotes: 3
Reputation: 3999
Actually, let me answer this without requesting your nginx configuration. Your setup works like this:
So let's look at a generic nginx configuration that will tell us how to listen on port 80 and forward all requests to an application running on port 3000:
# our http block to handle HTTP traffic with nginx
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# NGinx Server Configuration
server {
listen 80; #listen on port 80
server_name my.domain.com; # which domain we are listening for.
# Add some basic auth
# Remove this if not needed.
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
# Set up the location to map all requests to the Ruby App
location / {
proxy_pass http://127.0.0.1:3000;
access_log off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Now you need to do 2 things:
Hope this explains how the 2 work together and what you need to change in your file to help them communicate.
basically: if nginx claims port 80, puma cannot claim it and needs to run on a different port, letting nginx reroute all traffic to that port and back.
Upvotes: 5