nginx .jpg and .jpeg not found in / but are found everywhere else - nginx

I'm new to nginx and I like it.
I'm putting up a few scgi feeds, and some static content.
After creating a home page hierarchy under /home, I went to move it to /.
But when I put it there the .jpg and .jpeg images were coming back 404.
sitename.com/test.gif is found just fine.
sitename.com/test.jpg is 404
but creating a a subdirectory, and copying test.jpg work.
sitename.com/subdirectory/jpg is fine.
I'm running with pretty empty config files as they were installed under Ubuntu 18.
I'd REALLY like to know what's going on here, and why top level .jpg/.jpeg files are doing this.
I know I could create a location directive as follows:
location ~ \.(jpg|jpeg)$ {
root /real/location/of/my/home/;
}
But that breaks access to .jpg/jpeg files in the scgi locations served from other roots.

I found it! It wasn't the jpg/jpeg suffix. It was the filename!
I have a /wdc location that is an scgi script.
A file in / that begins wdc for example /wdc-face.jpg goes through to scgi.
Many of the nginx example give locations without trailing slashes. But I think that a trailing slash is what people should be encouraged to use by default

Related

React app - Blank page for all pages with a dynamic URL, on nginx server

Locally, the app works correctly.
When deploying it on a ubuntu server, there is a problem with this route:
<Route path="/combination/:some_id" exact component={SomePage} />
I'm using a BrowserRouter.
When clicking on a link, the url in the address bar is updated to the correct one, but I'm not redirected to the page.
When trying to access a page (i.e http://my_ip/combination/hjg234jg2323jh4g) all I can see is a blank (white) page.
I think the problem is with nginx configuration, because locally it works. and other routers work (/contact-us)
My /etc/nginx/sites-available/default file contains:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri /index.html;
}
You need to add only base href="/xyz" in your index.html file.
If you added basename in history, then base href should be equal to
basename or else put only / .
There is no problem in the configuration of the default file.
It's worked well for me.

Adding new files to rsyslogd with wildcards

We're got a pre-existing rsyslog config file which is working for papertrail e.g.
/etc/rsyslog.d/20-papertrail.conf which has
*.* #logs4.papertrailapp.com:44407
However we've got a couple of NGINX websites on the server so would like to have it also monitor their error logs.
The paths to them are:
/var/log/nginx/www.website-one.com-error.log
/var/log/nginx/www.website-two.com-error.log
/var/log/nginx/www.website-three.com-error.log
However this /var/log/nginx also contains a bunch of .log files which we do not want to monitor e.g.
/var/log/nginx/error.log
/var/log/nginx/access.log
/var/log/nginx/error.log1
/var/log/nginx/nginx.log
In my head we need to add something like...
/var/log/nginx/*-error.log
And make sure they pipe to the papertrail url as well.
However I'm struggling to decipher the rsyslog documentation to figure out how to do this.
Thanks!
In rsyslog documentation it seems that you can use wildcards in files.
File
The file being monitored. So far, this must be an absolute name (no macros or templates). Note that wildcards are supported at the file name level (see WildCards below for more details).
WildCards
Before Version: 8.25.0
Wildcards are only supported in the filename part, not in directory names.
/var/log/*.log works.
/var/log/*/syslog.log does not work.
Since Version: 8.25.0
Wildcards are supported in filename and paths which means these samples will work:
/var/log/*.log works.
/var/log/*/syslog.log works.
/var/log/*/*.log works.
All matching files in all matching subfolders will work. Note that this may decrease performance in imfile depending on how many directories and files are being watched dynamically.
If you want to forward your vhosts logs you can change configuration directly in NGINX vhosts configuration, you should change/add access_log and error_log policies as explained here or use custom facilities to forward your logs (using rsyslog).
HOW TO DO IT USING RSYSLOG?
Create a new custom file in /etc/rsyslog.d/nginx_custom.conf:
module(load="imfile" PollingInterval="1") #needs to be done just once
# File 1
input(type="imfile"
File="/var/log/nginx/www.website-*.com-error.log"
Tag="websites"
Facility="local0")
local0.* #logs4.papertrailapp.com:44407
#Just to test that logs are forwarded, comment the line once you've tested it
local0.* /var/log/test.log
And restart rsyslog service
NOTE: Line local0.* /var/log/test.log is just to test that you can see forwarded logs into your local server, comment this line after you've tested that everything works.

nginx 404 not found if URL contains "star"

Weird problem: If the URL contains the word "star", the result is a 404. It does only happen with this word.
Working:
http://example.com/some/another/url
Not working:
http://example.com/some/url/with/star
The virtual host config is not the problem as it appears on all server blocks, even in the default one.
The error does not appear in the access.log!
Anyone else with nginx 1.9.14 can reproduce this strange problem?
The reason was a copy & pasted line that should cache static files:
~*.(ogg|ogv|svg|tar…)
Since "star" is ending with tar (like the .tar archive) the rule fired because there is a missing backslash. It must be
location ~*\.(ogg|ogv|svg|svg|tar)
Thanks to nginx mailing group!

conditional rewrite or try_files with NGINX?

I'm having trouble setting up a conditional rewrite, and I've been trying to use the if directive (despite all sources indicating it's "evil") with the -f switch to check for the presence of a file, but it's not working. I believe the issue/case is best explained by example, so here goes:
Directory structure
workspace/
myapp/
webroot/
index.php
assets/
baz.js
hello/
foo.js
modules/
hello/
assets/
foo.js
bar.js
Expected results
/ => /workspace/myapp/webroot/index.php
/assets/hello/foo.js => /workspace/myapp/webroot/assets/hello/foo.js
/assets/hello/bar.js => /workspace/myapp/modules/hello/assets/foo.js
/assets/baz.js => /workspace/myapp/webroot/assets/baz.js
In summary:
foo.js is only present in the modules/hello/assets folder and gets delivered from there.
bar.js is present both in webroot/assets/hello and modules/hello/assets and gets delivered from webroot.
(it hides/overrides the file in modules)
baz.js is only present in webroot/assets and gets delivered from there.
The part that doesn't work right now, is this:
location /assets/ {
if (-f $uri) {
break;
}
root /workspace/myapp/modules;
rewrite ^/assets/([^/]+)/(.*)$ /$1/assets/$2 break;
}
Namely the if directive, doesn't seem to have any affect - the bar.js file gets delivered from modules rather than webroot.
Should I be using if or not?
Is there any way I can solve this problem with try_files instead? I can't seem to grasp how this would work together with rewrite which I can't seem to get around.
Please do not suggest reorganizing the assets using a deploy script or something - it's not an option, for various other reasons.
I have used this pattern with Apache before, and NGINX seems more capable in most respects, so I'm sure this must be possible?
One requirement that isn't absolute, is I don't have to be able to override modules/hello/assets/foo.js with webroot/assets/hello/foo.js - serving scripts from webroot/assets/* is however a requirement.
The answer is divided into two parts: the first part explains why your configuration does not work and the second one provides examples of how to solve your problem. If you are only interested in the solution, go straight to the second part.
The problem
First of all, note that the positon of the root directive in a location block is not important. It does not matter if you put it at the very top or at the bottom of a location, it will affect the whole location anyway. Also, keep in mind that break in the end of the rewrite line tells Nginx to stay within the current location even if the URI has been successfully rewrited.
Having said that, let's take a look at your configuration and see how every request from the Expected results is processed and why nothing works as expected.
Let's presume that there is no other suitable location with a higher priority in your configuration. Since every request from Expected results starts with /assets, all of them will be handled according to the rules presented in your location. So:
/assets/hello/foo.js
The root is set to /workspace/myapp/modules. The if directive will be evaluated to false, because /assets/hello/foo.js does not exist and so break will not be executed. Finally, the last rewrite will change the requested URI from /assets/hello/foo.js to /hello/assets/foo.js and the following break will tell Nginx to stay within the current location. As a consequence /workspace/myapp/modules/hello/assets/foo.js will be served.
/assets/hello/bar.js
This request is processed exactly the same way as the previous one, so /workspace/myapp/modules/hello/assets/bar.js will be served.
/assets/baz.js
Yet again the root is set to /workspace/myapp/modules and the if is evaluated to false. But this time the final rewrite will not change the URI, because the request does not match the regular expression. As a consequence Nginx will try to serve /workspace/myapp/modules/assets/baz.js and since there is no such file exists, will return 404.
As you can see your configuration cannot possibly work as you want it to for several reasons:
if is always evaluated to false, because you try to check URIs and not files;
the request stays within the location because you tell it to stay there with break in the rewrite line;
root is always set to /workspace/myapp/modules in this location so no file can be served from anywhere else.
The solutions
The easiest solution would be to use try_files:
root /workspace/myapp/webroot;
location /assets/ {
try_files $uri #modules;
}
location #modules {
root /workspace/myapp/modules;
rewrite ^/assets/([^/]+)/(.*)$ /$1/assets/$2 break;
}
This configuration tells Nginx to look for a file in the webroot folder first and if nothing is found then go to the modules folder in another location. This approach is considered most preferable.
On the other hand, using if would allow you to solve the problem within one location:
location /assets/ {
root /workspace/myapp; # The parent folder
if (-f $document_root/webroot/$uri) {
rewrite ^(.*)$ /webroot/$1 break;
}
rewrite ^/assets/([^/]+)/(.*)$ /modules/$1/assets/$2 break;
}
However, this approach is considered outdated is not recommended for use.

Nginx try_files & rewrite & content type

I'm currently migrating from lighttpd to nginx.
I've got some weird files (don't ask why):
1. say a file named 'news', which actually should be more like news.txt
2. a file named '.html', which actually should be index.html
With lighttpd, simply rewrite those things would work.
Nginx would still locate those files with try_files or rewrite, but I've got no control of the content type returned. I mean if the file is named '.html', the content type is 'application/octet-stream'.
I know I can use more_set_headers to achieve that, but is there any other way to do that? I mean why does nginx think a file named '.html' not an html file?
I mean why does nginx think a file named '.html' not an html file?
A dot at the beginning in unix-like systems is usually used as the indicator of hidden files. In this case, a part after the dot isn't file extension.
I know I can use more_set_headers to achieve that, but is there any other way to do that?
You should use the default_type directive instead of 3-rd party modules.
For example:
location =/.html {
default_type text/html;
}

Resources