I wanna to deploy my Ruby on Rails application in my local computer by Nginx and RoR web servers (like Unicorn, Thin or WEBrick).
As shown below, I wanna access to my web-app by post subdomain:
upstream sub {
server unix:/tmp/unicorn.subdomain.sock fail_timeout=0;
# server 127.0.0.1:3000;
}
server {
listen 80;
server_name post.subdomain.me;
access_log /var/www/subdomain/log/access.log;
error_log /var/www/subdomain/log/error.log;
root /var/www/subdomain;
index index.html;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
try_files /system/maintenance.html $uri $uri/index.html $uri.html #ruby;
}
location #ruby {
proxy_pass http://sub;
}
}
Everything is working fine and when I type post.subdomain.me I can see my RoR app.
Problem: When I use post.subdomain.me url I can't access to my subdomain (request.subdomain returns empty and request.host returns subdomain instaed of subdomain.me). But when I use post.subdomain.me:3000 every things work perfect (I lost half of my hairs to realize that). Why and How can I resolve it?
When you access app with port - you are accessing the rails server directly, not proxied by nginx, this is fine for debug, but usually is not well for production.
Probably host header is not passed over by client, $host defaults to nginx host
Try
location #ruby {
proxy_set_header Host $host;
proxy_pass http://sub;
}
And a 'hardcode'-way: proxy_set_header Host post.subdomain.me;
The proxy_set_header and proxy_redirect directives configure the proxy_pass directive and need to be within the same location block or inherited from the enclosing server block. You need to format your configuration file like this:
location / {
try_files /system/maintenance.html $uri $uri/index.html $uri.html #ruby;
}
location #ruby {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://sub;
}
EDIT: Assuming that nginx is not passing the information to RoR correctly, as #Vasfed suggested, try other values for proxy_set_header Host. There are three other candidates, all with slightly different meanings.
proxy_set_header Host post.subdomain.me;
proxy_set_header Host $server_name;
proxy_set_header Host $host;
Related
I have migrated to nexus 3 from nexus 2 . But then there is a problem that the nexus 3 does not support the Unzip plugin . So the workaround I came up with was to deploy a nexus 2 container and proxy all the unzip repos to the nexus 2 . Then create a redirect link when the url ends with ".zip-unzip" it redirects to the nexus 2. This could be done on the nginx configuration . And it should also preserve the nexus3 url but display the nexus2 page.
I tried to do this by defining a location block with a regex to match urls ending with ".zip-unzip" and the proxy pass of the nexus2. But it does not seem to work. I am also not sure how to make the nexus 2 also ssl encrypted at the same time.
server{
listen 443 ssl;
server_name mt-nexus.psi-mt.de;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_certificate /etc/nginx/conf.d/server.crt;
ssl_certificate_key /etc/nginx/conf.d/server.key;
include /etc/nginx/custom-errors.conf;
client_max_body_size 1G;
location / {
proxy_pass http://nexus3:8081;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 900;
}
location ~ ^"/nexus/(?<section>.+).zip-unzip$" {
proxy_pass http://nexus2:8081/$section.zip-unzip;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto "https";
}
}
I expect that when the url "https://nexus3.xyz.com/nexus/content/repositories/Releases_Unzip/xxx.zip-unzip" is passed, it redirect to the nexus 2 url link "https://nexus2.xyz.com/nexus/content/repositories/Releases_Unzip/xxx.zip-unzip" but have the url preserved of the nexus 3 i.e https://nexus3.xyz.com/...
Issue resolved by myself. you would have to use a location block but location block does not support the use of "$" when using the proxy pass. So you would have to use a rewrite inside the location block like this.
location ~ .zip-unzip/ {
rewrite ^/nexus/(.*)$ /nexus/$1 break;
proxy_pass http://nexus4unzip:8081;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
I have a simple application with two separated containers: one to the backend (api-container) and other to the frontend (front-container).
I`d like to configure ngnix to redirect all requests from domain api.myurl.com to backend container and all requests from myurl.com to the frontend container.
To do that I configured the ngnix, as showed below:
server {
listen 80;
server_name myurl.com;
location / {
resolver 127.0.0.11;
proxy_pass http://front-container:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name api.myurl.com;
location / {
resolver 127.0.0.11;
proxy_pass http://api-container:3010;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Everything works almost fine. When I access http://myurl.com everything is ok but when access another route like http://myurl.com/other the ngnix returns 404 error. This route works like a charm without ngnix.
What is wrong in my configuration?
Important: ngninx is running also in a container in the same network to other containers.
I want to configure NGINX to work as a reverse proxy to other Microservices.
I am able to forward the request from NGINX to one of the microservice
if I do curl http://xx.xx.xx.xx:8080/ call did landed on consumer-portal But
its using default location configuration /
when I comment the 1st block and configure the same code for location /consumer-portal and do curl http://xx.xx.xx.xx:8080/consumer-portal
I get :
Cannot GET /consumer-portal
I have more than 10 microservice which I want to call using NGINX.
Below is my nginx.conf file
worker_processes 4;
events {
worker_connections 1024;
}
http {
sendfile on;
upstream consumer-portal {
server xx.xx.xx.xx:9006;
}
upstream publisher-portal {
server xx.xx.xx.xx:9001;
}
server {
listen 8080;
#1st Block
#location / {
# proxy_pass http://consumer-portal;
# proxy_redirect off;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Host $server_name;
#}
#2nd Block
location /consumer-portal {
proxy_pass http://consumer-portal;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
#3rd Block
location /publisher-portal/ {
proxy_pass http://publisher-portal;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
Also, Please let me know If I can forward the request using docker container name.
e.g instead of server xx.xx.xx.xx:9006 i want to use server consumer-portal:9006
Please suggest what changes I need to do into .conf file.
location /consumer-portal {
proxy_pass http://consumer-portal;
If your proxy_pass URL is just a domain/IP/hostname and has no URI set then Nginx will pass the full client request URL to the proxy for requests matching the location block. So here your request to
http://xx.xx.xx.xx:8080/consumer-portal will be proxied by Nginx to
http://consumer-portal/consumer-portal
If your proxy_pass URL is a domain/IP/hostname which also has a URI appended then Nginx will replace the matching part of your location block from the original client request with the URI in your directive and then proxy the resulting URL to the upstream server. So if you had proxy_pass http://consumer-portal/new/location; then a request to
http://xx.xx.xx.xx:8080/consumer-portal/account would be proxied by Nginx to
http://consumer-portal/new/location/account
As you want to remove /consumer-portal from the request to the upstream proxy the solution is as simple as adding a trailing slash to your proxy_pass directive, like this:
proxy_pass http://consumer-portal/;
I am setting up a Rails app with nginx in front.
What I want is first to check if the URL makes sense for Rails then serve content of the public folder.
I can't achieve this:
upstream extranet {
server localhost:3000;
}
server {
location / {
try_files #extranet $uri;
root /var/www/extranet/public;
}
location #extranet {
proxy_pass http://extranet;
proxy_read_timeout 90;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
client_max_body_size 100m;
}
}
I get: *1 rewrite or internal redirection cycle while internally redirecting to "/" error.
It seems like try_files $uri #extranet; works but in my case it feels safer to check the Rails app first because the public folder might change.
try_files checks for the presence of a file on the local file system and cannot respond to the response code from a proxy.
Presumably, the proxy response with a 404 response if the remote page does not exist, which can be intercepted by an error_page statement.
For example:
location / {
proxy_pass http://extranet;
proxy_set_header ...
proxy_set_header ...
proxy_set_header ...
proxy_intercept_errors on;
error_page 404 = #fallback;
}
location #fallback {
root /var/www/extranet/public;
try_files $uri =404;
}
See this document for more.
What the quickest and cleanest solution if you want to proxy URL request to two different backends via proxypass based on location.
location /app1/ {
alias /var/www/ruby/public;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
try_files $uri $uri/ #ruby;
}
location #ruby {
proxy_pass http://127.0.0.1:3000;
}
location /app2/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
try_files $uri $uri/ #other;
}
location #other {
proxy_pass http://127.0.0.1:8080;
}
With this config nginx pass "/app1" or "/app2" to proxy and backend doesn't recognize the url/command ..
as for instance would like to pass to http://127.0.0.1:3000 only /messages when accessing http://<nginx>/app1/messages - but in configuration above also pass /app1/ as http://127.0.0.1:3000/app1/messages. Same goes for /app2
Try putting "/" at the end of upstream name
e.g
proxy_pass http://127.0.0.1:8080/;
Please see this post:
How to preserve request url with nginx proxy_pass