Serving the same Rails application with different ENV variables - ruby-on-rails

I'm trying to serve the same Rails application with different ENV variables on different ports, i.e.
port 443 with BRAND_SPACE set to "default"
port 444 with BRAND_SPACE set to "somethingelse"
This particular ENV variable affects the styling of the application (think multi tenant) and I want to be able to check the same application with both stylings.
I have the following setup with nginx+Passenger (shortened for readability):
http {
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/ruby;
passenger_max_pool_size 8;
passenger_max_instances_per_app 4;
passenger_max_requests 500;
passenger_show_version_in_header off;
server {
listen 443;
server_name staging.example.de;
root /apps/staging/example/current/public;
passenger_enabled on;
rails_env staging;
passenger_env_var BRAND_SPACE default;
}
server {
listen 444;
server_name staging.example.de;
root /apps/staging/example/current/public;
passenger_enabled on;
rails_env staging;
passenger_env_var BRAND_SPACE somethingelse;
}
}
What now happens is that the ENV variable of the app that was first requested after a restart is used for both applications, i.e. if you request the app on 443 first, then the ENV variable "default" will also be set for the app on 444.
Am I using the configuration wrong or should this be solved in a different way? If so, I'd appreciate any help on this.

The issue reappeared again and I finally found an answer:
https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_app_group_name
Setting this variable will allow you to serve the same application, with the same root under two different domains or server blocks.

Related

nginx - how to create rails app without app name in domain

I'm using nginx with passenger and I wanted to ask, how to create rails app, without showing app name in domain.
Currently I know how to setup nginx configuration with domain like this:
domain.com/app_name
and in the routes file when I create root 'welcome#index'
I still have to type domain.com/app_name to view my controller, but how to make it display welcome controller when the domain is simply domain.com
my nginx configuration looks looks this:
server {
listen 80 default_server;
server_name domain.com;
root /home/username/rails;
location ~ ^/app_name(/.*|$) {
alias /home/username/rails/app_name/public$1; # <-- be sure to point to 'p$
passenger_base_uri /app_name;
passenger_app_root /home/username/rails/app_name;
passenger_document_root /home/username/rails/app_name/public;
passenger_app_env development;
passenger_enabled on;
}
}
when I try to comment out #passenger_base_uri /app_name I got 403 ERROR code.
Any help would be appreciated.
You need to remove the location block, alias, passenger_base_uri, passenger_app_root, and passenger_document_root. Change root to your Rails public directory too. It should look like this:
server {
listen 80 default_server;
server_name domain.com;
root /home/username/rails/app_name/public;
passenger_app_env development;
passenger_enabled on;
}
Try to follow this example of this production nginx config, which also includes some best practices for configuring your server: https://gist.github.com/mikhailov/711913

Nginx Config: one Server name and two Applications

Sorry, this question may have already being answered, but I can't find the answer that will help me.
My situation is like this. We have a interal server, say called "helper.local.company" We currently use it to run a Rails Application. To get there a user just types "helper.local.company/ror_app1_route"
I would like to now install another app on to the server and then alloy the users to only type helper.local.company/ror_app2_route to get to the new app.
my current nginx conf file looks like this:
server {
listen 80 default_server;
server_name helper.local.company;
root /var/www/apps/ror_app1/current/public;
passenger_enabled on;
rack_env production;
}
What would I need to change or add inorder to allow the two rails apps to work with out having to use sub-domains?
Thanks
what keyword you need is 'passenger_base_uri'
reference from:http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_rails_to_sub_uri
The following is a simple example
Suppose that you already have a server virtual host entry:
http {
...
server {
listen 80;
server_name www.phusion.nl;
root /websites/phusion;
}
...
}
And you want your Ruby on Rails application to be accessible from the URL http://www.phusion.nl/rails.
To do this, make a symlink in the virtual host’s document root, and have it point to your Ruby on Rails application’s public folder. For example:
ln -s /webapps/mycook/public /websites/phusion/rails
Next, set passenger_enabled on and add a passenger_base_uri option to the server block:
http {
...
server {
listen 80;
server_name www.phusion.nl;
root /websites/phusion;
passenger_enabled on; # <--- These lines have
passenger_base_uri /rails; # <--- been added.
}
...
}
Then restart Nginx. The application has now been deployed.
You can deploy multiple Rails applications under a virtual host, by specifying passenger_base_uri multiple times. For example:
server {
...
passenger_base_uri /app1;
passenger_base_uri /app2;
passenger_base_uri /app3;
}

Nginx with Phusion Passenger URI routing

This is my Nginx Server config file
server {
listen 80;
location /node {
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/proxy.conf;
}
location /ror {
root /var/www/ror/public;
passenger_enabled on;
proxy_cache off;
proxy_pass_header Server;
}
location / {
root /usr/share/nginx/www;
}
}
This is mostly a 'HelloWorld' setup to test running Node and RoR simultaneously for a REST server.
The issue is that I need to have servername.com/ror forward to /var/www/ror/public, inorder for RoR to respond. I have tried a few configurations, and cannot figure out how to get it to forward correctly. The issue seems to be that the ror URI segment gets passed on to RoR, which causes it to look for that controller, which returns a 404.
The other configuration, changing root to /var/www works as long as I include /ror/public in the URI.
So, is there a way to perform the sub URI routing on the reverse proxy in this manner?
Ok, so I added the rewrite rule.
location /ror {
root /var/www/ror/public;
rewrite ^/ror/(.*)$ /$1 last;
passenger_enabled on;
proxy_cache off;
proxy_pass_header Server;
}
The issue, however, is that now it is serving files from the default root, which in my install is /usr/nginx and is completely ignoring the root inside the location block.
**I appreciate the help. This is my first time with Nginx (Typically an Apache Fiend), so I'm having trouble wrapping my head how it's interpreting these commands.
/ror/a.txt is /var/www/ror/public/ror/a.txt in local fs, so you need to use rewrite rule in location /ror.
Like rewrite ^/ror(.*)$ $1;
I eventually figured it out.
My VHOST Section:
server {
#server_name domain.com;
listen 80;
root /var/www/rails;
passenger_enabled on;
passenger_base_uri /todo;
rails_spawn_method smart;
rails_env development;
proxy_cache off;
proxy_pass_header Server;
location /node {
proxy_pass http://127.0.0.1:8080;
include /etc/nginx/proxy.conf;
}
}
I ended up creating a new directory called rails, and inside of that I created a symbolic link to the public directory of the actual application.
ln -s /var/www/todo/public /var/www/rails/todo
Also, I was not initializing Passenger correctly, which is why it was not responding and giving back errors. This setup is not ideal, considering I now have to manually add each sub URI application, but it works.

How to use different rails_env with nginx, passenger and redmine

I need to have redmine running in combination with nginx, phusion passenger and mysql. Because of the project requires several instances of redmine, which should be realized using different rails_env, I tried to set them in the different server vhosts with nginx.
Example of one vhost:
server {
listen xxxx;
server_name redmine.xxxxx;
root /xxxxx/redmine/public;
passenger_enabled on;
rails_env production;
}
Same goes for the other server vhost, but there server_name is matched to the other domain and rails_env set to internal.
The problem is, that nginx just uses one of both rails_env for both redmine instances, not one for each. Any advice how to use different rails_env with the same application, nginx and phusion passenger?
Thanks
I think you're having the same problem I had. You want to use the same physical directory to host the application instances but you want to interact with the app under different environments (development/production) by using different DNS entries (redmine.development / redmine.production)???
The problem is that passenger recognizes the incoming request as using the rails app found in the directory above root. If you're using the same literal reference for root in multiple nginx configs, passenger will forward the request to the single running instance found in root. i.e., if you start up your development application first, then try to access production via redmine.production, you'll end up interacting with the development environment. However if you start up your production app first, then try to access redmine.development, you'll end up interacting with production.
The answer is to symlink your app's directory for every environment you want to run. Passenger only looks at the literal path to root - if it doesn't match a currently running instance, it'll spawn a new one.
ex.)
Physical root is ~/rails_apps/myserver (where myserver contains app, public, etc.)
Create a symlink called ~/rails_apps/dev.myserver to ~/rails_apps/myserver and another one called ~/rails_apps/pro.myserver to ~/rails_apps/myserver.
Now inside your nginx config, use the symlink locations to the public folder as root.
ex., if symlink /home/user/rails_apps/[dev|pro].redmine points to /home/user/rails_apps/redmine)
server {
listen xxxx;
server_name redmine.development;
root /home/user/rails_apps/dev.redmine/public;
passenger_enabled on;
rails_env development;
}
server {
listen xxxx;
server_name redmine.production;
root /home/user/rails_apps/pro.redmine/public;
passenger_enabled on;
rails_env production;
}
nginx passenger doesnt follow symlink of .../app/public directory many time
because it expect it to be a directory not file
However you can use PASSENGER_APP_GROUP_NAME directive.
like this:-
server {
listen xxxx;
server_name redmine.xxxxx;
root /xxxxx/redmine/public;
passenger_enabled on;
rails_env production;
passenger_app_group_name devlopment;
}
server {
listen xxxx;
server_name redmine.xxxxx;
root /xxxxx/redmine/public;
passenger_enabled on;
rails_env production;
passenger_app_group_name production
}

Running the same Rails app on localhost on different domains and on a different Environment

I want to run the same Rails 3 app at urls: davinci.local.dev:8081 davinci.testing.dev:8082 and with environments development and testing, respectively.
I am using Nginx and passenger. My first attempt was:
server {
listen 8081;
server_name .davinci.local.dev;
root /Users/Nerian/NetBeansProjects/DaVinci/DaVinci/public;
passenger_enabled on;
rails_env development;
#rails_env development
}
server {
listen 8082;
server_name .davinci.testing.dev;
root /Users/Nerian/NetBeansProjects/DaVinci/DaVinci/public;
passenger_enabled on;
rails_env test;
#rails_env development
}
Yet when I browse to said urls, I get to the same deployment. If I first request the testing one, then it is that the app that is served always, whether I browse to davinci.local.dev or davinci.testing.dev. If I first request the development one, then it is that one which is served always.
Both deployments are using the same root app. Is there a way to make this works?
The objective is to serve the same app at different ENV in different domains.
I had a similar problem. I wanted a Rails application (named apparat) to have two nginx instances: example.eu for english version of the site and example.ee for estonian version. They share exactly the same functionality, so it makes sense to have just one code base for it (but I do have to make sure static assets like user-uploaded images won't collide).
server {
listen 80;
server_name example.eu;
root /home/apparat/public;
passenger_enabled on;
rails_env apparat_eng;
}
server {
listen 80;
server_name example.ee;
root /home/apparat/public;
passenger_enabled on;
rails_env apparat_ee;
}
However, similar to above, if I accessed example.ee, I got the example.eu instance of my Rails app. Possibly some quirk in nginx / passenger?
Anyway I got around by making an arbitrary symlink to /home/apparat, for instance
ln -s /home/apparat /home/apparat_eng
ln -s /home/apparat /home/apparat_ee
and changed the nginx config respectively
server {
listen 80;
server_name example.eu;
root /home/apparat_eng/public;
passenger_enabled on;
rails_env apparat_eng;
}
server {
listen 80;
server_name example.ee;
root /home/apparat_ee/public;
passenger_enabled on;
rails_env apparat_ee;
}
So I'm able to trick nginx into thinking these are different directories.
I took a different approach. The development server is served by nginx using passenger while the testing server is started on demand when using rake spec:acceptance.
So nginx.conf is:
server {
listen 8081;
server_name .davinci.local.dev;
root /Users/Nerian/NetBeansProjects/DaVinci/DaVinci/public;
passenger_enabled on;
rails_env development;
#rails_env development
}
Just that.
And in spec/support/custom_env.rb
Capybara.run_server = true
Capybara.app_host = 'http://davinci.testing.dev:8082'
Capybara.server_port = 8082
And that's the magic.

Resources