Deploying rails application - ruby-on-rails

I am trying to deploy a rail application which is in /opt/rails/my_app.
To achieve this I have installed passenger gem and configured nginx using passenger-install-nginx-module. I can access the static welcome page, however when I try some other page like home (which is generated by rails generate controller home index), the browser keep waiting and waiting for response.
This does not happen when I deploy the application using rails s on port 3000.
UPDATE
When I execute passenger-install-apache2-module, I get g++: unrecognized option '-R/usr/local/lib'. I figured that I need to change '-R/usr/local/lib' to 'Wl,-R/usr/local/lib' in order to compile the LoggingAgent properly. Can you please tell me how to change the make file?

Regarding NGINX, it's sounding as though it's a permissions issue on some of your files and/or directories. I would instead move the app to a dedicated /home directory. For example, if you had a user named tester, your nginx.conf would say (the following works for me in Production:
server {
listen YOURIPADDRESSHERE:80; #use :443 if SSL is being used.
server_name YOURFULLDOMAINNAMEHERE;
#uncomment out following if ssl is used.
#ssl on;
#ssl_certificate /etc/ssl/private/YOUR_chained.crt;
#ssl_certificate_key /etc/ssl/private/YOUR.key;
#ssl_session_cache shared:SSL:1m;
#ssl_session_timeout 5m;
#ssl_protocols SSLv3 TLSv1;
#ssl_ciphers HIGH:MEDIUM;
#ssl_prefer_server_ciphers on;
root /home/tester/YOURRAILSAPPNAME/public; # <--- be sure to point to 'public'!
passenger_enabled on;
charset utf-8;
access_log /var/log/nginx/YOURFULLDOMAINNAMEHERE-ssl_access.log;
error_log /var/log/nginx/YOURFULLDOMAINNAMEHERE-ssl_error.log warn;
location /home/tester/YOURRAILSAPPNAME/public/ {
root html;
index index.html index.htm;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Then make sure that your permissions are right (755 for all files, 644 for directories).

In my previous work I spent so much time in process of deploying rails apps to vps productions, with different configurations and gems, and finally before 9 months I discovered hatchbox.io service for deploying rails apps. It was built by Chris from GoRails and believe me it saved me so much time and nerves. This is not advertising but really service works perfect and its not expensive.

Related

Phusion Passenger is currently not serving any applications

I got error like Phusion Passenger is currently not serving any applications.
while trying to restart passenger with passenger-config restart-app command.
I googled but most of the answers were only related with deployment.
I want to restart passenger in the development environment as I am using vhost.
PS. My web server is nginx.
See my comment here.
You need to explicitly specify, where actual Ruby code of a Rails application is located, using passenger_app_root directive, described in Passenger's documentaion.
Without this directive, Passenger will thinck, that actual Ruby code is located in path, specified with root nginx-directive.
Example of a correct configuration file '/etc/nginx/sites-available/app_name':
server {
listen 80;
server_name 188.225.35.216;
passenger_enabled on;
rails_env production;
root /path/to/your/app/public/folder;
passenger_app_root /path/to/your/app/code; # <<< Point Passenger to application code
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
In my case, Passenger was't serving my Rails app, that was deployed with Capistrano.
I had have to specify a value for passenger_app_root like following /var/www/my_app/current.
This will point Passenger exactly, where application code is presented.
I am betting your passenger is running.
If you look at step 3, it hints at what I am talking about.
https://www.phusionpassenger.com/library/install/nginx/install/oss/trusty/
Nginx will take care of passenger for you if it's set up to do that.
Can you try the command in that tutorial and look for passenger processes too ?
sudo /usr/sbin/passenger-memory-stats
Good luck!

Point Nginx to one page of my rails app

I have a domain on namecheap and I created a subdomain for the staging env, nevertheless the point of me doing that because I want to have this domain to point to one page in my rails app but I'm not sure how to do that.
so I went to staging and I nano the file in sites-enabled directive and added this block:
server {
listen 8880;
server_name staging.my_domain_name.com;
access_log /var/www/my_app_name/current/log/access.log;
error_log /var/www/my_app_name/current/log/error.log;
root /var/www/my_app_name/current/public/;
passenger_ruby /home/deploy/.rbenv/versions/2.1.0/bin/ruby;
passenger_enabled on;
rails_env staging;
rails_spawn_method smart-lv2;
passenger_min_instances 1;
# Maintenance
error_page 404 /404.html;
error_page 403 /404.html;
location = /404.html {
internal;
}
}
so for the root I tried to change the path to my view path
/var/www/my_app_name/current/app/views/pages/page_name.html.erb;
I also tried to add the link as it is
I'm not sure how to do this and I'm still new in DevOps
I tried to look for how to make Nginx point to one page in my rails app
Note: It listens to 8880 because i have varnish server who listen to port 80
Any help would be highly appreciated.
Thanks.

nginx and passenger to run my rails application

I'm new to Rails and trying to deploy my rails app (which runs perfectly on my computer using rails server) on to a server.
My server has nginx and passenger both installed and working fine. However, when I change the nginx config file at /opt/nginx/conf/nginx.conf as follows
....
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/ruby1.9.1;
....
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /home/path_to_my_app/public;
index index.html index.htm;
}
passenger_enabled on;
}
it doesn't work. I'm not able to call my rails code. It keeps saying 404 error.
I restarted the nginx using service nginx restart which returned OK, but still no luck.
Can anyone tell how to debug this. Where should I check what all applications my passenger is running? What is the part I'm missing?
EDIT: I'm following this documentation very closely
It seems that there is no /home/path_to_my_app/public directory.
In Passenger version 5.0.7 directory access has been changed. Now if root directory doesn't exist it falls back to nginx to search index.html and gives 404 error if there is now such file.
[Nginx] The Nginx module now looks for index.html if the path ends in
/ so that it works intuitively, without needing to use try_files.
https://blog.phusion.nl/2015/04/29/passenger-5-0-7/
If your server log says that passenger agents are online and if you run sudo passenger-status and see your application listed, then it would appear the agent is setup correctly.
Are you trying to access the site using localhost? If you're trying to access it from outside the server, you'll need to set server_name to either your domain or an IP address (and restart nginx after any changes). If you run curl http://localhost on the server, do you see the html from your site, or just another 404?
"location /" means all the HTTP request will be handled by this location's handler but there isn't one so you will get "404 not found". I guess you mean that your home page is index.html so change "location /" to "location =/" will fixed your problem.
update
server {
listen 80;
server_name localhost;
root /path/to/public;
passenger_enabled on;
}
There is no need add location for simple app.

Rails 3.2.x - No production log entries on an ubuntu, nginx, unicorn setup

On an ubuntu, nginx, unicorn setup the only production log entries I see are from command line commands such as deployments and migrations. I am getting no entries from the website activity at all.
I have read up on this bug report https://github.com/rails/rails/issues/4277#commit-ref-b332877 and I have tried adding
Rails.logger.instance_variable_get(:#logger).instance_variable_get(:#log_dest).sync = true if Rails.logger
to an initializer as suggested but that just gives me an error indicating that sync is nil whenever I try to run anything at all
I have the same issue on rails v 3.2.1 and 3.2.9
Any ideas how I can get the log output?
Just a guess. Is it possible that your ruby server runs under a user which has no permissions to write to log the file? Check the server console (if it is available) for warnings.
Finally solved this
Firstly I believe (I could be wrong and stand to be corrected on this) that at the time of asking this question that there were bugs in the unicorn gem that meant log entries were not being flushed see this report for further info on this particular issue https://github.com/rails/rails/issues/4277
I'm using the latest unicorn gem and all is fine now but a quick note on the unicorn config file and other reasons why you may not see production log entries for an nGinx/Unicorn setup
1) nGinx can return a 500 error (if you have your nginx config set up to do this) if it is unable to connect to your web server. i.e. unicorn has failed to start up.
Obviously if unicorn is failing then your rails is not running and you will be hunting down rails log entries that just won't exist.
If this is the case then check you unicorn config to see where you are writing unicorn errors to. My unicorn.rb file looks similar to this
root = "/home/some_user/some_app/current"
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.log"
stdout_path "#{root}/log/unicorn.log"
Note that I am directing both error and normal unicorn log entries to the same log file. The standard is to use different log files but I just find it simpler for me to have only one unicorn log file to have to look through.
The reason why you may be seeing 500 error pages instead of the bad gateway error that you would normally see if your web server is not running is that you may have the nginx.conf file set to serve static error pages from your app, so you may have something like this
server {
listen 80;
server_name my_domain_name.com;
root /path_to_my_app_root/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://ff1;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
The error_page 500 502 503 504 /500.html; line tells nginx to serve your apps static 500.html page instead of the bad gateway nginx page if your server is not running. That's cool but it is confusing if you don't take into account that a rails 500 page is not necessarily going to give you production log entries.
To sum up. If you are seeing your apps 500.html page and you are seeing no entries in your production.log to help you track down the issue just remember to check the unicorn error log file s defined in your unicorn.rb config to check what, if any, reason is being given for the server failing to start up.

How do I get Nginx and Phusion Passenger to maintain sessions between two Rails instances?

I'm using Nginx with Phusion Passenger to run a Rails app on an EC2 CentOS machine.
I have a pretty standard set up with Nginx, Rails, Phusion Passenger and SSL (I think). My nginx.conf is below. So far it has worked out fine except that every time two requests hit the server at the same time, a new Rails instance is created to serve the second request.
The problem is that once the second request is directed to the newly created Rails instance, it loses the authenticated session from the original Rails instance, resulting in errors. My sessions are stored in memory.
As a workaround, I've set passenger_max_instances_per_app to 1 so on new Rails instances are created, but this is only a temporary fix.
Does anyone know how to make Nginx maintain the same session for requests from the same source? I might be missing something obvious here.
Thanks!
worker_processes 1;
events {
worker_connections 1024;
}
http {
...
passenger_pool_idle_time 0;
passenger_max_instances_per_app 1;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# this server isn't rails enabled.
# will redirect all traffic to https
server {
listen 80;
server_name example.com;
rewrite ^ https://www.example.com$request_uri permanent;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# HTTPS server
# - by default everything is served by https
server {
listen 443;
server_name www.example.com;
root /rails/root/public;
passenger_enabled on;
rails_env production;
ssl on;
ssl_certificate /path/to/cert/www.example.com.crt;
ssl_certificate_key /path/to/cert/www.example.com.key;
ssl_session_timeout 5m;
}
}
We generally have passenger_max_pool_size 2; unless we leave it out entirely (taking the default setting) and the two settings you're specifying, passenger_pool_idle_time and passenger_max_instances_per_app we also leave to the default.
The session key should be kept in a cookie so Rails can look it up between requests. Assuming that's working properly, the problem is that multiple Rails instances aren't sharing memory (feature, not a bug - they're processes, not threads) and therefore don't share session data. Try moving your session information into ActiveRecord:
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rake db:sessions:create")
ActionController::Base.session_store = :active_record_store
(the above code is in config/initializers/session_store.rb)
That way, because the data store is accessibly to multiple Rails processes, they should all have access to the same pool of active sessions.
For better performance, you should avoid :active_record_store and use memcached instead
config.action_controller.session_store = :mem_cache_store

Resources