nginx serve static files and run server on same host - nginx

Almost have this working how I want - basically I'm trying to serve static files on host/static (including directory listings), and serve to another backend for any non-file request (including the default site). The config below seems to do this, but the ONE problem remaining is that I can't get to the root static dir with host/static - a trailing slash is required! Any ideas?
My config:
location / {
try_files /static/$uri /static/$uri/ #myserver;
}
location /static/ {
alias /var/www/static_files/;
autoindex on;
disable_symlinks off;
}
location #myserver {
proxy_pass http://localhost:8081;
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_connect_timeout 150;
proxy_send_timeout 100;
proxy_read_timeout 100;
proxy_buffers 4 32k;
client_max_body_size 8m;
client_body_buffer_size 128k;
}

As #RichardSmith said - to get this behavior, just remove the trailing slash from the location and alias statements.

Related

Why do I get 404 on nginx reverse proxy?

Below is my config and I'm getting 404 on all routes defined apart from the well-known route and I don't understand why.
If I make a request to http://example.tech/connect I get a 404 and if I make a request to http://api.example.tech I also get a 404.
I can't see where I've gone wrong as this looks like it should work!
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#REMOVE REFERENCE TO FILES THAT HAVE "server" and "location" blocks in them so we can do it all in this file
#include /etc/nginx/conf.d/*.conf;
# issue with ip and the nginx proxy
real_ip_header X-Forwarded-For;
set_real_ip_from 0.0.0.0/0;
server {
listen 80;
listen [::]:80;
server_name example.tech;
location /.well-known/openid-configuration {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
location /connect {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
location /auth {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
}
server {
listen 80;
listen [::]:80;
server_name api.example.tech;
location /auth/ {
proxy_pass https://myapp.net;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
#proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-Host $host;
#proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
}
}
}
Needed a forward slash on the end of the proxy_pass for some reason
You need a specific uri in proxy_pass directive, not a backslash. But in your case here, a backslash is acting as the specific uri. Nginx replaces '/auth'(for example) with '/'(you've added).
In fact, the answer you put is right, turning proxy_pass http://myapp.net; to proxy_pass http://myapp.net/;.
The reason is that proxy_pass would work in two different ways with/without a specific uri. More details about this directive on nginx.org. Blow is some content quoted in that link.
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI
matching the location is replaced by a URI specified in the directive:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original
request is processed, or the full normalized request URI is passed
when processing the changed URI:
location /some/path/ {
proxy_pass http://127.0.0.1;
}
In your case, without URI in proxy_pass directive, so /auth would be passed to backend server. Unfortunately, your backend server does not have the /auth resource, so 404 is returned. If your backend server does have /auth to be processed, you would never get 404 error while requesting uri /auth.
Here are two examples, which hopefully clarify things.
location /some-path {
proxy_pass http://server:3000;
}
In this case the proxied server (target) must handle the route /some-path. If handling something else, like / only, it will return an error to Nginx.
One solution is to add a trailing / e.g.:
location /some-path {
proxy_pass http://server:3000/;
}
Now requests sent to /some-path can (and must) be handled by the route / on the proxied server side. However, this may cause issues with some servers. For example, with Express, curl localhost/some-path would be handled fine by Express, whereas curl localhost/some-path/ would cause Express to return Cannot GET //.
This might be different for your target server, but the principle is the same: if you specify the server only, the full path in location is passed to the server, so it must be handled accordingly.
This is my case how I've get 404 instead of 502:
# let's define some proxy pass
location ~ /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:5080; # this backend doesn't exist which leads to 502
proxy_set_header Host $host;
}
# this is a default directives
error_page 500 502 503 504 /50x.html; # this is a reason to redirect 502 to 50x.html
location = /50x.html { # but this file doesn't exist in root so we get 404 instead of 502
root /usr/share/nginx/html;
}

How to upload mutiple files to nginx?

I want to multiple files on nginx, I use the script which to perform saving one file(code below). I want to send a form with multiple files to save theirs on the server. How can I change my script?
location /someurl {
limit_except POST { deny all; }
client_body_temp_path /www/mydir/images;
client_body_in_file_only on;
client_body_buffer_size 128K;
client_max_body_size 1000M;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-FILE $request_body_file;
proxy_set_body off;
proxy_redirect off;
proxy_pass myurl;
}

How to proxy and rewrite a URL like /app/(wildcard)/(actually path for rewriting)

I want to rewrite and proxy all URLs like ...
http://foo.com/app/groupA/index.html
http://foo.com/app/groupB/index.html
to
http://foo.com:8080/index.html
Note how groupA and groupB URLs rewrite to the same place.
I've tried many things, this I think should most likely work because it matches everything after the third occurrence of a /.
location /app {
rewrite (?:.*?\/){3}(.*) /$1 break;
index index.html index.htm;
proxy_pass http://localhost:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_buffering off; # buffering would break CouchDB's _changes feed
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_connect_timeout 75s;
}
Yet on port 8080 I'm not seeing other requests come in. Note, I do see requests when I write...
location ^~ /app {
rewrite /app/(.*) /$1 break;
index index.html index.htm;
proxy_pass http://localhost:8080;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_buffering off; # buffering would break CouchDB's _changes feed
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_connect_timeout 75s;
}
The requests come in on port 8080 as...
/groupA/index.html
/groupB/index.html
I need to figure out how to get rid of that /groupA/ and /groupB/ part of the URL. Note, I don't actually know what string is going to be between those slashes where the group is. It could be /funnybunny/ for all I know :P.
Where a regular expression contains brace characters {} the expression should be enclosed in quotes.
Try:
rewrite "(?:.*?\/){3}(.*)" /$1 break;

How to use Nginx proxy with multi sites and two servers?

I've installed nginx proxy in a VPS (Ubuntu 12.04 + Nginx 1.1.19) in order to send requests:
A- from (site1.com, site2.com and site3.com) to SERVER_A
B- from (site4.com, site5.com and site6.com) to SERVER_B
I used /etc/nginx/proxy.confg file with content:
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;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
also in /etc/nginx/sites-enabled I created first file configuration with:
server {
listen 80;
server_name site1.com site2.com site3.com;
access_log /var/log/nginx/access.log;
location / {
proxy_pass http://IP_of_SERVER_A/;
include /etc/nginx/proxy.conf;
}
}
It works fine till here. The problem comes when I try to add second file configuration with:
server {
listen 80;
server_name site4.com site5.com site6.com;
access_log /var/log/nginx/access.log;
location / {
proxy_pass http://IP_of_SERVER_B/;
include /etc/nginx/proxy.conf;
}
}
Now:
sites in second file doesn't works and all requests from (site4.com, site5.com site6.com) goes to server_A too.
Any help to add missing parts?

Deploying Pyramid app: Nginx + Pserve

I've been following this recipe in the Pyramid Cookbook to try and deploy my app on DigitalOcean. It seems to work, I get the message Entering daemon mode just like I did when running on my local machine.
I've also added my domain name and set up my nameservers to point to DigitalOcean.
When I try to access my site at wisderm.com though, it doesn't load. I'm completely lost at this point -- What am I doing wrong?
This is how my files are structured:
home/
|----env/ # virtualenv
|----MyApp/
|
|----production.ini
|----requirements.txt
|----myapp.sql
|----myapp.psql
|----MyProject
|
|----scripts/
|----static/
|----templates/
|----__init__.py
|----views.py
|----models.py
This is my app.conf:
upstream myapp-site {
server 127.0.0.1:5000;
server 127.0.0.1:5001;
}
server {
server_name wisderm.com;
access_log /home/MyApp/access.log;
location / {
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 $scheme;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 60s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
proxy_buffering off;
proxy_temp_file_write_size 64k;
proxy_pass http://myapp-site;
proxy_redirect off;
}
location /static {
root /home/MyApp;
expires 30d;
add_header Cache-Control public;
access_log off;
}
}

Resources