Nginx load balance based on IP - nginx

We currently use an Nginx server for load balancing. We would like our office IP to be redirected to a specific server, where as all other traffic is load balanced normally.
Is this possible?

You can do a simple redirect with any web server (Apache, Tomcat, nginx, etc).
For example, on Java you can create a simple index.jsp with the following:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Your Company</title>
<link rel="icon" type="image/png" href="http://www.yourloadbalance.com/favicon.png">
</head>
<body>
<%
response.sendRedirect("www.yourloadbalance.com");
%>
</body>
</html>
This piece of code will redirect each request to the given URL, in your case to the load balancer.

This is not a working config but I hope the main idea is clear
map $remote_addr $backend {
default app-servers;
192.168.1.1 dev-servers; # office IP
}
upstream app-servers { # this is normal upstreams group
server ...;
server ...;
}
upstream dev-servers { # this is upstream(s) for Office IP
server ...;
}
server {
listen 80;
server_name bar.foo.com;
location / {
proxy_pass http://$backend;
}
}

Related

Trouble running two web applications on the same domain on nginx

I would like to have an nginx server hosting web applications on the same domain, with different paths.
For example,
http://example.org/booksapp/signin.html should point to the first app,
and http://example.org/shoesapp/signin.html should point to the second app
within my host, I have two folders, one for each app:
/var/webfolder/booksapp and /var/webfolder/shoesapp
my nginx configuration is the following
server {
server_name example.org;
index index.html index.htm;
location /foodapp {
root /var/webfolder;
try_files $uri $uri/ =404;
}
location /shoesapp {
root /var/webfolder;
try_files $uri $uri/ =404;
}
listen [::]:80;
listen 80;
}
This configuration does not work. My browser just shows a blank page when trying to load either web application.
Meanwhile, the nginx log files shows a list of 404 for every resource that the apps are trying to load.
What am I doing wrong?
You have to change your html files to use the right paths.
Your "booksapp" lives at example.org/booksap/, the html pages must load any static resource using that same path.
This is the head section of an example html file. If you deploy this to any of your sites it will not work, nginx can't find "normalize.css" and "styles.css" unless you specify the right path. Right now nginx is acting as a router between the two apps, you can't ask for just a file, you must specify which app.
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>sakura demo</title>
<link href="normalize.css" rel="stylesheet" type="text/css">
<link href="styles.css" rel="stylesheet" type="text/css" media="all">
</head>
It should be:
<link href="booksap/normalize.css" rel="stylesheet" type="text/css">
<link href="booksap/styles.css" rel="stylesheet" type="text/css" media="all">

Serving files and assets from a subdirectory

I'm attempting to server files and assets from a subdirectory of a site, like this:
Site: /go/tools/ (index.html is the root file)
With assets linked like this: /go/tools/assets/js/main.js
using nginx, my configuration looks like this:
server {
listen 80;
listen 443 ssl http2;
server_name local.tools;
index index.html;
location /go/tools {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
root /code/testing/build;
try_files $uri /$uri /index.html =404;
}
When I load the site with the url local.tools/go/tools, the index.html page loads and the html looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="icon" href="assets/img/favicon.ico">
<link href="assets/css/vendor/bootstrap.css" rel="stylesheet" type="text/css" />
<link href="assets/css/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>...
So that part is good. The problem is that the style and javascript aren't there. When I view the network tab, I see each asset is loading the index.html content instead of its own content.
what am I missing in my configuration so if I go to: /go/tools/assets/css/styles.css that I see the actual stylesheet?
You need to use below config
location /go/tools {
location /go/tools/assets/ {
alias /code/testing/build/assets/;
}
alias /code/testing/build;
try_files $uri $uri/ /index.html =404;
}
Basically when url is /go/tools/assets you need the search to happen from /assets in the build directory. That is why we need alias in the nested location

nginx serve page depending on protocol

I want to simultaneously optimize my site for HTTP/2 and HTTP/1.x. For HTTP/2 (and SPDY), since there are no additional round-trips for requests, I'd like to serve my CSS and JS files separately, to gain the benefit of independently caching each file. However, if I only did that, HTTP/1.x clients would suffer from additional round-trips; so for them, I'd like to serve my CSS and JS files concatenated.
Ideally, HTTP/2 users would be served this HTML:
<html>
<head>
<link rel="stylesheet" href="stylesheet-1.css">
<link rel="stylesheet" href="stylesheet-2.css">
</head>
<body>
<script src="script-1.js"></script>
<script src="script-2.js"></script>
</body>
</html>
And HTTP/1.x users would be served this HTML:
<html>
<head>
<link rel="stylesheet" href="all-stylesheets.css">
</head>
<body>
<script src="all-scripts.js"></script>
</body>
</html>
Is it possible to configure nginx to serve different HTML files depending on the client's protocol?
Yes, you can do so via the $server_protocol variable. I would usually recommend to interpolate file locations by variable expansion. But in this case I fear this would leave you open to injection attacks as the content of this variable seems to be copied verbatim from the request line.
There is a solution by exploiting the ngx_http_map_module, though. Assuming your site sits in /srv/www:
map $server_protocol $version {
default "1.1";
"HTTP/2.0" "2.0";
# extra case for any SPDY version
"~SPDY/" "2.0";
}
server {
listen [::]:80;
# The line below requires a working SSL configuration!
listen [::]:443 ssl http2;
server_name example.com
root /srv/www/http-1.1/htdocs;
location / {
root /srv/www/http-$version/htdocs;
try_files $uri $uri/ #fallback;
}
# fallback for HTTP/1.1 files. If this fails as well, we get a 404.
location #fallback {
try_files $uri $uri/ =404;
}
}
This would serve all requests out of /srv/www/http-2.0/htdocs for HTTP/2.0 requests and out of /srv/www/http-1.1/htdocs for all others. If a resource specially crafted for HTTP/2.0 cannot be found, the coresponding file for HTTP/1.1 is being served as a fallback.

How to change OpenShift Jenkins to use HTTP instead of HTTPs

I create an application Jenkins on Openshift, but when I tried to visit http://[app_name]-[domain_name].rhcloud.com/, it will be redirected to https://[app_name]-[domain_name].rhcloud.com/.
I curl the http address, the result is :
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved here.</p>
<hr>
<address>Apache/2.2.15 (Red Hat) Server at [app_name]-[domain_name].rhcloud.com Port 80</address>
</body></html>
If I do not want to be redirected to https, what should I do?
I searched in my openshift folders, but cannot find any helpful things
You should change it on your .htaccess file.
RewriteRule ^https://[app_name]-[domain_name].rhcloud.com/(.*) http://[app_name]-[domain_name].rhcloud.com/$1 [R=301,NC]

Avoid showing 404 not found in nginx ssi includes

I'm trying to move to nginx from apache but one of the features I most use in apache are the ssi includes. I'm testing how nginx deal with ssi but I'm having some problems...
If an include virtual file doesn't exist I'm getting a 404 page embeded, not even the [an error has occurred] message. With apache ssi, if the file doesn't exist an error is shown as comment.
The other point is, with apache SSIErrorMsg directive I can set at server config level the error text but I couldn't find this in nginx, just the <!--# config errmsg="custom error" --> inside the html. I coudn't see a directive like SSIErrorMsg in nginx documentation
nginx 404 ssi error :
<html>
<head>
<title>simple</title>
</head>
<body>
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
</body>
</html>
but in apache:
<html>
<head>
<title>simple</title>
</head>
<body>
<!-- Error -->
</body>
</html>
The error message only appears in nginx when for instance I write a ssi include with some typo like
<!--#include virtualll="example.html"-->
Is there a way to show an error instead of embedding the 404 file in case of not found?
This is the nginx server config:
server {
listen 80;
server_name demo.localhost;
ssi on;
ssi_silent_errors off;
location / {
root /var/www/demoweb;
}
}
If I set ssi_silent_errors off; nothing is shown but I want something like <!--Error--> as apache does

Resources