Nginx Proxy for PlayFramework from port to path prefix - nginx

I have a Play application listening on a local port :9000. There are other applications running.
I would like to server this application at a path like:
http://myhost/this-play-app -> localhost:9000
So that other apps could be nested at other paths.
I've tried the basic proxy_pass but it doesn't seem to work.
server {
listen 80;
server_name myhost;
# MMC Tool
# ----------------------------------------------------
location /this-play-app {
proxy_pass http://localhost:9000;
}
}
The play app seems to forward to the root. Is there a way to trick the play app to work within the /this-play-app path ?
Like /this-play-app/some-controller instead of /some-controller ?
Thanks

Using apps in folders isn't comfortable idea - you would need to at least prepare some dedicated config and change it each time when changing the location.
Instead as other suggested you should use subdomains, in this case each app behaves exactly the same as in the root domain and even if you will need/want to change that domain all you'll need will be change in the nginx's config.
Typical nginx's config looks like
upstream your_app {
server 127.0.0.1:9000;
}
server {
listen 80;
server_name your-app.domain.com;
location / {
proxy_pass http://your_app;
}
}
Most probably on some VPS or shared hosts you'll need to add the subdomain by some kind of admin's panel - on localhost just need add the subdomain to the hosts file.
Edit if using subdomain is not possible anyway (pity) you can workaround it anyway by config, in nginx use (as you did in question:
...
location /this-play-app {
proxy_pass http://your_app;
}
...
and then add this line into your application.conf (Play 2.1+)
application.context = "/this-play-app"
Or this in case of Play 2.4+ (info)
play.http.context = "/this-play-app"

Related

One Next.js instance for two domains - how to redirect?

Let's say I have a business offering two different types of services. I would like to have two domains, eg. example-shop.com and example-rental.com and have one Next.js server instance for both of them (so that they can use common components, styles etc.). How should I configure Next.js or the server (eg. with Nginx) to make it work?
What I've tried:
In my Next.js project, I created the subfolders /pages/shop/ and /pages/rental/. I built the project and run it on the server on port 3000. Then, I set up an Nginx reverse proxy on my server with the following redirects:
server {
listen 80;
server_name example-shop.com;
location / {
proxy_pass http://localhost:3000/shop/;
}
}
server {
listen 80;
server_name example-rental.com;
location / {
proxy_pass http://localhost:3000/rental/;
}
}
The HTML file loads correctly, but all the other files (js, css, images) are also redirected to /shop or /rental and end up with 404. How can I fix this?
My ideas:
only redirect HTML files to localhost:3000/shop or localhost:3000/rental and redirect all the other requests to localhost:3000/ (but how?)
set up Next.js so that all the resource files are stored under a separate directory - then I could do
location /resources {
proxy_pass http://localhost:3000/;
}
... but how?

Download files in remote server using reverse proxy Nginx

I have a server running with Nginx reverse proxy.
We have our application running in another server, which is served using this Nginx proxy. Below is the configuration I have used and its working fine.
location / {
rewrite ^/(.*) /$1 break;
proxy_pass http://10.0.0.121:8000;
}
I would need to download a pdf file in the application machine (10.0.0.121) , which is under /home/ubuntu/app/pdf/data-2021-03-25.pdf.
How could I make the file in application machine downloadable from the proxy server, please help.
Thanks in Advance.
I would simply install another nginx instance on 10.0.0.121 and configure it like this. NON-PROD READY!
server {
listen 8080;
server_name ...;
root /home/ubuntu/app/pdf;
location = /data-2021-03-25.pdf {
try_files $uri $uri/ =404;
}
server {
listen 8090;
location / {
proxy_pass http://localhost:8080;
}
}
}
Not tested but this server will handling the request serving the file. Then you could just use proxy_pass on the other server to proxy the request.
But beside from this option you can use a python, perl, php, java, nodejs, assembly or what ever programming language you want to use to open a http port and serve the file on an incoming request. Its really your choice.
just make sure if you're going for the proxy solution you are sanitizing the requests on your proxy. For example. With a small change in the setup above you could cheat and get any other files from your home/app directory by sending an request like curl -v localhost:8090/pdf/../other/file. So make sure you are using the root(/home/ubuntu/app/pdf/) directive and set a location matching the pdf-file on the proxy-server as well.
That worked in my demo app.

Wordpress & Nginx with Docker: Static files not loaded

I'm using Docker to serve my simple WordPress website. A nginx container and a wordpress container. Simple setup:
upstream wordpress_english {
server wordpress_en:80;
}
server {
listen 80;
server_name my_domain.com www.my_domain.com;
location / {
proxy_pass http://wordpress_english;
}
}
Problem: Static files (css, js and images) are not loaded.
The output from the browser console shows a 404:
http://wordpress_english/wp-content/themes/twentyfifteen/genericons/genericons.css?ver=3.2
Its easy to spot the problem: The browser looks for the static files at wordpress_english (the nginx upstream name), instead of my_domain.com
How can I fix this problem?
This is not a nginx problem, but a WordPress problem.
Solution:
In wp-config.php, add the following two lines:
define('WP_HOME','http://my_domain.com');
define('WP_SITEURL','http://my_domain.com');
During the WordPress installation, WordPress automatically sets WP_HOME to nginx upstream name. The above solution overwrites the default setting.
Seems to be an issue in your nginx config file.
When declaring your server my_domain you provide location / with proxy_pass wordpress_english. I don't know a lot on nginx, but I don't see any declaration of path in your server my_domain and is root is linked to wordpress_english. Seems normal that he is looking for files in wordpress_english and not in you server. (In fact, I guess he is looking in your server but your server tells to look in wordpress).
Not sure about it cause I don't know well nginx and proxy_pass functions.

Deployement of Play! web app with Nginx

I'm trying to do some deploy on my webb app project with Play! and Nginx.
I followed the guide on Play! web site but it dosen't work. Sombody get to make it works?
Wich are the differences?
PS: My web app work, if I it localhost:9000 I get the page and if I hit only localhost I get the welcome message from Nginx, but I can't make them work together.
Thanks
The problem is that you have changed the default port to 9000. Only using localhost/projectname is going through port 80. In order to do it that way you should change your default port to port 80.
I'd say you only need to do a proxy pass in nginx, replace the example.com with your website name.
server {
server_name example.com;
proxy_pass http://localhost:9000;
}
if you don't want to create a separate server block, you can use a location block
location /webapp {
proxy_pass http://localhost:9000;
}
This way it would work by using http://localhost/webapp
Here is my nginx configuration:
upstream play_app {
server 0.0.0.0:9000;
}
server {
listen 7000;
location / {
proxy_pass http://play_app;
}
}
And then you just need to visit your website via: IP:7000

Struggling with location blocks in nginx config

I got a new slice off slicehost, for the purposes of playing around and learning nginx and more about deployment generally. I installed a ruby app on there (which i'll call app1) which uses passenger. I made it the default app to use for that server with the following server block in my nginx config:
server {
listen 80;
server_name <my server ip>;
root <path to app1 public folder>;
passenger_enabled on;
}
This works fine. However, i want to try a few different apps out on this slice, and so thought i would set it up like so:
http:///app1
http:///app2
etc. I thought i would be able to do that by adding a location block, and moving the app1 specific stuff into it like so:
server {
listen 80;
server_name <my server ip>;
location ^~ /app1 {
root <path to app1 public folder>;
passenger_enabled on;
}
}
However, on doing this (and restarting nginx of course), going to the plain ip address gives the 'welcome to nginx' message (which i'd expect). But, going to /app1 gives an error message:
404 Not Found
The requested URL /app1 was not found on this server.
This is distinct from the error message i get when i go to another path on that ip, eg /foo:
404 Not Found
nginx/0.8.53
So, it's like nginx knows about that location but i've not set it up properly. Can anyone set me straight? Should i set up different server blocks instead of using locations? I'm sure this is simple but can't work it out.
Cheers, max
What you're after is name virtual hosting. The idea is that each domain is hosted on the same IP, and nginx chooses the virtualhost to serve based on the Host: header in the HTTP request, which is sent by the browser.
To use name virtual hosting, use the domain you want to serve instead of your server's IP for the server_name directive.
server {
listen 80;
server_name app1.com;
location / {
root /srv/http/app1/public;
passenger_enabled on;
}
}
Then, to host more apps on the same box, just declare a separate server { } block for each one.
server {
listen 80;
server_name app2.com;
location / {
root /srv/http/app2/public;
passenger_enabled on;
}
}
I'm using unicorn instead of passenger, but the vhost part of the structure is the same for any backend.
The global nginx config (which on its own hosts nothing): https://github.com/benhoskings/babushka-deps/blob/master/nginx/nginx.conf.erb
The template wrapper for each virtualhost: https://github.com/benhoskings/babushka-deps/blob/master/nginx/vhost.conf.erb
The details of the unicorn virtualhost: https://github.com/benhoskings/babushka-deps/blob/master/nginx/unicorn_vhost.common.erb
I fail to see the real problem here tho,
in order for you to figure that out
you need to view the nginx log files on most systems at:
/var/log/nginx/
and open the relevant access file here(might be error.log)
in there you can see what url nginx exactly tried to access and why did it fail.
What I really think is happening, that you got the root path wrong,
maybe it should be alias instead because
if you are proxifying the connection to another app, it might get the
"app1" word in the url instead of a direct one.
so please try:
server {
listen 80;
server_name <my server ip>;
location /app1 {
alias <path to app1 public folder>;
passenger_enabled on;
}
}
and see weather it works and also try to view the logs first to really determine whats the problem.
I think its just a slight syntax problem:
location ~ ^/app1 { ...
should work, or a little more efficient:
location = /app1 { ...
One problem is that your Rails app probably wasn't designed to run from a subdirectory. Passenger has a directive that will fix this:
passenger_base_uri /app1;
However, running Rails apps in subdirectories is somewhat non-standard. If you can, a better option may be to set up subdomains using nginx's virtual hosts.
It seems that you want to host more apps on the same server with base uri. Try this:
root /srv/http/;
passenger_base_uri /app_1;
passenger_base_uri /app_2
Also under /srv/http, create 2 symlinks:
ln -s /srv/http/app_1 /srv/http/app1/public
ln -s /srv/http/app_2 /srv/http/app2/public
The app1 can be accessed under: http://domain.com/app_1.
Here is more for reading: http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_rack_to_sub_uri

Resources