Nginx: link to another server on a different port - nginx

I have an Nginx server/site installed on my Raspberry pi and runs on https://example.com.
I also have a Calibre ebook server on the same Raspberry pi that runs on https://example.com:8585. Having a port number at the end is ugly and not easy to remember.
I want my Calibre server to be accessible at https://example.com/calibre
Is there a setting in the Nginx server that I can tweak to achieve this? I am new to web server setups. Any suggestions would be helpful. Thanks!

Two simple ways. First - create location /calibre which cuts "/calibre" and pass requests to 8585 (trailng slash at end of proxy_pass is important)
server {
...
location /calibre {
proxy_pass https://example.com:8585/;
}
...
}
Second (and better I think) way - to create subdomain calibre.example.com in your DNS and make another server{} for calibre like this
server {
listen 443 ssl;
... ssl options here...
server_name calibre.example.com;
location / {
proxy_pass https://example.com:8585;
}
}

Related

Basic proxy_pass from nginx from one local ip to another local ip

I am a new user of nginx and I am following a video guide from Linode on youtube (How to Set Up an NGINX Reverse Proxy).
I have a working nginx and apache server both on port 80. I know that because when I type the ip address of both in firefox, it directs me to nginx/apache welcome page.
The youtube video configuration template is as follow (where the server_name is the linode ip) :
server {
listen 80;
listen [..]:80;
server_name 172.105.104.226;
location / {
proxy_pass http://localhost:3000/;
}
On my Proxmox machine, the nginx server is on a VM at 192.168.1.241 and the apache server on another VM at 192.168.1.243.
Looking at nginx documentation we find that this :
location /some/path/ {
proxy_pass http://www.example.com/link/;
}
should proxy all the traffic received on the nginx listening port and redirect it to the address specified by proxy pass.
With all these information, my configuration file is like this :
server {
listen 80;
listen [::]:80;
server_name 192.168.1.241;
location / {
proxy_pass http://192.168.1.243;
}
}
My understanding is that this configuration file should listen at the address 192.168.1.241 on port 80 (nginx server) and redirect it to the specified address 192.168.1.243 (apache server)/
If i understand correctly, Location / should take the request as is received on the nginx server and redirect it to the apache server.
However, when I enter 192.168.1.241 in my browser, it doesn't show the apache welcome message but shows the nginx welcome message. That means that the proxy isn't working.
My nginx understanding is extremely limited as I am just starting to learn, but to me it seems like this should work but doesn't.
Thank you for your help
It turns out that the configuration is correct.
The problem was that the webpage was cached. By forcing a full refresh, 192.168.1.241 redirected to 192.168.1.243 successfully.

How to let the backend api handle https certificate?

I'm new to nginx.
I have a machine, behind my router, that runs a server and handles correctly 80 and 443 request with Https.
Problem is that I want to host a second website on another device but I have only one IP address. I bought a raspberry pi zero to use it as a reverse proxy behind my router. I install nginx and want to redirect all the request to my other machines. Both the RPI 0 and the old machine have local IP.
To redirect requests from my router to RPI 0 and then to my old machine, I used proxy_pass. On port 80 everything works fine, but on port 443 I get a certificate error on my browser.
Is it possible to let the whole request go on the old machine and let the old machine handles the https certificate like before ? Or is it mandatory to have the certificate processed by nginx ?
Diagram of the old but functional installation
Current installation with certificate error
My configuration:
upstream backend_a {
server 192.168.0.20:80;
}
upstream backend_a_s {
server 192.168.0.20:443;
}
server {
listen 80;
server_name mydomain;
location / {
include proxy_params;
proxy_pass http://backend_a;
}
}
server {
listen 443 ssl;
server_name mydomain;
location / {
include proxy_params;
proxy_pass https://backend_a_s;
}
}
I found a solution. I need to use port forwarding. To do this in nginx, I need to use stream keyword.
stream {
server {
listen 443;
proxy_pass 192.168.0.20:443;
}
}
The stream keyword need to be at the same level as http, so I needed to edit /etc/nginx/nginx.conf source. Other solution is to manually compile a version of nginx, with the parameter --with-stream source.

Nginx Proxy for PlayFramework from port to path prefix

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"

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