nginx 301 from www to mobile site causes 404 - mobile

I'm getting a 404 for the root of my mobile site. My browser detection code looks for a mobile user-aget, sets the vary header, and 301s to the mobile site.
Here is the main site config
server {
listen 80;
server_name www.mydomain.com;
location / {
if ( $is_mobile) {
add_header Vary "User-Agent";
return 301 $scheme://m.mydomain.com$request_uri;
}
}
Here is the mobile site config
server {
listen 80;
server_name m.mydomain.com;
root /var/www/mobile;
index index.html;
location / {
try_files $uri $uri/ #dynamic;
}
location #dynamic {
rewrite ^/(.*)$ /index.html last;
}
}
I'm using the FireFox Override User Agent extension to test. If I go to www.mydomain.com the app loads properly. However, when I switch to a mobile browser Nginx 404s.
Nginx 200s for pages entered manually -
http://m.mydomain.com/index.html
http://m.mydomain.com/about.html
http://m.mydomain.com/pricing.html
Since both index and root are set shouldn't the site point http://m.mydomain.com/ to http://m.mydomain.com/index.html?
If not what is the best standardized approach to get this working?
UPDATE: Added config for mobile detection
Here is the config I use in the main nginx.conf file for mobile detection
map $http_user_agent $is_desktop {
default 0;
~*linux.*android|windows\s+(?:ce|phone) 0; # exceptions to the rule
~*spider|crawl|slurp|bot 1; # bots
~*windows|linux|os\s+x\s*[\d\._]+|solaris|bsd 1; # OSes
}
map $is_desktop $is_mobile {
1 0;
0 1;
}

See nothing wrong. I tried your config file in my devbox and it worked: the request was redirected to m.mydomain.com and the index.html was served.
So it could be something else caused the issue. How did you set $is_mobile? Maybe setting $is_mobile has some side effect and that if block in your question is not picked by nginx to serve the mobile request. Your mobile request went into another location block that doesn't know how to handle it.

In sites-available there was a file named 1 which was symlinked to site-enabled. Not sure how it got there but I unlinked and deleted it, restarted Nginx, and / now resolves to index.html properly. Very odd.

Related

Nginx routes and refresh cause 404

I've set up an Express and React website using nginx and Elastic Beanstalk. It works fine when navigating the website, but if I refresh on a route other than the home route, or try type in a specific route other than the home route it causes a 404.
I've found a lot of different solutions to do with changing the nginx.config, and think I'm one step away. This is my current nginx.config:
server {
listen 80;
server_name leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com www.leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com;
root /var/www/leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
I've seen a lot of solutions suggesting to use root /usr/share/nginx/html;, however when I use this instead of the root above every page links to the nginx index.html. So I changed to try the root as the path to the domain, which I think I have wrong, but don't know how to work out the path, and currently causes 500 internal error on every route including the home route.
Any help would be massively appreciated, thanks.
I think your nginx config has the wrong syntax. In the below nginx.conf, the / location points to your index.html in the folder /var/www/html
server {
listen 80;
server_name leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com www.leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com;
location / {
root /var/www/html;
index index.html
try_files $uri $uri/ /index.html;
}
}
You need to manually copy all the content of the client/build folder to /var/www/html - or you can just create a symlink (which is IMO not the very best solution, but it should work)
ln -s client/build /var/www/html
If you want to work with a symlink, make sure to remove the folder before creating the symlink otherwise you get an error

Nginx Subfolder admin react app under main react app

I have a situation where i have two apps developed in react.
User App
Admin App
I made a build of both apps and have placed the user app build in site directory, where as admin app build is inside site/admin directory
What i want is
when someone tries www.mydomain.com/admin, it should go to admin directory, where as if no admin is given in url then it should not look for admin instead user files should be served.
I am willing to change directory structure any possible way to make this urls work as expected.
I have given alot of time and tries but failed to achieve the result. I am missing something, possibly its related to try_files configuration but i am not sure yet.
Following is the Nginx file i have created so far for my needs.
If i write mydomain.org/admin, it works fine.
But when i write mydomain.org/admin/{someotherparam e-g dashboard}, it loads the main user react app instead of admin app. I guess it reads the index file of user in that case. How to make read the index file of admin if /admin/ is in the url on first.
I have not much knowledge on nginx configuration, thou i did tried google.
Only 1 task is remaining to do on my part is if i put admin directory and user directory separate.
But then i would have to do domain.org/user and domain.org/admin, which i do not want.
I want admin react to work only if there is admin in url in first place after url.
I am not sure how to get this to working.
server {
listen 80;
listen [::]:80;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name mydomain.org www.mydomain.org;
location / {
root /var/www/mydomain.org/html/frontend/site;
try_files $uri $uri/ /index.html;
}
location /admin(.*) {
root /var/www/mydomain.org/html/frontend/site/admin;
try_files $uri $uri/ /index.html;
}
}
I am using LEMP on ubuntu 18.
Could you try this config?
server {
listen 80;
listen [::]:80;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name mydomain.org www.mydomain.org;
root /var/www/mydomain.org/html/frontend/site;
location / {
try_files $uri $uri/ /index.html;
}
location /admin {
try_files $uri $uri/ /admin/index.html;
}
}

NGINX - Refresh child route in SPA application

I have a SPA application, written in ReactJS. The application has an index view (/myapp) which shows a list cards. Pressing on a card redirects to a new page via routes (/myapp/item, /myapp/itemXX). The application works fine when the user access from the index. However, refreshing the browser in /item ends up in a 404 Not Found error.
The server is NGINX and the configuration looks like:
# ...
location /myapp {
root /usr/share/nginx/html/;
try_files $uri $uri/ /index.html;
index index.html;
}
# ...
In the log file I see:
{
"log": "2019/12/26 08:32:36 [error] 178#178: *3146 open() \"/etc/nginx/html/index.html\" failed (2: No such file or directory), client: 46.222.205.233, server: app.mydomain.com, request: \"GET /myapp/item/8?param=888 HTTP/2.0\", host: \"app.mydomain.com\"\n",
"stream": "stderr",
"time": "2019-12-26T08:32:36.253097755Z"
}
I have already tried several location rules without success (location ^~ /myapp, creating specific rule for internal routes location /myapp/item).
Any help? Thanks!
I found this question, which summarizes how routing works in both, server and client side:
React-router urls don't work when refreshing or writing manually
The solution that works for me is:
location /myapp {
if (!-e $request_filename){
rewrite ^(.*)$ /myapp/index.html break;
}
}

Running a C FastCGI script using NGINX

This should be my last question regarding FastCGI and NGINX (I've asked way too many already), but I had a question regarding running C FastCGI scripts on a web server, specifically NGINX. So right now this is how my nginx.conf file looks like:
user nobody nobody;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name localhost;
location / {
root /nginx/html;
index index.html index.htm new.html;
autoindex on;
fastcgi_pass 127.0.0.1:8000;
}
}
}
I have a simple C FastCGI script that prints out Hello World. I know that in order to run this script, I first have to compile the C script which would result in a binary. I then execute this binary using spawn-fcgi -p 8000 -n <binary> or cgi-fcgi -start -connect localhost:8000 ./<binary>. I have had success doing this and displaying the correct results. However, when I do this, the CGI script is the only thing that is being displayed on the web server. I cannot go to any .html page or any other page for that matter. Even if I type in a random extension which should result in a 404 Page not Found error, the CGI script is being displayed. Basically I'm trying to have a index.html be the home page and then when the user clicks on a button, the user is taken to a new page that displays the C CGI script.
Is this possible? If so, how could I do it? I have spent hours trying to find a solution online but have had no success. Please let me know if the question is too vague/unclear or if you need more information! Thank you!
There are two possibilities that I can think of. You can assign a URI to your CGI program and use that to access it. Or you can send any invalid URI to your CGI program.
In the first case, you could use:
root /nginx/html;
index index.html index.htm new.html;
location / {
try_files $uri $uri/ =404;
}
location /api {
fastcgi_pass 127.0.0.1:8000;
}
So, any URI beginning with /api will be sent to the CGI program. Other URIs will be served by nginx, unless not found, in which case a 404 response will be returned.
In the second case, you could use:
root /nginx/html;
index index.html index.htm new.html;
location / {
try_files $uri $uri/ #api;
}
location #api {
fastcgi_pass 127.0.0.1:8000;
}
So any URI that does not exist will be sent to the CGI program.
See this document for the try_files directive, and this document for the location directive.

Nginx with cakephp - configuration problem

I am karthik. This is my first post here.
I have a vps running on centos with nginx server. I want a photogallery on my site. so i created a subdomain clicks.example.com. I am using a flash template called whitespace cms which uses cakephp. The problem is with the rewrite rules. I am not able to figure out the root directory.
This is my configuration file.
server {
listen 80;
server_name clicks.example.com;
access_log /home/www/example.com/logs/access.log;
error_log /home/www/example.com/logs/error.log;
rewrite_log on;
# rewrite rules for cakephp
location / {
root /home/www/example.com/clicks/fotoblog/app/webroot/;
index index.php index.html;
# If the file exists as a static file serve it
# directly without running all
# the other rewite tests on it
if (-f $request_filename) {
break;
}
if (!-f $request_filename) {
rewrite ^/(.+)$ /index.php?url=$1 last;
break;
}
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/example.com/clicks/fotoblog/app/webroot$fastcgi_script_name;
include fastcgi_params;
}
}
I think i am messing up with subdomain and root of cakephp. any help will be appreciated. I tried for 8 hours :) still no luck. When i use the above configuration i get blank page and sometimes i get a 502 bad gateway error.
Update: okay, 502 errors was due to nginx php-fpm problems. now when i access clicks.example.com i am getting redirected to the blackened of the cms. clicks.example.com/users/login.. [actually the backened should be clicks.example.com/fotoblog/users/login, do know where i am going wrong]
You're doing nothing wrong! I had a similar issue as well and was able to fix it after hours of researching and wasting time - I simply did a fresh install of a new Cake version and it solved my nginx rewrite rule issues.

Resources