Overcoming "404 Not Found" in Nginx - nginx

I have a VPS that was serving static files using Apache. After covering some mileage in Django, I decided to change from Apache to Nginx. I thought it would be a simple matter (e.g. specifying the root folder for the domain, that settles it). I see that my expectations were unrealistic because now I am getting "404 Not Found" on all paths except the root folder.
mysite.conf:
server {
listen [::]:443 ssl;
listen 443 ssl;
server_name share.mysite.com;
root /var/www/html/share.mysite.com;
location / {
index index.html index.php;
}
}
How do I scale this configuration to serve static files located in different folders in the hierarchy?
1. share.mysite.com/tutorials/a-subject/a.mp4
2. share.mysite.com/tutorials/another-subject/something.jpg
3. share.mysite.com/some-folder/somefile.zip
At the moment, any of the above combinations give me a "404 Not Found", all except "https://share.mysite.com". Yet, the files are there.
I understand that this may involve the "location" keyword but I haven't seen a lucid explanation that translates to my case. I seek understanding. Nginx is new to me.

It is because of the rewritten rules. You had them in place when using Apache as most probably WordPress automatically created a .htaccess file and placed the necessary default rewrite rules for the so-called "pretty" URL ( e.g. accessing /blog /contact etc. ). In order to do that in Nginx, you have to add a few lines in the vhost for your domain there, please refer to the official documentation for that:
https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/

Related

Serving static website in nginx, wrong path for static files

I'm trying to use nginx to serve a static website that was given to me. Its folder structure is like this:
static_website/
index.html
www.example.com/
resources.example.com/
uploads.example.com/
The index.html file in the root is the one generated by httrack and it simply contains a redirect to www.example.com/index.html.
Inside the folder www.example.com are all the html files, in the other two folders are the css, javascript and image files.
Here is the nginx configuration:
server {
index index.php index.html index.htm;
server_name example.com;
location / {
root /var/www/static_website/www.example.com;
try_files $uri $uri/ =404;
index index.html;
}
}
I can navigate through the pages, but the css, javascript and image files are not loaded.
The path to one of the css files inside the html is like this:
href="../resources.example.com/style.css"
The only way I managed to get this working was to have the have the url like this:
example.com/www.example.com/
This way, all the path are correct. I'd like to avoid this and have simply example.com.
Is there a way to do this?
It looks like the site was originally intended to operate with ugly URLs like //example.com/www.example.com/.
But the path-relative URIs for the resources should work just fine relative to /, you just need to provide a location block which matches /resources.example.com/.
For example:
location / {
root /var/www/static_website/www.example.com;
try_files $uri $uri/ =404;
index index.html;
}
location /resources.example.com/ {
root /var/www/static_website;
}
I originally commented that you should try this:
location ~ \.(css|js|jpg|png|svg)$ {
root /var/www/static_website;
}
Which achieves a similar goal, but Nginx will process prefix locations more efficiently that regular expression locations.
I want to share my experience with this problem for others encountering similar issues as the solution was not so obvious to me
My setup and problem in particular had to do with cloudlflare settings which i was using to leverage TLS instead of handling it on the origin server for one of my 2 sites. if you are serving your site from a CDN that supports encryption and you use nginx on your origin consider the following setup:
# static1.conf
{ server_name static1.com; root: /var/www/static1/public; listen 80; listen 443; }
# static2.conf - no tls setup in nginx, figured id let cloudflare handle it
{ server_name static2.com; root: /var/www/static2/public; listen 80; }
static1 was setup at the origin with letsencrypt to handle tls connections
static2 was setup at the origin without any tls configuration
from left to right, here are the appropriate cloudlfare TLS modes which allowed me to access the correct files thru nginx
The distinction between full and flexible is that full mode lets the origin handle the certificate.
Initially I had the static2 site misconfigured as full, which lacked a listen directive for 443 causing nginx to serve static1 instead.
I realize the original question has nothing to do with cdn's or cloudflare but this scheme / protocol mismatch cost me a few hours and I am hoping to save someone else from similar grief
Honestly I am surprised nginx doesn't stick to matching on server_name and that oit implicitly matches on scheme as a fallback (or atleast appears to), even without a default_server specified - and without any meaningful messages in the logs to boot! Debugging nginx is a nightmare sometimes.

Nginx rewrite disabled? Can't do a simple rewrite

I've been having a lot of trouble with rewrite directives - nothing seemed to actually work, so I tried making the most basic rewrite sample that I could:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
location / {
rewrite ^/a$ /test.html break;
}
}
I was assuming this would return the contents of /var/www/html/test.html at http://localhost/a but it doesn't, it gives me a 404. Permissions on test.html are set correctly and it is accessible at http://localhost/test.html. I'm assuming rewriting is actually disabled - but I can't find anything like that in nginx.conf. The settings file above is the default in sites-available, and other than adding rewrite_log on; to the nginx.conf file everything is stock as distributed by the nginx 1.12.1 package in Ubuntu (17.10).
Logs provide no useful information and enabling rewrite logging has added no extra information to the logs. And yes, I've restarted nginx after each edit of the settings.
I've been trying all sorts of combinations, so at this point I'm just assuming rewrites aren't working/enabled? I'm totally confused here - ANY hints would be a big help.
I have no idea why but changing break to last made it work. This is confusing to me, as with this configuration I wouldn't expect there to be any processing after the rewrite. This is a pretty fresh install and there's not actually anything else on it yet that I would think would be interfering - so there must be some reason for this? If anyone has a better answer I'll switch the accepted, but for now this 'worked'.

NGINX multiple server_name, but have robots.txt file for each server_name?

I have to create a server_name as a listener for origin pulls by my CDN.
The CDN wants to pull from origin.mydomain.com
I already have 100s of lines of code under www.mydomain.com that showcases all the rewrites, rules and such, and I need to use all this code again.
My easy solution would be to have
server_name www.mydomain.com origin.mydomain.com
To easily have NGINX listen for the requests to the "origin" subdomain.
My fear is that google discovers the subdomain and starts crawling it. I'd like to block google from the "origin" subdomain somehow. Since declaring multiple server_name, I am not sure I can just place robots.txt file somewhere, since using same root folder as live site.
Is there an easy way to do this?
All feedback appreciated.
Cheers
Ryan
Use two server blocks and use the include directive to pull in the common code. For example:
server {
server_name www.mydomain.com;
include /path/to/common/config;
location = /robots.txt {
root /path/to/friendly/dir;
}
}
server {
server_name origin.mydomain.com;
include /path/to/common/config;
location = /robots.txt {
root /path/to/unfriendly/dir;
}
}
So you have two robot.txt files in different directories - or use rewrite ... last to map the URI to different local files.

Wordpress & Nginx with Docker: Static files not loaded

I'm using Docker to serve my simple WordPress website. A nginx container and a wordpress container. Simple setup:
upstream wordpress_english {
server wordpress_en:80;
}
server {
listen 80;
server_name my_domain.com www.my_domain.com;
location / {
proxy_pass http://wordpress_english;
}
}
Problem: Static files (css, js and images) are not loaded.
The output from the browser console shows a 404:
http://wordpress_english/wp-content/themes/twentyfifteen/genericons/genericons.css?ver=3.2
Its easy to spot the problem: The browser looks for the static files at wordpress_english (the nginx upstream name), instead of my_domain.com
How can I fix this problem?
This is not a nginx problem, but a WordPress problem.
Solution:
In wp-config.php, add the following two lines:
define('WP_HOME','http://my_domain.com');
define('WP_SITEURL','http://my_domain.com');
During the WordPress installation, WordPress automatically sets WP_HOME to nginx upstream name. The above solution overwrites the default setting.
Seems to be an issue in your nginx config file.
When declaring your server my_domain you provide location / with proxy_pass wordpress_english. I don't know a lot on nginx, but I don't see any declaration of path in your server my_domain and is root is linked to wordpress_english. Seems normal that he is looking for files in wordpress_english and not in you server. (In fact, I guess he is looking in your server but your server tells to look in wordpress).
Not sure about it cause I don't know well nginx and proxy_pass functions.

All requests to same directory, regardless of domain - NGINX

WordPress Multisite
Nginx
WPMU Domain Mapper
(I think my question has a non-WP-specific solution.)
Domains that point at my server's IP address don't get sent to my WordPress site unless they are defined in the config file or the domain is defined in /sites-enabled
So, if I just set the A-record of some random example.com domain to my IP, I get a "Welcome to nginx on Debian!" message.
But I need it to go directly to the WordPress directory.
And I need it to happen anytime anyone sets up a domain to point at the IP address. That is --- I need to set up the config so all requests go to the WordPress directory.
EDIT:
I have tried to set the default directory to /var/www/wordpress --- but that didn't seem to work.
You can use regex in nginx/conf.d/ config, to catch domains:
server {
listen 80;
set $location_root "/var/www/";
server_name ~^(?<somedomain>[\w-\.]+\.com)$;
root $location_root/$somedomain;
include conf.d/wpconf;
}
If you have domains not only in *.com area, just fix regex. For example, for domain site.com, this regex will go to /var/www/site.com directory.
Note: including conf.d/wpconf is not necessary, because i store in that file specific options for WPsites.
The solution was simple:
server {
listen 80 default_server;
server_name myprimarydomain.com *.myprimarydomain.com;
server_name_in_redirect off;
root /var/www/wordpress;
.
.
.
If you followed the Nginx/Multisite guide from WPMU --- you also have to remove the default file in the sites-available directory. It is being included by a line in the confd file, and it contains a conflicting default_server line.

Resources