Apache won't server static assets for rails app - ruby-on-rails

I'm trying to configure my apache server for serving static assets from my rails app. I already tried the suggested configurations but my assets still aren't shown and when trying to access them directly I just got an rails error that no matching controller was found but the asset stuff should be handled by apache directly I think.
My apache configuration looks like this:
<VirtualHost *:80>
ServerName xxx
DocumentRoot /home/xxx/test/public
PassengerEnabled off
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
ProxyPass / http://127.0.0.1:9292/
ProxyPassReverse / http://127.0.0.1:9292/
</VirtualHost>
Did I missed something?

I used,
RAILS_ENV=production bundle exec rake assets:precompile
To make it all work right, I added this to config/application.rb...
module MyApp
class Application < Rails::Application
.
.
config.assets.precompile += ['custom.css']
config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)
.
.
end
end
(I had created custom.css.scss. But Rails did not recognize .scss, as you see above.) I assume that all your assets are appearing in public/assets folder after precompile. I don't understand what you are doing with LocationMatch, pardon my ignorance. Further more, I did not use port 80. I used 8000. Not sure if that makes a difference.
Also, there's a setting in config/environments/production.rb,
# Disable Rails's static asset server (Apache or nginx will already do this).
config.serve_static_assets = false

This is directly from the Rails Asset-pipeline documentation regarding the Apache server:
http://guides.rubyonrails.org/asset_pipeline.html
4.1.1 Far-future Expires Header
Precompiled assets exist on the file system and are served directly by your web server. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add those headers.
For Apache:
# The Expires* directives requires the Apache module
# `mod_expires` to be enabled.
<Location /assets/>
# Use of ETag is discouraged when Last-Modified is present
Header unset ETag
FileETag None
# RFC says only cache for 1 year
ExpiresActive On
ExpiresDefault "access plus 1 year"
</Location>

Related

How to configure Phusion Passenger X-frame options?

I'm trying to iframe a site I built (using Rails) and deployed on an ubuntu instance on AWS using Phusion Passenger.
I looked more into it and found that I need to change my X-frame options, a HTTP header from 'SAME ORIGIN' to 'ALLOWALL'. I already added this line into my config/application.rb file and my config/environments/production.rb
config.action_dispatch.default_headers.merge!({'X-Frame-Options' => 'ALLOWALL'})
Even then, when I open my site, I still get these settings in my Network Headers:
Status:200 OK
Transfer-Encoding:chunked
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Powered-By:Phusion Passenger 5.0.11
This leads me to believe that there's a Phusion Passenger config file somewhere that I need to change the X-Frame-Options for. Any clues or help would be great, thanks!
X-Frame-Options header should be set in your vhost (usually Apache or Nginx). For security reasons, if possible, only allow HTTPS whitelisted domains and whitelisted paths.
<virtualHost *:443>
# ... Host and Passenger configuration ...
<Location "/your-iframable-path">
Header always set X-Frame-Options "ALLOW-FROM https://domain-using-iframe"
</Location>
</virtualHost>
I had the same problem. After trying for a long time, I found the solution to it.
Passenger uses a template for it's nginx configuration. When starting passenger, you pass the template to it using the --nginx-config-template parameter.
Now, to configure the X-Frame-Options header for passenger, simply edit the template file. Add the following line under the http { block of the template file:
add_header X-Frame-Options "SAMEORIGIN";
And make sure to run
sudo service passenger restart
To make the changes go live.
:)

Images are not loading on production

I'm deploying a Rails app to Digitalocean. I'm working with Apache and Passenger. I was able to run my app locally in production and worked fine. I had the same problem on localhost but did the following things to make it work. Locally I work with Webrick server and in Ubuntu with Apache.
Installed these gems:
therubyracer
execjs
I added this to production.rb
config.serve_static_files = true
config.assets.compile = true
config.assets.precompile = ['*.js', '*.css']
Then I did
RAILS_ENV=production bundle exec rake assets:precompile
I tried the same for production in Ubuntu and everything seems fine but the images.
This is what I have in /etc/apache2/sites-available/metalmind.com.co.conf
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin something#hotmail.com
ServerName metalmind.com.co
ServerAlias www.metalmind.com.co
DocumentRoot /home/luisjar/Metalmind_2/public
<Directory "/home/luisjar/Metalmind_2/public">
Options All
AllowOverride All
Require all granted
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
I appreciate any help here.
For images to load in production , you need to check certain things -
1) What's the url being generated where you see no image loaded (Use firebug to see the url path)
2) Where are you storing your images , is it under images or under public folder .
3) Have you precompiled you assets for production using this command (rake assets:precompile RAILS_ENV=production)
Also , in cases like these logs are quite helpful too .

CSS doesn't load in production - everything fine in dev (Rails 4.1, Capistrano 3; bootstrap), update: nginx config issue

Problem is as follows: Everything works fine in development, but when I deploy my rails app to production, the site works in plain html, but CSS (bootstrap) doesn't get loaded (JS probably also not).
Sorry, I looked for 2 days at ~15 possible solutions and could not make it work...
Update: After following #rich-peck's advice, it looks like it's a server issue. Updated with nginx config
My setup:
Ruby 2.1.2, Rails 4.1
Rbenv
mysql2 as db
Bootstrap 3
Ubuntu 14.04 on Server with nginx and passenger
Capistrano 3 for deployment
Config as follows - production.rb:
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = true
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.assets.version = '1.0'
config.log_level = :info
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/
config.i18n.fallbacks = true
config.active_support.deprecation = :notify
config.log_formatter = ::Logger::Formatter.new
config.active_record.dump_schema_after_migration = false
Capfile:
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/rbenv'
set :rbenv_type, :user
set :rbenv_custom_path, '/home/deploy/.rbenv/'
set :rbenv_ruby, '2.1.2'
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
in application.rb:
...
# Enable the asset pipeline
config.assets.enabled = true
...
application.css.scss:
/* ...
*= require_self
*= require_tree .
*/
#import "bootstrap";
#import "custom";
#import "exchange_rates";
#import "contacts";
This is what I tried (among many others):
# on dev machine and server /current:
RAILS_ENV=production bundle exec rake assets:precompile
see Link Custom CSS and Javascript to Rails After Deployment
in configs:
config.serve_static_assets = true # tried false
config.assets.compile = false # tried true
see rails application doesn't load css/js/images in production-environment
production.log doesn't throw any errors, except for pages with js.
Also read a lot about the Rails Asset Pipeline and nginx server setup, but couldn't figure it out... Any help would be greatly appreciated!!
Update: nginx server config
Originally, I followed the very helpful and clear deploy tutorial at gorails: https://gorails.com/deploy/ubuntu/14.04
However, nginx wasn't starting correctly so I updated the config files (with help from SO) as follows:
/etc/nginx/nginx.conf:
events {
worker_connections 4096; ## Default: 1024
}
http {
##
# Phusion Passenger
##
# Uncomment it if you installed ruby-passenger or ruby-passenger-enterprise
##
passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /home/deploy/.rbenv/shims/ruby;
passenger_nodejs /usr/bin/nodejs;
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name <URL>;
passenger_enabled on;
rails_env production;
root /home/deploy/<PROJECT_NAME>/current/public;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
(URL and PROJECT_NAME redacted in question)
/etc/nginx/sites-enabled/default I could keep empty, and with this I got nginx to run smoothly - except for this problem with the assets. Does any one have any advice?
Several things to test:
When you precompile your assets, do the required files appear in your public directory?
When you precompile your assets, you basically tell the Rails asset pipeline to merge & compile all your assets in the public directory. This means if you're trying to include a particular file in your production asset pipeline, it should be precompiled
I would run the rake assets:precompile RAILS_ENV=production command, and then look at all your assets in the public folder to check if they're there
--
If the assets are present in your public folder, are they being pushed to the server?
You should SSH into your server & browse to the public directory of your app (in /current). This will allow you to see if your assets have been uploaded to your server as you need
If they are not there, the problem is with Capistrano's deploy process; if they are there, it means there's a problem with your Rails server
--
If the assets are in the public folder on your server, it will mean the server is at fault somehow
Probably the best way to ensure it's not a server issue is to reload the server. With apache, you'll typically use service reload apache2, but I'm not sure about nginx.
This should be accompanied by looking at your Rails installation - is it calling the correct assets as defined in your config files?
This is a bit off topic, but for organization's sake you might want to put your Nginx server block in /etc/nginx/sites-available/default and then make sure you have it linked to /etc/nginx/sites-enabled/default.
It should work fine with the server block in /etc/nginx/nginx.conf but it's best practice to put it in the default host or create another virtual host if you so desire.
Glad you were able to get things working.

Rails 3.2 Asset Pipeline with Thin and Apache, not finding assets

My question is similar to this one Rails 3.2 Asset Pipeline with Passenger Endless Errors except that when I try to actually go to
<link href="/assets/application-eed7996ee9017637f923133371ab3e92.css" media="all" rel="stylesheet" type="text/css" />
I get a 404. Here's the thing I don't understand. It is looking in /assets/, but when I look at the code that was deployed, the assets are only in /public/assets, which is actually a symlink to /var/www/myapp/shared/assets. So what in the world is responsible for telling the app that looking in /assets will produce correct results??
I am using Rails 3.2.0, ruby-1.9.3-p125, deploying to Ubuntu, Apache, and Thin.
I should clarify: My assets are indeed deployed to the server. Everything works perfectly fine until they need to be served, in which case production.log tells me it's looking for them in /assets/application-eed7996ee9017637f923133371ab3e92.css, which 404's.
For every request my thin.log says
cache: [GET /] miss
and production.log says
ActionController::RoutingError (No route matches [GET] "/assets/application-abecf2e096af9ee80697fd49e79a55e7.js"):
UPDATE
#Brandan thanks for the help. My assets are indeed in RAILS_ROOT/public/assets. I put this in my Apache vhost file:
DocumentRoot /var/rails/myappname/current/public
RewriteEngine On
XSendFile On
XSendFilePath /var/rails/myappname #not even sure if this line is needed
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
My RAILS_ROOT/config/environments/production.rb settings:
config.cache_classes = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.serve_static_assets = false
config.assets.compress = true
config.assets.compile = false
config.assets.digest = true
config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
Delete the following lines from your Apache configuration.
ProxyPass / balancer://thinservers/
ProxyPassReverse / balancer://thinservers/
The answer came from In Rails, should I enable serve_static_assets?.
Typically, your assets should only exist in /public/assets for a deployed application.
Apache should be configured so that its DocumentRoot is your RAILS_ROOT/public. Then it will serve http://example.com/assets/whatever.css from RAILS_ROOT/public/assets/whatever.css, and it never goes through Rails for static assets.
Have you restarted your application since you precompiled your assets? Sometimes Rails is expecting an older/newer compiled version of your assets than is currently deployed.
I've been having this problem for days now. Thought it was an issue with capistrano or the ruby version however I'm pretty sure it's permissions related too.
My configuration was pretty much the same as yours although I'm also using Unicorn.
Here's what I did to sort:
Temporarily remove the following section because I think that was causing problems with the troubleshooting:
<LocationMatch "^/assets/.*$">
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</LocationMatch>
Perhaps get it all working and then add it back in. I don't think it's the cause of the problems however, when diagnosing things like this, it's best to remove as much as you can to find the culprit.
Run a chown -R xxx.xxx (replace xxx with your application user or web user) on the public directory. As soon as I did so, the css appeared again.
(What I did but maybe not essential) You might also want to install locally without cap. just in case there's an issue with it. That also worked for me.
Completely wipeout tmp/cache and public/* just in case.
Restart your apache server a couple of times.
You can see a gist of my conf. here
Try removing the ProxyPass and ProxyPassReverse directives from your apache/thin configuration. The P flag in your rewrite rule is already performing the proxy pass that you desire.
See http://httpd.apache.org/docs/2.0/mod/mod_proxy.html for more information.
Passanger knows its a RoR application as there is a config.ru file.
The same error you are reporting happened to me due to wrong permissions. Apache was not able to serve the files inside assets, but was able to send the files on public/
In my case I use capistrano so assets was a symlink to shared/public/assets.
what I did was:
chmod -R o+x shared/
x permissions are required to list and access directories. After that it worked. You have to make sure that assets has +x for others

Phusion Passenger not displaying CSS, Javascript files

I have a Phusion install, configured with Rails 3.0.10 and Apache 2, and assets like CSS and Javascript are apparently being served, but not utilized by the browser.
So for instance when I hit the root url, the page renders, but CSS and javascripts are not used by the browser. I see GET requests coming through for each asset in the access logs.
I can visit those assets directly in my browser, going to stylesheets/application.css?1313636333 I see the correct application.css
I dont see permission errors in production logs, or apache error logs.
My VHost looks like:
<VirtualHost *:80>
ServerAdmin info#example.com
ServerName portal.example.com
DocumentRoot /app/example/public
<Directory /app/example/public>
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
Since you can access your static assets, the mime-type incorrectness might be the cause.
Take the output of the following:
curl --head http://portal.example.com/stylesheets/application.css
the result should contains "Content-Type: text/css"

Resources