nginx proxy_pass to Jboss+Spring/Websphere+Portal projects - spring

I have an nginx up at the front serving as a proxy to two servers, one running Websphere Portal Server and one running Spring on a Jboss server.
I'm currently having problems with the proxying of certain requests, for instance, I have the following:
server{
listen:8080;
server_name:localhost;
location /jbossSpring/ {
proxy_pass http://177.21.1.15:9000/Spring_project/;
}
location /webspherePortal/ {
proxy_pass http://177.21.1.15:9400/Portal_project/;
}
}
Now, this does the proxy from localhost:8080/jbossSpring/ and localhost:8080/webpsherePortal/ correctly, however, the pages I get keep requesting files that are located on localhost:8080/Spring_project/ and localhost:8080/Portal_project/.
Is there anyway for me to handle these in nginx? or do I have to modify the Spring/Portal projects to get the right url? (path dependencies probably?)

You may achieve this result by using http rewrite module, documented at ngx_http_rewrite_module
To give an idea, I guess your rewrites shall look like below (I haven't validated this)
server {
...
rewrite ^/Spring_project/(.*) /jbossSpring/$1 last;
rewrite ^/Portal_project/(.*) /webspherePortal/$1 last;
...
}

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)

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.

Firefox "Unable to connect" without www?

I wasn't sure whether to put this in Serverfault or on Stackoverflow; it doesn't seem to be a server issue so I though here would be best.
I am currently working on a university website, and for some reason Firefox refuses to load the site unless you use www (ex www.university.edu). Every other browser accepts university.edu and simply redirects to www.university.edu as nginx is setup to do. My nginx config:
server {
listen 80;
server_name university.edu www;
rewritei ^http://www.university.edu$request_uri? permanent;
}
server {
listen 80;
server_name www.university.edu static.university.edu m.university.edu www.university.com;
.
.
.
}
So what should happen is when a request comes in and is www.university.edu, the second block catches it and everything runs normally, but if a request comes in and is university.edu the first block catches it and redirects it to the second block. But for some reason Firefox is not doing this.
Any idea's what could be causing this issue?
Update 1:
rewritei is not mispelled. The university's nginx was changed before it was compiled to enable regex case insensitivity, and was placed under the function "rewritei". Also after playing around with the site I found figured out that if you visit the site at www.university.edu first, then try university.edu it will load, but if you clear the cache and try to visit university.edu it will not load until you visit www.university.edu.
You have a typo; "rewrite" and try removing the www.
server {
listen 80;
server_name university.edu;
return 301 http://www.university.edu$request_uri;
}
Also take a look at the pitfalls on rewrite - http://wiki.nginx.org/Pitfalls#Taxing_Rewrites

Grails Optimum way to save users avatar photos and show them in GSP?

Which folder should I use to save users avatar photos in Tomcat container, and how can I show it in view?
I know that it must be outside of war file, but I cannot access images with image tag which is outside of extracted war folder. An example on uploading and showing user profile photos is appreciated.
If they're just small avatars, you could consider persisting them to your database. When you need to display them again you can fetch them from the db and write them to the response's outputstream.
Here's an example of how to do this:
http://grails.1312388.n4.nabble.com/Load-image-from-database-and-show-it-in-a-gsp-td4644393.html
Acually Tomcat aren't good in serving static file, so it's very common to put a "frontend" in front of your Java app. Usually it's Nginx server. If you aren't using Nginx, I strongly suggest to start using it, Nginx can give you up to 5x speedup.
With Nginx you can store/and server images from any directory:
server {
location ~ ^\/(css|js|images)\/.*\.(gif|jpg|jpeg|png|ico|css|js)$ {
root PATH_TO_WEBAPP;
}
location ~ ^\/avatar\/.*$ {
root PATH_TO_AVATARS;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Where:
PATH_TO_WEBAPP is where tomcat have extracted you app (/etc/tomcat/webapps/myapp)
PATH_TO_AVATARS is your directory for storing avatars (/etc/my_avatars)
http://127.0.0.1:8080 just forward all other requests to Tomcat on localhost:8080
So, you'll be able to store avatars in own directory from Grails, and serve them through Nginx. For end user it will be a url like /avatars/myavatar.png, so you can use
resource tag as usual:
<img src="${resource(dir: 'avatars', file: 'myavatar.png')}" />

nginx - can proxy caching be configured so files are saved without HTTP headers or otherwise in a more "human friendly" format?

I'm curious if nginx can be configured so the cache is saved out in some manner that would make the data user-friendly? While all my options might fall short of anything anyone would consider "human friendly" I'm in general interested in how people configure it to meet their specific needs. The documentation may be complete but I am very much a learn by example type guy.
My current configuration is from an example I ran accross and if it were to be used woud is not much more than proof to me that nginx correctly proxy caches/the data
http {
# unrelated stuff...
proxy_cache_path /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
proxy_temp_path /var/www/cache/tmp;
server {
server_name g.sente.cc;
location /stu/ {
proxy_pass http://sente.cc;
proxy_cache my-cache;
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
}
}
Nginx has two methods to cache content:
proxy_store is when Nginx builds a mirror. That is, it will store the file preserving the same path, while proxying from the upstream. After that Nginx will serve the mirrored file for all the subsequent requests to the same URI. The downside is that Nginx does not control expiration, however you are able to remove (and add) files at your will.
proxy_cache is when Nginx manages a cache, checking expiration, cache size, etc.

Resources