Nginx proxy server not serving static assets on rails app - ruby-on-rails

I followed some answers here did the changes to the location block to serve the static assets. Seems no luck.
/etc/nginx/sites-enabled/default
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
proxy_pass http://127.0.0.1:3000;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location ~* /(assets|fonts|swfs|images)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
Can someone please help me how to fix this issue?

If your assets' folders are inside /var/www/html, for example /var/www/html/images/test.jpg, you want to use this syntax:
location ^~ /(assets|fonts|swfs|images)/ {
access_log /var/log/nginx/test.com.access_proxy.log;
error_log /var/log/nginx/test.com.error_proxy.log;
root /var/www/html/;
internal;
}

Related

Apache htaccess rewrite rule works but how do I translate to nginx rewrite directive?

I have a live server running Apache and a dev server running NGINX in docker. I wish to rewrite my sites urls from /index.php?t=123abc to /123abc.
This rule seems to work in .htaccess
RewriteRule ^([0-9a-f]{6})$ index.php?t=$1 [L]
However, I can't get it to translate to an nginx directive. My 'default' site conf is:
server {
listen 80 default_server;
listen 443 ssl;
root /config/www;
index index.html index.htm index.php;
server_name _;
ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;
client_max_body_size 0;
location / {
rewrite "^/([0-9a-f]{6})/?$" "/index.php?t=$1";
try_files $uri $uri/ =404;
}
autoindex on;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-cgi alone:
fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
}
}
The /index.php?t=123abc works fine but /123abc gives 404 error.
Please help

docker nginx not loading css styles

When uploading static files to my server using Nginx as the web server my css, javascript, and google fonts are not working as they do when testing the site on localhost.
I'm running Nginx in a docker container using the base image.
Dockerfile
FROM nginx
COPY example.com.conf /etc/nginx/nginx.conf
COPY build /etc/nginx/html/
nginx.conf
user nginx;
events {
worker_connections 4096; ## Default: 1024
}
http {
server {
listen 80;
listen [::]:80;
server_name example.com;
include /etc/nginx/mime.types;
root /etc/nginx/html;
index index.html;
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
location / {
try_files $uri /index.html =404;
}
}
}
Can someone tell me whats wrong with my conf?
Also when viewed on Chrome the console logs this Resource interpreted as Stylesheet but transferred with MIME type text/plain
Some other SO post I looked at:
SO post
SO post
With the help of this SO answer and the comments I was able to get it working. If my answer doesn't help you I suggest you look at that one when running Nginx in a docker container.
For me it was moving the include /etc/nginx/mime.types; and adding sendfile on;
outside my server block and in the http block
My example.com.conf now looks like this:
user nginx;
events {
worker_connections 4096; ## Default: 1024
}
http {
include /etc/nginx/mime.types;
sendfile on;
server {
listen 80;
listen [::]:80;
server_name example.com;
root /etc/nginx/html;
index index.html;
location ~ \.css {
add_header Content-Type text/css;
}
location ~ \.js {
add_header Content-Type application/x-javascript;
}
location / {
try_files $uri /index.html =404;
}
}
}

Nginx reverse proxy instead of directory listing

I'm trying to have nginx serve static content while reverse proxying everything else to a rails server.
All that works, except for the home page.
If I go to example.com I get a 403 error and the error log shows
2019/06/14 04:32:59 [error] 9746#9746: *1 directory index of "/var/www/html/" is forbidden
I want the request to be sent to the rails server as example.com/ instead of trying (and failing) to get a directory listing. The rails server should display a homepage instead. (side note: if I turn autoindex on I will get a directory listing)
Configuration is here:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name example.com;
index index.html;
location / {
autoindex off;
root /var/www/html;
try_files $uri $uri/ #rails;
expires max;
access_log off;
}
location #rails {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
}
}
If you want to disable the index behaviour for all URIs, drop the $uri/ term from the try_files statement. For example:
location / {
try_files $uri #rails;
...
}
See this document for details.
Alternatively, add a new location block to specifically handle the URI /, for example:
location = / {
try_files nonexistant #rails;
}
See this document for details.
A fix for the homepage would be to add an exact location for the homepage, like so:
location = / {
try_files #rails =404;
}

Rails App behind Wordpress using fastcgi_intercept_errors

I'm starting a migration of a WordPress website to a rails application. The migration needs to be done gradually over the next few months, so I'll need to be able to run both sites in parallel. Using fastcgi_intercept_errors on a test environment I've managed to get any 404 errors returned by WordPress to forward on to the Rails application using the following configuration:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name mydomain.com;
root /var/www/html/wordpress;
index index.php index.html
error_page 500 502 503 504 404 #rails;
location / {
try_files $uri $uri/ /index.php?$args;
recursive_error_pages on;
error_page 404 = #rails;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
include fastcgi_params;
error_page 404 = #rails;
}
location #rails{
passenger_enabled on;
passenger_user user;
rails_env development;
root /home/user/rails_app/app/public;
}
}
The problem now comes when the rails app references any /assets links they always forward back into the rails app and always load the root location of the application.
Is there any way to fix this so that assets will also be treated as part of the rails application?
This nginx configuraton was able to do what I needed. error page directive was moved into the only the php location, and an assets location was added to redirect the default root location from the php app to the ruby application public folder.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name mydomain.com;
root /var/www/html/wordpress;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
recursive_error_pages on;
error_page 404 = #rails;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
include fastcgi_params;
error_page 404 = #rails;
}
location ^~ /assets/ {
root /home/user/rails_app/app/public;
}
location #rails{
passenger_enabled on;
passenger_user user;
rails_env production;
root /home/user/rails_app/app/public;
}
}

Nginx causes 301 redirect if there's no trailing slash

I'm running nginx in a Virtual Machine using NAT and I'm having redirection issues when I access it from the host machine.
Works as expected
http://localhost:8080/test/index.htm: works.
http://localhost:8080/test/: works.
Doesn't work as expected
http://localhost:8080/test: redirects to http://localhost/test/ . This is not what I want. (notice it strips the port number)
What I've tried
Based on what I've googled, I tried server_name_in_redirect off; and rewrite ^([^.]*[^/])$ $1/ permanent;, both with no success.
My default.conf:
server {
listen 80;
server_name localhost;
# server_name_in_redirect off;
location / {
root /usr/share/nginx/html;
index index.html index.htm index.php;
}
location ~ \.php$ {
# rewrite ^([^.]*[^/])$ $1/ permanent;
root /usr/share/nginx/html;
try_files $uri =404;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
I posted a possible solution to this problem on serverfault; reproduced here for convenience:
If I understand the question correctly, you want to automatically serve, without using a 301 redirect, http://example.com/foo/index.html when the request is for http://example.com/foo with no trailing slash?
Basic solution that works for me
If so I've found this try_files configuration to work:
try_files $uri $uri/index.html $uri/ =404;
The first $uri matches the uri exactly
The second $uri/index.html matches a directory containing the index.html where the last element of the path matches the directory
name, with no trailing slash
The third $uri/ matches the directory
The fourth =404 returns the 404 error page if none of the preceding patterns match.
Taken from Serverfault answer
My updated version
If you add in the server block:
index index.html index.htm;
And modify try_files to look like this:
try_files $uri $uri/ =404;
It should work too.
A somewhat simpler solution, that worked for me, is to disable absolute redirects with absolute_redirect off; as in the following example:
server {
listen 80;
server_name localhost;
absolute_redirect off;
location /foo/ {
proxy_pass http://bar/;
}
If I run curl on on http://localhost:8080/foo, I can see that the Location header in the redirect HTTP response is given as /foo/ and not http://localhost/foo/.
$ curl -I http://localhost:8080/foo
HTTP/1.1 301 Moved Permanently
Server: nginx/1.13.8
Date: Tue, 03 Apr 2018 20:13:28 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: /foo/
From that, I assume any web-browser would do the right thing with the relative location. Tested on Chrome and it works fine.
try :
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm index.php;
if (-d $request_filename) {
rewrite [^/]$ $scheme://$http_host$uri/ permanent;
}
}
}
Try changing
server_name localhost;
# server_name_in_redirect off;
to
server_name localhost:8080;
server_name_in_redirect on;

Resources