NGINX: Rewrite image location - image

I am using NGINX for a project, and I have WordPress installed.
I would like to hide the wp-content directory and want to rewrite the image URLs for images.
I want to support multiple extensions (jpg,jpeg,gif,png).
Another thing that I needed is a dynamic folder, it contains the ID of a user.
I used the following code but without luck, The number 1 should also become dynamic but for now I want to start with a simply rewrite, to keep things simple.
location /images/auctions/1/(.*).(png|jpg|gif) {
rewrite /wp-content/plugins/myplugin/uploads/auctions/1/(.*).(png|jpg|gif) /images/auctions/1/$1.$2;
}
I searched for NGINX rewrite and some other search queries but nothing that really answers my needs.

Ok I think I got some kind of way that works for me (only not yet with the dynamic folder /1/ but I probably will fix that later).
Here is the code for the nginx config:
location ~ ^/images/(.*)$ {
try_files $uri $uri/ /wp-content/plugins/myplugin/uploads/$1;
}
Edit:
Below the code that also handles the dynamic ID folder of the user:
location ~ ^/images/(.*)/(.*)$ {
try_files $uri $uri/ /wp-content/plugins/veilgarant/uploads/$1/$2;
}

Related

Extending Nginx config on Beanstalk doesn't rewrite urls properly

I have an existing Laravel API application running on Beanstalk. It's been lagging in updates on EBS, so currently I'm in the process of upgrading the platforms and CI/CD for this app. There one remaining problem I'm running into, which leaves me scratching my head at the 'but it should work'-level.
What I want
All URLs containing https://example.com/index.php/endpoint to be redirected to https://example.com/endpoint and show the same content as https://example.com/index.php/endpoint would (incl. subsequent the URL's slugs)
How I'm trying to do this
Due to this wonderful answer by cnst, I have the configuration below that seems to work for many (incl. some other online sources).
server{
index index.php;
if ($request_uri ~* "^(.*/)index\.php/*(.*)$") {
return 301 $1$2;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
# Remove from everywhere index.php
if ($request_uri ~* "^(.*/)index\.php(/?)(.*)") {
return 301 $1$3;
}
}
if (!-d $request_filename) {
rewrite ^/(.+)/$ /$1 permanent;
}
if ($request_uri ~* "\/\/") {
rewrite ^/(.*) /$1 permanent;
}
}
I'm putting this configuration in a file located at my_project/.platform/nginx/conf.d/proxy.conf, which according to AWS' documentation, should upload with the project and extend the nginx configuration. As far as I can tell, it does pick it up, since any typo will result in an error after eb deploy. I can also see on the server it has been added to /etc/nginx/conf.d/proxy.conf.
The Problem
Even though the extending proxy.conf is being deployed and the configuration in it seems to be picked up, the application won't pick up the rewrite and leave the application URLs running with the index.php instead of the rewrite.
https://example.com/index.php/endpoint → works
https://example.com/endpoint → results in a server generated 404
Nginx logs show 2021/02/12 14:23:24 [error] 7523#0: *35 open() "/var/www/html/public/api" failed (2: No such file or directory) which tells me it has searched for a file and never tried running it through index.php.
The Questions
What am I missing in my configuration?
Or is it something about EBS that I overlooked or misunderstood?
Is the index.php angry since I'm trying to hide its face from public view?
Solution moved from the question to an answer:
I gave it a weekend to see if anyone would know and went back to work.
First thing, I did is see if Beanstalk was picking up any
configuration, so I put an invalid variable in and see if that would
break the server. It didn't...
Second, I checked if my Beanstalk instance was actually using Nginx
(default) or got switch to Apache (httpd) for some reason (it includes
both). Via its GUI config I could easily tell it's Nginx.
Third, I viewed the nginx.conf on the server and checked how other
.conf files were being included. Part of it is seen here;
http {
[...]
include conf.d/*.conf;
map $http_upgrade $connection_upgrade {
[...]
}
server {
listen 80 default_server;
access_log /var/log/nginx/access.log main;
[...]
# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/*.conf;
}
}
Here lays the problem; I was including a file at the conf.d/*.conf
level with a second nginx server configuration block, which is
effectively overwritten with the standard server configuration block
by Beanstalks own config.
So there's two solutions here;
override the entire nginx.conf by including a new .platform/nginx/nginx.conf in your project, where you extend the
server block with your own config
or, in my opinion more gracefully, add .platform/nginx/elasticbeanstalk/proxy.conf to your project,
extending the server block specifically (but remove any server
blocks from your own config)
Solution 2 will gard that AWS can always update its default nginx.conf
without you having to watch out for it (unless they change the
location of the elasticbeanstalk configs).
I did try putting my configuration in
.platform/nginx/elasticbeanstalk/proxy.conf before, but that would
break the server, since I was including a server block, causing it
to double nest.
Lesson here;
add .platform/nginx/nginx.conf to override your entire Beanstalk Nginx configuration
add .platform/nginx/conf.d/your_conf.conf for any extensions to the http block
add .platform/nginx/conf.d/elasticbeanstalk/your_conf.conf for any extensions to the server block (or nesting within)

query parameter change into "query_string" at laravel 5.5 and php 7.4

My website uses Laravel 5.5 and PHP 7.4.
Browser should be sending URL and query parameters as shown below,
[correct url of my site]?mode=specific&number=ID
but my controller receives it like this:
[correct url of my site]?query_string=
I can confirm this by adding $request->fullUrl() into my controller.
Same code works in another environment,
the only difference is PHP = 7.0 and it does receive correct query parameters.
I'm sorry bothering SO for such a ridiculous question.
I just miss $ at nginx server configuration
try_files $uri $uri/ /index.php?query_string; <---- wrong
try_files $uri $uri/ /index.php?$query_string; <---- correct
Half a year ago my server is broke and then I quickly setuped current server and I missed this "$".
Thank you all.

Multiple Laravel Projects on a single domain with NGINX

At work we have a single staging server with a staging domain, something like https://staging.example.com. We recently decided to switch from Apache to NGINX on a new server and we're having issues with our Laravel routing.
All of our laravel apps sit in sub-directories on the staging server, like so.
https://staging.example.com/app1/public
https://staging.example.com/app2/public
I've tried configuring the NGINX conf file as specified in the Laravel docs but get a 404 when accessing any 2nd level route, i.e. https://staging.example.com/app1/public/a/b
Using something like the below config, I can access all the routes in an app.
location #laravel {
rewrite /app1/public/(.*)$ /app1/public/index.php?$1;
}
location / {
try_files $uri $uri/ #laravel;
}
However, we have many apps hosted on this server and we don't want to have to update an NGINX conf file every time we want to add an app to the server.
Is there a way of constructing a rewrite to apply to any sub-directory and keep Laravel's routing system working?
Note: I've also tried this rewrite rewrite (.*)/(.*)$ $1/index.php?$2 and that doesn't work for 2nd level routes.
Your first capture is probably too greedy, you should limit it by using:
rewrite ^(/[^/]+/[^/]+)/(.*)$ $1/index.php?$2 last;
See this useful resource on regular expressions.

Nginx cache static files from different aplications

I use WordPress as a home page (mysite.com) and Django for the rest (mysite.com/pages). I have single nginx config file for both of them and its working fine. Moreover, they reside in a single server block.
Here are some parts of my configuration:
server {
...
root /var/www/wordpress;
...
location /static/ {
alias /home/username/Env/virtenv/mysite/static/;
}
}
With this both WordPress and Django static files are served.
Now I want to cache all static files for 7 days in the browser. If I put this in addition:
location ~* \.(jpg|jpeg|png|svg|gif|ico|css|js)$ {
expires 7d;
}
then the WordPress static files are properly cached, but Django's static files are not even served.
I know this is because the /static/ location is never reached and then Nginx searched Django's files in the root directive which is on server block level and which points to the WordPress location.
I can remove the cache location and add expires 7d; in the /static/ location. This will in opposite cache only the static files of Django.
But how can I make both static resources to be cached for a week?
Finally I was able to cache both static files - of Wordpress and Django.
For requests starting with /static/, I found a way to make Nginx use the /static/ location and not the general static files location, which has the purpose to only cache Wordpress static files.
Its so simple: just use the location modifier ^~.
As this wonderful article of DigitalOcean says:
The block modifier ^~ means that if this block is selected as the best non-regular expression match, regular expression matching will not take place.
Here is the working version of the two location blocks:
location ~* \.(?:jpg|jpeg|png|svg|gif|ico|css|js)$ {
# Cache Wordpress or any other public static files
# of those types for a week in the browser
expires 7d;
}
location ^~ /static/ {
alias /home/username/Env/virtenv/mysite/static/;
# Cache Django's static files for a week in the browser
expires 7d;
}
All requests with mysite.com/static/... will match the /static/ location and will not continue to any other regex location.
And for example requests as mysite.com/wp-content/themes/a-theme/style.css?ver=4.7.2
will match the regex location.

ProxyPass GET parameters via image using Nginx

I have an image that is served as static file using Nginx, but I need to call it with different GET parameters. Is it possible to proxypass those parameters to different server BUT (Here is the trick) return the static image back?
Thank you in advance.
If I'm understanding you correctly, you want to pass the request arguments to a different server, but mask this from the user by returning a static image?
If you can make the remote server return a 404, then this should work:
root /path/to/webroot;
location #otherserver {
include proxy_params;
proxy_pass http://some.other.server;
}
location /image.jpg {
try_files #otherserver /real_image.jpg;
}
You could probably leverage the error_page directive to similar effect.

Resources