Unable to load-balance with nginx - nginx

On my host machine I have three instances of one web-service - they run on ports 32826, 32827 and 32828. So that when I go to 127.0.0.1:32826 or 127.0.0.1:32827 or 127.0.0.1:32828, I see in browser a nice web-page.
Besides, I have nginx running on the same host. Now I want it to load-balance between these three instances. I did it like so:
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
upstream app_servers {
server 127.0.0.1:32826;
server 127.0.0.1:32827;
server 127.0.0.1:32828;
}
server {
listen 80;
root /code;
index index.php index.html;
location / {
try_files $uri/ $uri/ /index.php;
}
location ~ \.php$ {
proxy_pass http://app_servers;
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;
}
location ~ /\.ht {
deny all;
}
}
}
I put this configuration into '/etc/nginx/nginx.conf' and restarted nginx. When however I go to 127.0.0.1, I just see a default welcoming nginx page. I'm not sure what I did wrong and how can I fix it.

You are putting your reverse proxy config under wrong location block.
Try / location block.
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
upstream app_servers {
server 127.0.0.1:32826;
server 127.0.0.1:32827;
server 127.0.0.1:32828;
}
server {
listen 80;
root /code;
index index.php index.html;
location / {
proxy_pass http://app_servers;
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;
}
#location ~ \.php$ {
#proxy_pass http://app_servers;
#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;
#}
location ~ /\.ht {
deny all;
}
}
}

I discovered this question while troubleshooting my own problem with the same symptoms, but discovered a different solution.
With the default install on CentOS using the yum repositories, nginx.conf contains
include /etc/nginx/conf.d/*.conf
which I believe was overriding my configuration in nginx.conf. After commenting (or completely removing) this include statement and restarting nginx, load balancing worked as expected.

Related

How to host multiple apps using nginx and prefixes (app1.xxx and app2.xxx) in local network

I am trying to host an API and corresponding static web app on my raspberrypi. It will only be accessible via the local network. This is the config file:
server {
listen 80;
server_name api.raspberrypi;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name raspberrypi;
location / {
root /Development/UI/wwwroot;
try_files $uri $uri/ /index.html =404;
}
}
Depending on where I put the prefix (api. or ui.) this part becomes inaccessible while the other one is available in the local network at http://raspberrypi:80. I would like to have the api at http://api.raspberrypi. How can this be achieved?

nginx testing : acessing localhost and localhost2

I want to test nginx with docker with two apps before i deploy online.
I am trying to set different local domains. The localhost domain is working but if I try localhost2 as a domain, nginx doesnt get it in the browser (the dns must not be configured). So I tried with local ip adress (192.168.0.2) as a domain name but it is not working.
What should i put so i can access my first website at http://localhost and my second at a http://local_ip_adress?
This is the nginx config file :
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html/build;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8000/api;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 20M;
}
location /wagtail {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Script-Name /wagtail;
client_max_body_size 20M;
}
location /djangostatic {
alias /app/static;
}
location /media {
alias /app/media;
}
}
server {
listen 80;
server_name 192.168.0.2;
location / {
root /usr/share/nginx/html/build2;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend2:8000/api;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 20M;
}
location /wagtail {
proxy_pass http://backend2:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Script-Name /wagtail;
client_max_body_size 20M;
}
location /djangostatic {
alias /app/static;
}
location /media {
alias /app/media;
}
}

How to stop Nginx redirect if HOST HEADER is incorrect

I have been trying to solve this issue for quite awhile now. Bots are hitting my sites hard with INVALID HOST HEADERS and Nginx forwards these requests to Gunicorn/Django. I need to stop them at Nginx. I have tried every solution I can find on SO, and elsewhere, but none seem to work for my setup.
Nginx.conf:
upstream backend_server {
server backend:8000;
}
upstream backend_asgi {
server backend_asgi:8001;
}
server {
listen 80;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location ~* ^/(api|admin|static|v2) {
return 301 https://$host$request_uri;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.site *.example.site;
ssl_certificate /etc/letsencrypt/live/example.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.site/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location /ws/ {
proxy_pass http://backend_asgi;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
location ~ ^/v2(?:/(.*))?$ {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /v2/index.html =404;
}
location /backend_static/ {
alias /backend/assets/;
}
location /media/ {
alias /backend/media/;
}
location ~* ^/(api|admin) {
proxy_pass http://backend_server$request_uri;
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;
proxy_connect_timeout 360s;
proxy_read_timeout 360s;
}
location / {
proxy_pass http://backend_server$request_uri;
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;
proxy_connect_timeout 360s;
proxy_read_timeout 360s;
# Set upload size for videos to be 500MB
client_max_body_size 500M;
}
}
What can i add to my Nginx configuration to stop invalid host headers, given that I have a wildcard subdomain and bots are also using HOST HEADERS w/ subdomains?

How to use vue.js with Nginx?

I want to build a single page application with Vue.js using Nginx as my webserver and a my own Dropwiward REST API. Moreover I use Axios to call my REST request.
My nginx config looks like
server {
listen 80;
server_name localhost;
location / {
root path/to/vue.js/Project;
index index.html index.htm;
include /etc/nginx/mime.types;
}
location /api/ {
rewrite ^/api^/ /$1 break;
proxy_pass http://localhost:8080/;
}
}
Currently I can just call my localhost/api/path/to/rescource to get the the information from the backend.
I build the Front end with HTML and javascript(vue.js) which has worked so far. However when I want to build a single page application most tutorials mention node.js. How can I use Nginx instead?
Add the following code to your Nginx Config, as detailed in the VueRouter docs, here:
location / {
try_files $uri $uri/ /index.html;
}
Also, you need to enable history mode on VueRouter:
const router = new VueRouter({
mode: 'history',
routes: [...]
})
I struggled with same problem. But I found how can I do. You just add this to your nginx.conf.
location / {
root /home/admin/web/domain.com/public_html/; #-> index.html location
index index.html;
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.html;
}
This worked for me:
location /static/ {
root /root/bdn/bdn/server/;
}
location /media/ {
root /root/bdn/bdn/server/;
}
location ^~ /admin/ { # Define routes to be directed to backend as proxy
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;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /api/ { # Define routes to be directed to backend as proxy
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;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /api-auth/ {
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;
proxy_pass http://unix:/run/gunicorn.sock;
}
location ^~ /{
root /root/bdn/bdn/server/templates/;
index index.html;
}
error_page 404 /; # PARTICULARLY THIS ERROR REDIRECTION

NGINX force SSL for all but health check file?

I have a Rails app with an NGINX reverse proxy behind an AWS ELB. I am terminating SSL on the ELB and I have NGINX configured to force any attempt at HTTP to rewrite as HTTPS. This setup works fine, but I'm also serving the site through ECS, and since the ELB health check is on HTTP port 80, when it gets the redirect and returns 301, the ELB health check fails and the instance is deregistered.
How do I set up NGINX to send all but the health check file through HTTPS?
Here is my server block from nginx.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
location ~ ^elbcheck\.html$ {
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://rails_app;
break;
}
location / {
proxy_redirect off;
proxy_next_upstream error;
if ($http_x_forwarded_proto != "https") {
rewrite ^ https://$host$request_uri? permanent;
}
try_files $uri $uri/ #proxy;
}
location ~* \.(jpg|jpeg|svg|png|gif|ico|css|js|eot|woff|woff2|map)$ {
proxy_cache APP;
proxy_cache_valid 200 1d;
proxy_cache_valid 404 5m;
proxy_ignore_headers "Cache-Control";
expires 1d;
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;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://rails_app;
}
location #proxy {
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;
proxy_pass http://rails_app;
}
}
I had the same problem, and found this answer somewhere on the internet (don't have the source anymore, it was a while ago)
server {
listen 80;
set $redirect_to_https 0;
if ($http_x_forwarded_proto != 'https') {
set $redirect_to_https 1;
}
if ($request_uri = '/status') {
set $redirect_to_https 0;
}
if ($redirect_to_https = 1) {
return 301 https://$host$request_uri;
}
...
}
Found a simple answer that worked great at this post. Here is what #ceejayoz suggested there:
server {
location /elb-status {
access_log off;
return 200;
}
}
Seems to be working--ECS hasn't terminated my service due to failed health checks anymore.

Resources