Rails App behind Wordpress using fastcgi_intercept_errors - ruby-on-rails

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;
}
}

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

Nginx config file is not configured properly. "This site can’t be reached"

I'm fairly new to Nginx and web servers in general.
My setup is docker, Nginx, PHP/laravel, +let's encrypt.
I have this Nginx config file:
server {
listen 80;
server_name www.example.io;
return 301 https://example.io$request_uri;
}
server {
listen 80;
server_name example.io;
return 301 https://example.io$request_uri;
}
server {
listen 443 ssl;
server_name example.io;
ssl_certificate /etc/nginx/certs/example.io.pem;
ssl_certificate_key /etc/nginx/certs/example.io.key;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
I'm pretty sure my certificates are not what the problem is. because they do work when I have a single port 80 server and it has server_name example.io www.example.io but in that case, I'm unable to access the website through example.io as secure. while the www.example.io is secure. it also acts like two different websites. I believe the cookies in one do not implement in the other.
What I'm trying to achieve is, I wish to redirect both www.example.io and example.io to https://example.io

Nginx proxy server not serving static assets on rails app

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;
}

Nginx configuration for Wordpress in a directory

I have a Rails app configured with nginx with its root at /var/www/apps/example/current/public. It's accessed at https://www.example.com. That all works great. I decided to add a blog, and I wanted to go with Wordpress. I installed it in a different directory on the server, /var/www/apps/blog, and I want to be able to access it by going to https://www.example.com/blog
Below is my nginx config:
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/certs/example.com.pem;
ssl_certificate_key /etc/ssl/certs/example.com.key;
server_name www.example.com;
root /var/www/apps/example/current/public;
passenger_enabled on;
rails_env production;
client_max_body_size 100M;
client_body_buffer_size 256k;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /blog {
root /var/www/apps;
location ~ [^/]\.php(/|$) {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
I can navigate to example.com/blog and it takes me there without any issues. The problem comes when I enable pretty URLs and try to view a post. It circumvents the /blog directory and hits my Rails app, ending up with a 404. I see the following error in /var/log/nginx/error.log:
2016/06/30 17:24:32 [error] 7035#0: *20 "/var/www/apps/blog/hello-world/index.html" is not found (2: No such file or directory), client: 199.27.128.198, server: www.example.com, request: "GET /blog/hello-world/ HTTP/1.1", host: "www.example.com", referrer: "https://www.example.com/blog/"
Adding an index index.php directive doesn't fix the problem, it merely then states that /var/www/apps/blog/hello-world/index.php is not found instead.
Any ideas? I'm stumped.
try_files $uri=404; is not enough for pretty permalinks.
To enable pretty permalinks, you need to change it to:
location /blog {
root /var/www/apps/blog;
try_files $uri $uri/ /index.php?$args;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Or, try non-root try_files redirect:
location /blog {
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Here's a quick guide setting up wordpress with rails

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