Nginx 'if' doesn't work properly - if-statement

I have some problem with nginx. Here is my simple virtualhost config that doesn't seem to work properly:
server {
listen 80;
server_name my.site;
access_log /home/my.site/www/my.site/log/access.log;
error_log /home/my.site/www/my.site/log/error.log error;
root /home/my.site/www/my.site/public/;
charset utf-8;
location /search/ {
error_page 418 = #passenger;
recursive_error_pages on;
if ( $arg_mode = block ) { return 418; }
default_type text/html;
try_files $request_uri #passenger;
}
location / {
try_files $uri #passenger;
}
location #passenger {
root /home/my.site/www/my.site/public/;
passenger_enabled on;
}
}
The problem exactly is with the location /search/. I want nginx to pass the request immediately to the backend if uri includes the parameter 'mode' with the value 'block' (i.e. uri looks like http://my.site/search/word?mode=block&type=... (other parameters) )
But now it doesn't work. If static file /public/search/word exists server sends it even if parameter mode=block exists in uri... What is my misstep?

Your configuration is fine Nginx wise and any request for /search/ with mode=block will get sent to #passenger.
A simple test case is ...
server {
listen 80;
server example.com;
location /search/ {
error_page 418 = #passenger;
recursive_error_pages on;
if ( $arg_mode = block ) { return 418; }
default_type text/html;
echo "/search/";
}
location #passenger {
echo "#passenger!";
}
}
Calling this using curl ...
# curl -i http://example.com/search/word/?mode=block&a=b$c=d
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 02 Oct 2014 11:35:50 GMT
Content-Type: application/octet-stream
Transfer-Encoding: chunked
Connection: keep-alive
#passenger!
So, if files are getting served, then this is happening in the #passenger block as #Alexey Ten inferred in his comment.

Related

How to set nginx proxy path to use static contents of a specific s3 bucket folder?

I'm working on an nginx reverse proxy container image to proxy frontend files from s3, and Im trying to access these files from a specific folder location, instead of just the base path of the s3 bucket. As of yet I can only serve up the index.html which I'm using a rewrite for, but I'm getting a 403 on the js and css files.
I've tried including mime.types
include mime.types;
I've tried adding an s3 folder bucket param
proxy_pass http://YOURBUCKET.s3-website.eu-central-1.amazonaws.com/$1;
And then various regex options
Here is my nginx conf file
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/nginx-server.crt;
ssl_certificate_key /etc/ssl/nginx-server.key;
server_name timemachine.com;
sendfile on;
default_type application/octet-stream;
resolver 8.8.8.8;
server_tokens off;
location ~ ^/app1/(.*) {
set $s3_bucket_endpoint "timemachineapp.s3-us-east-1.amazonaws.com";
proxy_http_version 1.1;
proxy_buffering off;
proxy_ignore_headers "Set-Cookie";
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-s3cmd-attrs;
proxy_hide_header Set-Cookie;
proxy_set_header Authorization "";
proxy_intercept_errors on;
rewrite ^/app1/?$ /dev/app1/index.html; <-- I can only access index.html and the other js and css files throw a 403
proxy_pass https://timemachineapp.s3-us-east-1.amazonaws.com;
break;
}
}
As you can see, I'm trying to make this so that the user goes to https://timemachine/app1 that this will go to the homepage and load all the css and js files. Again, what im getting is a 403 and sometimes a 404. Insight appreciated.
From the question it looks like
There's a constant request-url prefix /app1/
There's a constant proxied-url prefix /dev/app1/
On that basis...
First, enable the debug log
There will already be an error_log directive in the nginx config, locate it and temporarily change to debug:
error_log /dev/stderr debug;
This will allow you to see how these requests are being processed.
Try naive-simple first
Let's use this config (other header directives omitted for brevity):
location = /app1 { # redirect for consistency
return 301 /app1/;
}
location = /app1/ { # explicitly handle the 'index' request
proxy_pass https://example.com/dev/app1/index.html;
}
location /app1/ {
proxy_pass https://example.com/dev/;
}
And emit a request to it:
$ ~ curl -I http://test-nginx/app1/some/path/some-file.txt
HTTP/1.1 403 Forbidden
...
Note that S3 returns a 403 for requests that don't exist, nginx is just proxying that response here.
Let's look in the logs to see what happened:
2023/01/28 14:46:10 [debug] 15#0: *1 test location: "/"
2023/01/28 14:46:10 [debug] 15#0: *1 test location: "app1/"
2023/01/28 14:46:10 [debug] 15#0: *1 using configuration "/app1/"
...
"HEAD /dev/some/path/some-file.txt HTTP/1.0
Host: example.com
Connection: close
User-Agent: curl/7.79.1
Accept: */*
"
So our request became https://example.com/dev/some/path/some-file.txt
That's because the way proxy_pass works is:
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
Meaning:
Nginx receives:
/app1/some/path/some-file.txt
^ the normalized path starts here
Proxied-upstream receives:
/dev/some/path/some-file.txt
^ and was appended to proxy-pass URI
I point this out as renaming/moving things on s3 may lead to a simpler nginx setup.
Rewrite all paths, not specific requests
Modifying the config above like so:
location = /app1 { # redirect for consistency
return 301 /app1/;
}
location = /app1/ { # explicitly handle the 'index' request
proxy_pass https://example.com/dev/app1/index.html;
}
location /app1/ {
rewrite ^/(.*) /dev/$1 break; # prepend with /dev/
# rewrite ^/app1/(.*) /dev/app1/$1 break; # OR this
proxy_pass https://example.com/; # no path here
}
And trying that test-request again yields the following logs:
"HEAD /dev/app1/some/path/some-file.txt HTTP/1.0
Host: example.com
Connection: close
User-Agent: curl/7.79.1
Accept: */*
"
In this way the index request works, but also arbitrary paths - and there's no need to modify this config to handle each individual url requested.
Alright so found a solution. Unless I'm missing something, this is easier than thought. For my use case, all I had to do was simply add multiple writes with those css files passed in (I'm sure there's a simpler way to just specify any .css file extension regardless of the naming of the file. Anyway, here is solution at the moment:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/ssl/nginx-server.crt;
ssl_certificate_key /etc/ssl/nginx-server.key;
server_name timemachine.com;
sendfile on;
default_type application/octet-stream;
resolver 8.8.8.8;
server_tokens off;
location ~ ^/app1/(.*) {
set $s3_bucket_endpoint "timemachineapp.s3-us-east-1.amazonaws.com";
proxy_http_version 1.1;
proxy_buffering off;
proxy_ignore_headers "Set-Cookie";
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-s3cmd-attrs;
proxy_hide_header Set-Cookie;
proxy_set_header Authorization "";
proxy_intercept_errors on;
rewrite ^/app1/?$ /dev/app1/index.html;
rewrite ^/app1/?$ /dev/app1/cssfile.css; <- and keep adding, if needed
proxy_pass https://timemachineapp.s3-us-east-1.amazonaws.com;
break;
}
}

502 gateway error | sentence-transformer package not working correctly

Hello I'm trying to solve this problem from last 5days if anyone know the solution please reply.
My website is working properly but one page giving 502 gateway error on post request. The code is working properly on local server but not working on nginx live server.
I thought it could be giving error cause that post request take long time to process so i increase timeout in nginx.server file but still it's not working
/etc/nginx/sites-available/myproject
server {
listen 80;
server_name 54.199.217.173;
client_max_body_size 20M;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/bankproject/Live-Banking-Solutions-Applications;
}
location /media/ {
root /home/ubuntu/bankproject/Live-Banking-Solutions-Applications;
}
location / {
include proxy_params;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
Nginx error.log file giving this error
For that page
2022/12/26 07:21:57 [error] 2197#2197: *2 upstream prematurely closed connection while reading response header from upstream, client: 106.211.97.247, server: 54.199.217.173, request: "POST /admin/scaning_signature HTTP/1.1", upstream: "http://unix:/run/gunicorn.sock:/admin/scaning_signature", host: "54.199.217.173", referrer: "http://54.199.217.173/admin/get_signature"
I mentioned sentence-tranformers in question cause only that page is giving error where i use sentence-transformer. other pages post requests are working correctly

Nginx Not Serving Image Files

I have set up a django website that would be served by Nginx, everything was working perfectly not until images stopped showing recently.
I tried inspecting the possible cause of this strange development using curl and then realized that the Content-Type is not recognized as Content-Type: image/jpeg returns a Content-Type: text/html; charset=utf-8
This behavior looks strange as I have included mime.types in my nginx.conf file.
Below is an example response from curl command
user#server:~$ curl -I https://domain.name/media/upload/image.jpg
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 29 May 2022 00:45:53 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 11392
Connection: keep-alive
X-Frame-Options: DENY
Vary: Cookie
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Cross-Origin-Opener-Policy: same-origin
Set-Cookie: csrftoken=T9Z3jrp4dzOAINxo6JzOUyjIGwGYHoc37TZaYsIOmHHyrQUw30vI6ETIAcy66Wnr; expires=Sun, 28 May 2023 00:45:53 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Here is my full nginx.conf file
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
Contents of /etc/nginx/sites-enabled/app
# /etc/nginx/sites-enabled
server {
server_name my_server_IP my_server_NAME;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/app;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
listen 443 ssl;
ssl_certificate /path/to/certfullchain.pem;
ssl_certificate_key /path/to/certprivkey.pem;
include /etc/cert-provider/options-ssl-nginx.conf;
ssl_dhparam /etc/cerrt-provider/ssl-dhparams.pem;
}
server {
if ($host = www.domain.name {
return 301 https://$host$request_uri;
}
if ($host = domain.name) {
return 301 https://$host$request_uri;
}
listen 80;
server_name my_server_IP my_server_NAME;
return 404;
}
Note: I am serving this website with gunicorn
I was able to fix this problem by adding new location directive which matches my media files.
In this case my files are uploaded to media
I fixed this by add the following to my server block
location /media/ {
root /home/user/app;
}
Now my new /etc/nginx/sites-enabled/app looks like this.
# /etc/nginx/sites-enabled
server {
server_name my_server_IP my_server_NAME;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/app;
}
location /media/ {
root /home/user/app;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
listen 443 ssl;
ssl_certificate /path/to/certfullchain.pem;
ssl_certificate_key /path/to/certprivkey.pem;
include /etc/cert-provider/options-ssl-nginx.conf;
ssl_dhparam /etc/cerrt-provider/ssl-dhparams.pem;
}
server {
if ($host = www.domain.name {
return 301 https://$host$request_uri;
}
if ($host = domain.name) {
return 301 https://$host$request_uri;
}
listen 80;
server_name my_server_IP my_server_NAME;
return 404;
}

nginx serving from html instead of gunicorn

I have a nginx / gunicorn / django app I've set up following
https://medium.com/#_christopher/deploying-my-django-app-to-a-real-server-part-ii-f0c277c338f4
It works when I go to the main IP from the browser (I got Django tried these URL patterns, in this order: admin/...) but when I go to /admin I got a 404. Nginx logs are as follows:
2019/07/05 00:30:28 [error] 13600#13600: *1 open() "/usr/share/nginx/html/admin" failed (2: No such file or directory), client: 186.190.207.228, server: 127.0.0.1, request: "GET /admin HTTP/1.1", host: "128.199.62.118"
So it is trying to serve files from html/ instead of serving gunicorn, why?
Nginx config:
server {
listen 80;
server_name 127.0.0.1;
location = /favicon.ico {access_log off;log_not_found off;}
location = /static/ {
root /home/juan/site;
}
location = /media/ {
root /home/juan/site;
}
location = / {
include proxy_params;
proxy_pass http://unix:/home/juan/site/site.sock;
}
}
Remove the = from all the Location directives except the first. That means exact match, instead of the prefix match you want.
location = /favicon.ico {access_log off;log_not_found off;}
location /static/ {
root /home/juan/site;
}
location /media/ {
root /home/juan/site;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/juan/site/site.sock;
}

Getting Nginx to serve static content in front of Django local server

I'm trying to use Nginx in front of Django's localhost webserver (127.0.0.1:8000) to serve the static content. I'd like Nginx to serve all files under '/static', and if not, pass the request onto the Django's webserver, but I'm stuck! Here's what I've done:
Got Nginx running on my OSX, so the 'welcome to Nginx!' page shows on localhost.
Changed my /etc/hosts file to add 'testdev.com':
127.0.0.1 localhost
127.0.0.1 testdev.com
Made /sites-available and /sites-enabled files in /usr/local/src/nginx-1.2.6
My nginx.conf file in /conf is the default plus the include statement:
include /usr/local/src/nginx.1.2.6/sites-enabled/testdev.com
5.My testdev.com file is in sites-available, with a symlink in /sites-enabled.
server {
root /<path-to-my-django-project>/website/static;
server_name testdev.com;
gzip off;
listen 8000;
location = /favicon.ico {
rewrite "/favicon.ico" /img/favicon.ico;
}
proxy_set_header Host $host;
location / {
if (-f $request_filename) {
add_header X-Static hit;
access_log off;
}
if (!-f $request_filename) {
proxy_pass http://127.0.0.1:8000;
add_header X-Static miss;
}
}
}
If I curl the testdev.com, it shows Nginx:
curl -I http://testdev.com
HTTP/1.1 200 OK
Server: nginx/1.2.6
Date: Mon, 22 Apr 2013 18:37:30 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 21 Apr 2013 19:39:47 GMT
Connection: keep-alive
Accept-Ranges: bytes
But if I try to access a static file, nothing:
curl -I http://testdev.com/static/css/style.css
HTTP/1.1 404 Not Found
Server: nginx/1.2.6
Date: Mon, 22 Apr 2013 18:38:53 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive
All this is based from a Google search, and finding this.
I added in the
listen 8000
statement in my testdev.com conf file as I thought that was needed for the Nginx virtual host, but I'm super confused. The blog author used
127.0.1.1 testdev.com
In his hosts file, but if i add that, the first curl statement just hangs.
What am I doing wrong?
Thanks all - I've got it working, here's my working testdev conf:
server {
root /<path-to-django-site>;
server_name testdev.com;
gzip off;
autoindex on;
proxy_set_header Host $host;
location /static/ {
add_header X-Static hit;
}
location / {
proxy_pass http://127.0.0.1:8000;
}
}
Looks like the location block takes the server root path if you don't supply one. Now when I curl:
curl -I http://testdev.com/static/js/utils.js
HTTP/1.1 200 OK
Server: nginx/1.2.6
Date: Tue, 23 Apr 2013 01:36:07 GMT
Content-Type: application/x-javascript
Content-Length: 2730
Last-Modified: Thu, 13 Dec 2012 18:54:10 GMT
Connection: keep-alive
X-Static: hit
Accept-Ranges: bytes
Many thanks #Evgeny - got me on the right lines. Miget be useful for others looking to do the same.