nginx - how to have proxy pass render a subdomain on the page? - nginx

We have a PHP server with Nginx running. On a separate server hosted by Vercel we have a Next.js app running. We've deployed the Vercel app to a subdomain of our main domain: https://vercel.employbl.com/ Our domain is hosted by Cloudflare and we linked it to Vercel by adding a CNAME record like so:
What I'm trying to do is have our main jobs page instead Render the jobs page of the Vercel app. So user enters https://www.employbl.com/jobs but the Next.js app with the matching path https://vercel.employbl.com/jobs renders instead while keeping "employbl.com/jobs" as the URL.
This is the Nginx config we have currently using proxy_pass. Unfortunately I'm getting a 404 error from Vercel when I navigate to "employbl.com/jobs" using this Nginx config:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /jobs {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://vercel.employbl.com/jobs;
}
This renders the page from Vercel: 404 - Code: DEPLOYMENT_NOT_FOUND but the site is working at the URL provided in the nginx config.
How can I configure Nginx so that when the user navigates to "employbl.com/jobs" the https://vercel.employbl.com/jobs page renders?

Try it like this, with trailing slash after the location directive (/jobs/). Then take /jobs off the proxy URL. I think your location path /jobs is being handed to the proxy_pass and ending up doubling the /jobs/ part somehow. Because with no trailing slash it passes that forward. So try:
location /jobs/ {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://vercel.employbl.com; #removed jobs
}
Edit: On my server I can only get it to work this way. Both location directive and proxy URL end in a slash. From what I've read, this should make it drop the location directive path, instead of passing it on.
location /jobs/ {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass https://vercel.employbl.com/jobs/;
}

We ended up getting it working like this. Needed a separate entry to point to files for the _next directory that holds our assets. I think the primary fix was having resolver 8.8.8.8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /jobs {
resolver 8.8.8.8;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://vercel.employbl.com/jobs;
}
location ~ ^/_next/(.*)$ {
resolver 8.8.8.8;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://vercel.employbl.com/_next/$1;
}

Related

Nginx catch and rewrite all requests begining with /api to proxy

I want to redirect all requests that have /api/ (http://example.com/api/) to my proxy application and drop the /api in the process. I have tried this but I get a 404 when curling it. It doesn't reach the application, I'm thinking it's something to do with the rewrite but I'm not sure if it's correct.
location ~ ^/api {
rewrite ^/api/(.*) /$1 break;
proxy_pass http://127.0.0.1:8070;
}
The following works when hard-coded. It redirects me to my application /error.
location = /api/error {
proxy_pass http://127.0.0.1:8070/error;
}
For example, I want http://example.com/api/login to hit my proxy application like so http://example.com/login.
This works for me. The $1$is_args$args part passes every thing after the /api in the URL. Now when hitting my domain, example.com/api/something passes /something to my proxy application.
location ~/api(.*)$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8070$1$is_args$args;
}

NGINX: Proxy to blog on wordpress

I have a wordpress based site with blog in /blog location. I wanted to re-use this blog from an other site, but I am redirected to www.example.com. My nginx config of the location is:
location ~ ^/blog {
resolver 8.8.8.8;
proxy_pass https://www.example.com$request_uri;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
How should this config look like?
To make WordPress respond correctly to two different hostnames, you will need to make it hostname agnostic.
Change the WordPress configuration so that the hostname is not part of the HOME and SITEURL parameter values. For example, use a value /blog, instead of https://www.example.com/blog.
See this document for more.
Regarding the location block. It can be simplified as follow:
location ^~ /blog {
resolver 8.8.8.8;
proxy_pass https://www.example.com;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}

Avoid duplication in password protect URL with proxy in nginx

I have a Flask application served using gunicorn, and with NGINX on top of it. I want to use Basic Authentication (user/password) to protect all URL's starting with /admin, which is the back office, but still continue serving all other URLs with gunicorn without password.
Here is my current NGINX config:
server {
listen 80;
server_name example.com;
charset utf-8;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /admin {
auth_basic "Administrator Login";
auth_basic_user_file /home/app/.htpasswd;
# the following four directives are duplicated :(
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
If I don't duplicate the proxy_* directives in the second location block, then the URLs starting with /admin doesn't get forwarded to gunicorn and I get a 404.
Is there any way to avoid the configuration duplication? I tried location nesting but apparently in the end NGINX only "executes" a single location block.
The proxy_pass must be within the location block. However, there's no need to duplicate the proxy_set_header directives, they can be moved into the server block. So your mistake was simply the assumption that proxy_pass could live in the server block :-)

Using nginx as reverse proxy for apache and want more htaccess control

I'm using nginx in a reverse proxy configuration with apache2. I have used other, preconfigured web servers in this way and enjoyed complete control over redirects from an .htaccess file.
My current configuration does not allow for this. First, I'll explain what happens.
Let's say I want to redirect /google to http://google.com. I add the following line to my .htaccess file.
redirect 307 /google http://google.com
I know it's working because I can test with curl from my server. This is hitting apache directly, behind the proxy.
curl -I localhost:8080/google
and I get a 307 as I would expect.
But if this request hits nginx from the outside, nginx knows there is no such file in the web root and responds 404.
Is there a configuration change I can make to remedy this?
Here's my nginx configuration file for this vhost.
server {
listen 80;
root /var/www/mywebsite.com/html;
index index.php index.html index.htm;
server_name mywebsite.com;
access_log /var/log/nginx/mywebsite.com.access.log;
error_log /var/log/nginx/mywebsite.com.error.log;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
location ~ /\. {
deny all;
}
}
It seems that I might need to take the reverse approach and proxy everything but exclude certain file types from the proxy.
Thanks for advice folks!
If you want to forward that request to /google to apache, then just change the location ~ \.php$ pattern to include the request you desire:
location ~ (/google/?)|(\.php)$ {
On the other hand if you want nginx to handle the redirect you can add new rule:
location ~ /google {
return 307 http://google.com;
}
Just make sure to put it before the location block which contains try_files.
EDIT:
To forward all requests that don't hit a file use this:
location /
{
if (!-f $request_filename) #test if a static file does not exists
{
# forward the request if there is no file to serve:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
Additionally if you want for nginx to also serve entire directories then add another condition:
!-d $request_filename
Also note that if you want only specific files to be served then instead location / use the pattern to match those files. For example if you want to serve only jpg's and css's use
location ~ \.(jpg|css)$
EDIT2: Here you have a simplified version of your script, which is also more robust - lets you serve only the types of files you want:
server {
listen 80;
server_name test.lcl;
root /home/www/test;
location / {
try_files $uri $uri/ #apache;
}
location #apache
{
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}

Nginx - Forward root-level URL (eg, favicon.ico) to Amazon S3?

I'm trying to configure my nginx server to serve root level assets, like www.domain.com/favicon.ico, from S3.
I think, but am not sure, that I'm supposed to proxy_pass to accomplish this. I'm also stuck on the location regex:
server {
listen 80;
server_name *.domain.com
# This is where I'm trying to catch URLs like /favicon.ico
location ~* /*\.(xml|txt|png|ico)$ { # wrong
proxy_pass http://<s3_bucket>?? # wrong
}
# Everything else goes to gunicorn/Django.
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
It's right to do this using proxy_pass. If you have problem you can set error log to debug level to trace the problem. From the trace log, you should focus on two points:
Whether /*\.(xml|txt|png|ico)$ match your requests?
Whether the url being passed is right and access successfully?

Resources