I have a nginx server with the following code added to the sites conf file. The first part is an alias to allow the folder called images to be severed when visiting for example: example.com/images
The second part has been added to allow permalinks in wordpress to work. Problem is each of the code blocks work separately but not together. The offending line of code is:
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
expires max;
log_not_found off;
}
This code stops any files being server from example.com/images and shows a 404 error
location /images {
alias /var/www/clients/client0/web6/images;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
expires max;
log_not_found off;
}
Why does the cache line conflict?
Use try_files. This way you can work with settings in another block.
Example url: http://your-site.com/img/lorena_improta.jpg
root /var/www/html/stackoverflow;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~* ^/img/(.*)$ {
try_files $uri /48725060/images/$1;
}
location ~* \.(jpe?g|gif|png) {
expires 1h;
}
Related
I have a react frontend and a flask backend.
Currently I serve backend the following way
server {
location / {
try_files $uri #yourapplication;
}
location #yourapplication {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
}
I'd like to configure nginx in a way that would allow me to serve my react app from / and access API from all other routes (i.e. /users is an api endpoint).
Is it a "sensible" set up?
What should my config file look like?
Ended up using the following setup
server {
root /var/www;
index index.html index.htm;
location =/ {
try_files $uri $uri/ /index.html;
}
# Media: images, icons, video, audio, HTC
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
# Javascript and CSS files
location ~* \.(?:css|js)$ {
try_files $uri =404;
expires 1y;
access_log off;
add_header Cache-Control "public";
}
# Any route containing a file extension (e.g. /devicesfile.js)
location ~ ^.+\..+$ {
try_files $uri =404;
}
location /user {
try_files $uri #yourapplication;
}
location /register {
try_files $uri #yourapplication;
}
location /login {
try_files $uri #yourapplication;
}
location #yourapplication {
include uwsgi_params;
uwsgi_pass unix:///tmp/uwsgi.sock;
}
}
In other words, for production it serves static files on =/ and for every other end ponint passes it to flask.
I have a nginx.conf that looks like this:
server {
...
root /var/opt/data/web;
...
location ~* \.(?:eot|woff|woff2|ttf|js)$ {
expires 1M;
}
...
location /one {
root /var/opt/data/alternatives;
try_files $uri $uri/ =404;
}
location /two {
root /var/opt/data/alternatives;
try_files $uri $uri/ =404;
}
}
when I curl http://localhost/one/ I get the content of index.html stored in /other. But when I curl .../localhost/one/foo.js the file is not found and I get this in the error.log:
open() "/default/foo.js" failed (2: No such file or directory)
I tried other variants like location ~ (one|two), location /one/ or even location ~ /(one|two) but all of them didn't work.
The complete config consists of a lot more locations, but I guess the cause of my problem is the location where I set up .js resources to expire -1 because this prevents changing the root to what I need.
If this matters: I use nginx 1.15.2. In case you are wondering why I have this strange alternatives directory: the web directory is created by a CMS software while alternatives is git pulled.
nginx chooses a one location to process a request. Your location ~* \.(?:eot|woff|woff2|ttf|js)$ block processes any URI that ends with .js, and its root value is inherited from the outer block as /var/opt/data/web.
Where you have multiple roots, you need to ensure that those location blocks take precedence, by using the ^~ modifier. See this document for details.
For example:
server {
...
root /var/opt/data/web;
...
location ~* \.(?:eot|woff|woff2|ttf|js)$ {
expires 1M;
}
...
location ^~ /one {
root /var/opt/data/alternatives;
try_files $uri $uri/ =404;
location ~* \.(?:eot|woff|woff2|ttf|js)$ {
expires 1M;
}
}
...
}
If you need your expires rule to apply to the other roots, you will need to repeat the location within that scope, as shown above.
As an alternative, the expires directive can be used in conjunction with a map. See this document for details.
For example:
map $request_uri $expires {
default off;
~*\.(eot|woff|woff2|ttf|js)(\?|$) 1M;
}
server {
...
root /var/opt/data/web;
expires $expires;
...
location ^~ /one {
root /var/opt/data/alternatives;
try_files $uri $uri/ =404;
}
...
}
I have a general nginx rule to serve jpgs from their URI.
So if the URI is "http://example.com/images/1.jpg" it will serve under the form root of the site/images/1.jpg
I want to try and serve the image from alternative path if not found on the original path. How do I write the second location?
Here is what I got:
location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf|ico)$ {
try_files $uri $uri/ #fallback;
access_log off;
expires max;
log_not_found off;
}
How do I write the fallback to look for the files in another location like /home/user/anotherfolder?
You can use a named capture in the regular expression location to save the filename for later. You can cascade named locations, to try different roots:
location ~* ^/images(?<filename>/.+\.jpg)$ {
try_files $uri #other;
}
location #other {
root /path/to/alternate;
try_files $filename #fallback;
}
If there is a suitable common parent directory, you can achieve the same thing in a single location block.
location ~* ^/images(?<filename>/.+\.jpg)$ {
root /path/to/ancestor;
try_files /dir/$uri /other/dir/$filename #fallback;
}
All I'm trying to do it redirect all users, apart from my ip address, to a "site down" page using the following
location / {
rewrite (.*) /sitedown.php redirect;
allow 94.12.147.139;
index index.html index.php;
try_files $uri $uri/ #handler;
expires 30d;
}
It redirects fine but won't allow my IP to access the site either. Any help would be grateful.
the following should work:
location / {
#this is the allow/deny/redirect bit
allow 94.12.147.139;
deny all;
error_page 403 sitedown.php;
#regular site config when not denied
index index.html index.php;
try_files $uri $uri/ #handler;
expires 30d;
}
location /sitedown.php {allow all;}
How about this
location / {
if($remote_addr != Your Ip) {
rewrite ^ http://www.domain.com/sitedown.php;
}
index index.html index.php;
try_files $uri $uri/ #handler;
expires 30d;
}
What would be the nginx rewrite rule to redirect my wordpress permalink structure from /%category%/%postname%/ to /%postname%/?
In summary, you need to let NGINX know that if that file doesn't exist, to not throw a 404 error, but rather call index.php. Wordpress is smart enough to parse the URL as parameters, and serve the correct page.
Add this snippet in your server configuration block:
location / {
try_files $uri $uri/ /index.php?$args;
}
Here is a complete example from nginx.org:
# Upstream to abstract backend connection(s) for php
upstream php {
server unix:/tmp/php-cgi.socket;
server 127.0.0.1:9000;
}
server {
## Your website name goes here.
server_name domain.tld;
## Your only path reference.
root /var/www/wordpress;
## This should be in your http block and if it is, it's not needed here.
index index.php;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi.conf;
fastcgi_intercept_errors on;
fastcgi_pass php;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}