nginx try_files from proxy'd app, then nginx - nginx

I'm attempting to have nginx reverse proxy static files from an application if the application is serving them, else serve them itself. Currently, I have this configuration:
upstream app_server {
server unix:/tmp/gunicorn.sock fail_timeout=0;
}
server {
listen 8080;
server_name example.com;
access_log /var/log/nginx.access.log;
error_log /var/log/nginx.error.log;
keepalive_timeout 5;
location /static {
try_files $uri #proxy_to_app;
alias /path/to/__static;
sendfile off;
}
location / {
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
This works if the files don't exist in /path/to/__static; it sends the request to the application server. However, if the files also exist in /path/to/__static, nginx serves the files itself.
Reversing the try_files line (try_files #proxy_to_app $uri) fails in both cases. If the client requests /static/css/test.css, the application receives a request for /css/test.css, and it never seems to try /path/to/__static even though the application returns a 404.
Updated to include full configuration.

location /static/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
proxy_intercept_errors on;
error_page 404 =200 /local$uri;
}
location /local/static/ {
internal;
alias /path/to/__static/;
}

Related

Nginx - location block misconfigured?

I have a location block inside of my sites-enabled example.conf that should be routing /testing to a 503 error html page but instead for some reason its hitting my app instead of nginx
[2020-06-30T20:36:13.821768 #6059] FATAL -- : [fc9cb972-f314-4a87-89d9-8334521767b3] ActionController::RoutingError (No route matches [GET] "/testing"):
that is a log line from my actual rails app - why is it even getting this far vs nginx routing to where I thought I told it to???
my nginx .conf
server { listen 443 ssl;
server_name status.* www.status.*;
# SSL
ssl_certificate_key /etc/nginx/ssl/server_example.com.key;
# logging
access_log /var/log/nginx/status.access.log;
error_log /var/log/nginx/status.error.log;
# security
include security.conf;
# reverse proxy
location / {
if (-f /opt/staytus/staytus/maint.on) {
return 503;
}
port_in_redirect off;
proxy_pass http://example.com:8787/;
}
error_page 503 #maintenance;
location #maintenance {
root /usr/share/nginx/html
rewrite ^(.*)$ /Performing-Maintenace.html;
}
location = /testing/ {
return 500;
}
}
server {
listen 80;
server_name www.status.* status.* 11.22.123.456;
root /opt/staytus/staytus/public;
client_max_body_size 50M;
# SSL
ssl_certificate_key /etc/nginx/ssl/example.com.key;
port_in_redirect off;
return 301 https://example.com$request_uri;
location #puma {
proxy_intercept_errors on;
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 http;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://example.com:8787;
}
}

Rewrite nginx url

I am facing problem with rewriting url in nginx.
The issue is if the url contains domain/.well-known/acme-challenge/ it should be replaced by domain/folder/.well-known/acme-challenge.
How can I rewrite nginx for this so that it points to proper location.
The request for the nginx configuration works with this url:
domain/folder/.well-known/acme-challenge
but I want it to redirect when it finds something like
domain/.well-known/acme-challenge/
Here is my nginx conf:-
#upstream jboss {
# server domain:8080;
#}
server {
listen ip:80;
server_name domain;
access_log /var/log/nginx/domian_access.log;
error_log /var/log/nginx/domain_error.log warn;
# location ~* .(jpg|jpeg|png|gif|ico|css|js)$ {
# expires 365d;
#}
location /folder/ {
# ModSecurityEnabled on;
# ModSecurityConfig modsecurity.conf;
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;
# proxy_set_header X-Forwarded-Host $host;
# proxy_set_header X-Forwarded-Server $host;
proxy_pass http://ip:8080/folder/;
proxy_connect_timeout 6000;
proxy_send_timeout 6000;
proxy_read_timeout 6000;
send_timeout 6000;
index Main.jsp index.html;
}
#index index.html ;
# try_files $uri $uri/ =404;
#error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root html;
#}
I don't think you need to rewrite the url, but to send the url to the correct folder.
.well-known/acme-challenge is known to be a challenge for ssl certificates that are made automatically (lets'encrypt), so simply set the alias to the folder where your bot writes the "challenge" and you are good to go.
location /.well-known/acme-challenge {
auth_basic off;
alias /directory/to/challenge;
default_type text/plain;
}
That way it will "accept" and respond the challenge correctly
Even if you keep wanting to rewrite it, set a redirec to to domain/folder/$request_uri line:
location /.well-known/acme-challenge {
return 301 http://$host/folder/$request_uri;
}

Nginx SPA Serving Static Files, Proxying API Calls, and Rewriting to /index.html

So, I'd like to have an nginx.conf that...
Serves all /static requests directly
Proxies all /api requests to another local server (port 8200)
Serves /index.html for all other requests (so, /contact/123 would really serve /index.html)
Here is my current config...
server {
listen 80;
server_name www.xyz.io;
root /opt/xyz/www;
location / {
try_files $uri $uri/ #backend;
}
location #backend {
proxy_pass http://127.0.0.1:8200;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
I'm really not clear how to have all other requests serve /index.html though. Ideas?
Try this:
server {
listen 80;
server_name www.xyz.io;
root /opt/xyz/www;
# index
index index.html;
# $uri, index.html
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://127.0.0.1:8200;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}

Why I'm getting frequent 504 Time out error?

my nginx configuration is as:
upstream app_server {
server unix:/run/DigitalOceanOneClick/unicorn.sock fail_timeout=0;
}
server {
listen 80;
root /home/rails/rails_project/public;
server_name example.com www.example.com;
index index.htm index.html;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mp3|flv|mpeg|avi)$ {
try_files $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
proxy_read_timeout 180;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
And unicorn configuration file is as:
listen "unix:/run/DigitalOceanOneClick/unicorn.sock"
worker_processes 4
user "rails"
working_directory "/home/rails/rails_project"
pid "/run/DigitalOceanOneClick/unicorn.pid"
stderr_path "/var/log/unicorn/unicorn.log"
stdout_path "/var/log/unicorn/unicorn.log"
I'm getting "504 Gateway Time-out" error frequently. I'm not getting any idea about the problem. Server OS is Ubuntu 14.04 with rails5.1.3, nginx and unicorn. Thank you.

Setting Up Uberjar with Nginx on Digital Ocean VPS

I used the instructions on the following link:
"Hosting Clojure Web Apps in 7 Easy Steps"
I know the uberjar works because i tested it both on my dev machine and the VPS.
It's just that Nginx doesn't seem to be able to find it.
I suspect that it has something to do with this site code:
# Web sockets
location /chsk {
proxy_pass http://backend/chsk;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
...but I don't know how to correct it...thanks for the help!
One other thing: on the "upstream backend" in the site file i tried both 127.0.0.1:3000 AND 0.0.0.0:3000 with no success.
Here's the default site config:
server {
# Replace this port with the right one for your requirements
listen [::]:80 ipv6only=off;
# Multiple hostnames separated by spaces. Replace these as well.
server_name clmitchell.net www.clmitchell.net main.clmitchell.net
books.clmitchell.net dna.clmitchell.net help.clmitchell.net
history.clmitchell.net svcs.clmitchell.net;
server_name_in_redirect off;
root /data/nginx/www/$host;
error_page 401 /error/401.shtml;
error_page 402 /error/402.shtml;
error_page 403 /error/403.shtml;
error_page 404 /error/404.shtml;
error_page 500 501 502 503 504 /error/500.shtml;
location ^~ /error/ {
internal;
root /data/nginx/www/www.clmitchell.net;
}
access_log /var/log/nginx/$host-access.log;
error_log /var/log/nginx/error.log;
index index.php index.html index.htm default.html default.htm;
# Support Clean (aka Search Engine Friendly) URLs
location / {
try_files $uri $uri/ /index.php?$args;
}
# serve static files directly
location ~* \.(jpg|jpeg|gif|css|png|js|ico)$ {
access_log off;
expires max;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ \.scm$ {
include fastcgi_params;
fastcgi_intercept_errors on;
# By all means use a different server for the fcgi processes if you need to
fastcgi_pass 127.0.0.1:9981;
}
location ~ /\.ht {
deny all;
}
}
I removed history.clmitchell.net from the list of server names.
Here's the current history site config:
upstream backend {
server 104.131.29.212:3000 fail_timeout=0;
}
server{
listen [::]:80 ipv6only=off;
server_name localhost history.clmitchell.net;
access_log /var/log/hist_access.log;
error_log /var/log/hist_error.log;
root /var//resources/public;
# Web sockets
location /chsk {
proxy_pass http://backend/chsk;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Static assets
location / {
try_files $uri #backend;
}
# The backend server
location #backend {
proxy_pass http://backend;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
}
}
there was a duplicate "listen" directive on the history site config, which i removed...but for some reason I'm still getting the error: '
sudo nginx -t
nginx: [emerg] duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/hist:6
nginx: configuration file /etc/nginx/nginx.conf test failed
Please try
proxy_pass http://backend;
And make sure you can access http://127.0.0.1:3000/chsk if your upstream is defined as below
upstream backend {
server 127.0.0.1:3000;
}
Or if we has only one backend server we can just use proxy_pass without upstream backend defined. e.g.
proxy_pass http://127.0.0.1:3000;
I learned a new lesson today: no two sites on a Nginx web server can have the same listen port!
I moved the new site to a new port and updated all the links...PROBLEM SOLVED!

Resources