A
A
Andrey Caramba2012-06-21 00:17:33
Nginx
Andrey Caramba, 2012-06-21 00:17:33

Nginx + 2 RoR3 applications, one of which is on Sub Uri. How to combine?

Greetings!

Already the brain broke with the following problem.
There are two virtual machines - one with Nginx, the other with a pair of RoR3 applications launched via Unicorn (each application on a separate TCP port). It is necessary that the first application be accessed through a subdomain (like app.domain.tld), and the second one through a sub uri on the same domain (app.domain.tld/app2).
It seems that I found how to do it - in the second application in application.rb I registered config.action_controller.relative_url_root = "/app2".
When typing uri in the browser, everything works correctly and all assets are loaded. But, all links on the page are generated relative to the subdomain's root directory (/), not /app2. That is, for example, it should be /app2/users/login, but it simply forms /users/login.
It seems that the same config.action_controller.relative_url_root is not taken into account when generating links. How can this misunderstanding be corrected?

If this means anything, then these applications are Redmine and GitLab, respectively .
Below are the configs

nginx.vhost.conf
upstream app {
        server IP:PORT1;
}

upstream app2 {
        server IP:PORT2;
}

server {
        server_name app.domain.tld;

        client_max_body_size 8m;
        keepalive_timeout 5;

        access_log  /var/log/nginx/app.domain.tld_access.log;
        error_log   /var/log/nginx/app.domain.tld_error.log;

        # redmine
        location / {
                try_files $uri $uri/index.html $uri.html @redmine;
        }

        location @redmine {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_redirect off;

                proxy_pass http://app;
        }

        # gitlab web interface
        location /app2 {
                try_files $uri $uri/index.html $uri.html @gitlab;
        }

        location @gitlab {
                rewrite /app2/(.*) /$1 break;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $http_host;
                proxy_redirect off;

                proxy_pass http://app2;
        }

        location ~ ^/(conf|includes)/ {
                return 404;
        }

        location ~ /\. {
                deny  all;
        }
}



redmine.unicorn.rb
rails_env = ENV['RAILS_ENV'] || 'production'

app_dir = "/path-to-redmine"
worker_processes 2

user "redmine", "redmine"
working_directory app_dir

listen PORT1, :tcp_nopush => true

timeout 30

pid "#{app_dir}/tmp/pids/unicorn.pid"
stderr_path "#{app_dir}/log/unicorn.stderr.log"
stdout_path "#{app_dir}/log/unicorn.stdout.log"

# Preload Rails App for Performance
preload_app true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end



gitlab.unicorn.rb
app_dir = "/path-to-gitlab"
worker_processes 2

user "gitlab", "gitlab"
working_directory app_dir

preload_app true

timeout 30

listen PORT2

pid "#{app_dir}/tmp/pids/unicorn.pid"
stderr_path "#{app_dir}/log/unicorn.stderr.log"
stdout_path "#{app_dir}/log/unicorn.stdout.log"

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{server.config[:pid]}.oldbin"

  if File.exists?(old_pid) && server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end


It seems that I read that this is easily solved through Passenger, but I also read not very flattering reviews about him, and I already became attached to Unicorn, I love unicorns))

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
dibrovsd, 2012-10-19
@andycaramba

Similar problem.
Decided like this:
1. config/environment.rb
Below

RedmineApp::Application.routes.default_scope = { :path => '/redmine', :shallow_path => '/redmine' }

# Это в конфиге есть
RedmineApp::Application.initialize!

Redmine::Utils::relative_url_root = "/redmine"

Thus, the application expects requests not from the root, but from the /redmine prefix.
And it forms links accordingly, not /users/login, but /redmine/users/login
2. unicorn.rb is not particularly interesting, but, just in case, I will give
orker_processes 2
working_directory "/home/www/redmine/"

preload_app true

timeout 30

listen "/home/www/redmine/tmp/sockets/unicorn.sock", :backlog => 64

pid "/home/www/redmine/tmp/pids/unicorn.pid"

stderr_path "/home/www/redmine/log/unicorn.stderr.log"
stdout_path "/home/www/redmine/log/unicorn.stdout.log"

before_fork do |server, worker|
    defined?(ActiveRecord::Base) and
        ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
    defined?(ActiveRecord::Base) and
        ActiveRecord::Base.establish_connection
end
~                                                                         

3. nginx config We do not need to
proxy requests with the /redmine prefix to the socket via upstream
rewrite, because redmine already expects the /redmine prefix from us (so that the links work) We send
the statics through nginx directly.
upstream unicorn_server { 
        server unix:/home/www/redmine/tmp/sockets/unicorn.sock;         
} 

server {
        server_name docflow.soglasie.ru;

        client_max_body_size 8m;
        keepalive_timeout 5;

        # apache
        location / {
                proxy_pass http://127.0.0.1:8181;
        }

        # redmine
        location /redmine {
                proxy_pass http://unicorn_server;
        }

        # redmine static
        location ~* /redmine/.+\.(ico|css|js|png) {
                rewrite /redmine/(.*) /$1 break;
                root /home/www/redmine/public/;
        } 

}


I do not pretend to be a quality config. This is my first time using nginx.
I don't write startup scripts, etc. It is assumed that you have them.
The main thing is that it works.
Maybe someone will come in handy (even myself, after a while)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question