Is there any way of serving static files by only some URL path? For example, next URL pattern http://host/static/*.png has /static/ substring (path), and Nginx will serve any statics from there.
In the web server documentation I found an example:
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|js)$ { ...
and defined my Nginx config like that:
location / {
try_files $uri $uri/ /index.html;
}
location /apib {
#some proxy_pass
}
location /apim {
#some proxy_pass
}
location /api {
#some proxy_pass
}
I try to add additional location for */static/*.* with root dir /var/www/some_statics.
location ~* ^/static/.+\.(png|whatever-else)$ {
alias /var/www/some_static;
expires 24h;
}
location / {
# regular rules
}
Hand written, may contain mistakes.
If you want to extend the rules to match anything/something/static/*.png just remove the ^ in the patten.
location ^~ /static/ {
alias /var/www/some_static;
}
Related
I am trying to write a Nginx config so that:
If the URL is exactly /Site/ it must serve C:\Site\index.html
If the URL is /Site/something/else it must serve C:\Site\something\else (fallback to index.html if it doesn't exists) BUT only if /something/ is different from /api/ and /dev/
If the URL is /Site/api/something/else it must redirect the exact request to another server otherserver/api/something/else
If the URL is exactly /Site/dev/ it must serve C:\Site-Dev\index.html
If the URL is /Site/dev/something/else it must serve C:\Site-Dev\something\else (fallback to index.html if it doesn't exists) BUT only if /something/ is different from /api/
If the URL is /Site/dev/api/something/else it must redirect the exact request to another server otherserverdev/api/something/else
So the key point here is that:
/Site/ and /Site/dev are two different websites
Each one has its own .../api endpoint
So far I wrote this config:
server {
listen 19001;
include mime.types;
location ^~ /Site/api/ {
proxy_pass http://otherserver;
}
location ^~ /Site/dev/api/ {
proxy_pass http://otherserverdev;
}
location = /Site/ {
root C:\Site;
try_files /index.html =404;
}
location ~ ^/Site/(.*) {
root C:\Site;
try_files $1 $1/ /index.html =404;
}
location = /Site/dev/ {
root C:\Site-Dev;
try_files /index.html =404;
}
location ~ ^/Site/dev/(.*) {
root C:\Site-Dev;
try_files $1 $1/ /index.html =404;
}
}
This doesn't work at all, I'm getting index.html in every request and also dev and nondev are mixed up.
Is there a way to achieve what I need?
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;
}
I'm running into small hick up with try_files in combination with proxy_pass (or alias for that matter).
Current config:
location /staticsrv {
alias /var/www/static/trunk/;
#proxy_pass http://static.localtest.nl/;
}
location ~ ^/staticsrv/images/gallery/(.*)$ {
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^(.*)$ /index.php/?c=media&m=index&imag=$uri;
}
However for every file it gets dropped to the rewrite rule as it doesn't exist.
Is there a "trick" (read correct config) to fix my misfortune? Or is it just not possible? Both domains will eventually be on the same server so we can work with alias and proxy_pass.
Thanks in advance
Your location ~ ^/staticsrv/images/gallery/(.*)$ needs a root or an alias to construct a local path for try_files to try. Also, you do not necessarily need a regular expression here:
location /staticsrv/images/gallery/ {
alias /var/www/static/trunk/images/gallery/;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
proxy_pass will not work with try_files as one deals with remote content and the other with local content.
I try to avoid using alias and try_files in the same location block because of this open bug.
A possible work around would be to use another intermediate URI that closely matches the document root:
location /staticsrv/images/gallery/ {
rewrite ^/staticsrv(.+)$ /trunk$1 last;
}
location /trunk {
internal;
root /var/www/static;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
I have a two locations where my app will serve static files, one is /my/path/project/static and the other is /my/path/project/jsutils/static.
I'm having a hard time getting the webserver to look in both directories for static content. Here is my entry for static location in the nginx configuration file for my app.
location ^~ /static {
root /my/path/project/static;
alias /my/path/project/jsutils/static;
index index.html index.htm;
}
I get an error that says : "alias" directive is duplicate, "root" directive was specified earlier.
I'm not sure how to go about having nginx look in both these paths for static content.
Thank you in advance for any help.
location ^~ /static {
root /my/path/project/static;
index index.html index.htm;
try_files $uri $uri/ #secondStatic;
}
location #secondStatic {
root /my/path/project/jsutils/static;
}
So first the file will be searched in /my/path/project/static and if that could not be found there, the secondStatic location will be triggered where the root is changed to /my/path/project/jsutils/static.
You may use try_files (http://wiki.nginx.org/HttpCoreModule#try_files). Assuming that you static files are in /my/path/project/static and /my/path/project/jsutils/static. you can try this:
location ^~ /static {
root /my/path/project;
index index.html index.htm;
try_files $uri $uri/ /jsutils$uri /jsutils$uri/ =404;
}
Let me know if it works. Thanks!
Just implement your configuration in nginx language:
location /my/path/project/static {
try_files $uri =404;
}
location /my/path/project/jsutils/static {
try_files $uri =404;
}
I had the exact same problem and it looks like nginx doesn't like when root is overwritten by an alias. I fixed it by firstly removing the root declaration that was inside the server section and instead declared the root and alias appropriately directly in the location sections (note the commented out lines):
server {
# root /usr/share/nginx/html;
location /logs/ {
root /home/user/develop/app_test;
autoindex on;
}
location /logs2/ {
# root /home/user/branches/app_test;
alias /home/user/branches/app_test/logs/;
autoindex on;
}
}