7
votes

I'm trying to setup Nginx with Rails and Puma locally on MAC to practice some setups. Ultimately I will have two apps running so Nginx would load balance them.

For Rails and Puma I have the next.

Procfile with:

web: bundle exec puma -C config/puma.rb

puma.rb with:

threads 0,16
workers 1
port 3000
environment "production"
bind "unix:///path_to_my_app/tmp/sockets/puma.sock"
preload_app!

"foreman start" fires up the app

09:28:15 web.1  | started with pid 31442
09:28:16 web.1  | [31442] Puma starting in cluster mode...
09:28:16 web.1  | [31442] * Version 2.13.4 (ruby 2.2.1-p85), codename: A Midsummer Code's Dream
09:28:16 web.1  | [31442] * Min threads: 0, max threads: 16
09:28:16 web.1  | [31442] * Environment: production
09:28:16 web.1  | [31442] * Process workers: 1
09:28:16 web.1  | [31442] * Preloading application
09:28:19 web.1  | [31442] * Listening on tcp://0.0.0.0:3000
09:28:19 web.1  | [31442] * Listening on unix:///path_to_my_app/tmp/sockets/puma.sock
09:28:19 web.1  | [31442] Use Ctrl-C to stop
09:28:19 web.1  | [31442] - Worker 0 (pid: 31444) booted, phase: 0

The application is running and I can access it using 127.0.0.1:3000, 0.0.0.0:3000 or localhost:3000

Now I would like to conect it with Nginx.

I installed Nginx with brew and got version 1.8.0

The nginx.conf is located at /usr/local/etc/nginx and looks like below. I removed some of the commented lines for readability:

worker_processes  1;
error_log  logs/error.log;
events { worker_connections  1024; }

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       8080;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html { root   html; }
    }

    include servers/*;
}

Then the configuration that really should connect with the rails app is inside the servers folder. There I have a file named micro.conf.

upstream app {
    server 127.0.0.1:3000;
    #server unix:///path_to_my_app/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 8080 default;
  root /path_to_my_app/public;
  try_files $uri/index.html $uri @app;

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app;
  }
}

Now, if I go to localhost:8080 shouldn't it end up serving the Rails app? It just goes to the Welcome to Nginx page.

If I go to one of the resources of the Rails app, like localhost:8080/contacts I can see this in the logs:

2015/10/13 10:10:19 [error] 31614#0: *2 open() "/usr/local/Cellar/nginx/1.8.0/html/contacts" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /contacts HTTP/1.1", host: "localhost:8080"

Which shows clearly that it is not looking for the app in the right place.

I get the same result with the socket in the upstream. Any ideas to get this very basic setup working?

1

1 Answers

2
votes

I found the problem. The thing is that the server defined in nginx.conf and in micro.conf were sharing the same port, 8080. So it never went to the intended server because the other was capturing the request first. Setting a different port for each server makes the Rails app "visible". Of course...