Nginx Load Balancing - image

I want to load balance my website with nginx.
The load balancing in nginx wiki is proxy, so the actual file being downloaded from the frontend server. (http://wiki.nginx.org/LoadBalanceExample)
This is how I need the balancing:
user request file:
http:// site.com/image1.jpg
nginx redirect user to one of the servers (with Location header):
http:// s1.site.com/image1.jpg
http:// s1.site.com/image1.jpg
http:// s3.site.com/image1.jpg
Is this possible with nginx?

http {
split_clients "${remote_addr}" $server_id {
33.3% 1;
33.3% 2;
33.4% 3;
}
server {
location ~* \.(gif|jpg|jpeg)$ {
return 301 "${scheme}://s${server_id}.site.com${request_uri}";
}
}

Related

nginx conf for tonic rest with multiple sites on mac

i try to config nginx with tonic rest for multiple sites on my mac.
My nginx runs as localhost on my mac.
My root is /Users/thorsten/Sites
In root i habe some projects e.g. /project1, /project2
Each project has the tonic rest folder /standard/rest...
In nginx.conf i try
location /rest/ {
fastcgi_pass_header Authorization; # Pass the http authorization parameter to the PHP script
if (!-e $request_filename) {
rewrite ^/(.*)$ /rest/dispatch.php?/$1 last;
break;
}
}
Nothing happend.
Do i need a config for each project or can i have a global config for all project e.g. $project/rest/...?
This config works for me
location ~ ^/(?<project>.+)/standard/rest/ {
fastcgi_pass_header Authorization;
include /usr/local/etc/nginx/conf.d/php-fpm;
if (!-e $request_filename) {
rewrite ^/(.*)$ /$project/standard/rest/dispatch.php?/$1 last;
break;
}
}

Cross domain session with Sinatra and AngularJS

I am using Sinatra as a webservice and angularjs to make the calls
post '/loginUser' do
session[:cui]=user['cui']
end
get '/cui' do
return session[:cui].to_s
end
But it doesn't seem to work (the '/cui' call returns an empty string) any help would be greatly apreciated.
UPDATE:
setting this in sinatra headers['Access-Control-Allow-Credentials'] = 'true' allows me to send the session, but it seems like $http directive is not using the browsers cookies
on the sinatra app
before do
headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
headers['Access-Control-Allow-Origin'] = 'http://localhost:4567'
headers['Access-Control-Allow-Headers'] = 'accept, authorization, origin'
headers['Access-Control-Allow-Credentials'] = 'true'
end
angularjs app
host='http://127.0.0.1:5445/'
#viewController = ($scope,$http)->
$scope.getCui = ()->
$http.get(host+'cui',{ withCredentials: true}).success (data)->
$scope.cui=data
console.log data
Explanation:
AngularJS uses his own cookie system, so we need to specify that we can pass the cookies trough the $http.get call using the {withCredentials:true} configuration object. Sinatra needs to accept the cross domain cookies so we need the headers mentioned above.
Note: 'Access-Control-Allow-Origin' header cannot be wildcard.
One option around this would be to configure a http server with a proxy pass, so you could hit the same domain without incurring a cross origin error. That way you can continue to properly maintain your abstractions as 2 separate apps.
Here is a brief example with nginx:
upstream angular_app {
server localhost:3003;
}
upstream sinatra_app {
server localhost:3004;
}
server {
listen 80;
server_name local.angular_app.com;
root /Users/username/source/angular_app/;
location / {
proxy_set_header Host $http_host;
proxy_redirect off;
}
location ~ ^/api/(.*)$ {
proxy_set_header Host $http_host;
proxy_read_timeout 1200;
proxy_pass http://sinatra_app/;
}
}
By routing at the server level, you can successfully bypass domain restrictions AND you can keep the applications separate.

If Chrome, use WebP

Because currently only Chrome and Opera supports WebP, I was wondering if I could target those two particular browsers and redirect them to fetch another version of my website so I can help optimize my site downloading speed more faster?
Thanks.
I solved this problem like this:
Check if the client advertises "image/webp" in Accept header
If WebP is supported, check if the local WebP file is on disk, and
serve it
If server is configured as proxy, append a "WebP: true" header and
forward to backend
Append "Vary: Accept" if a WebP asset is served
in Nginx:
location / {
if ($http_accept ~* "webp") { set $webp "true"; }
# Use $webp variable to add correct image.
}
In my case, I use thumbor software to convert images.
https://github.com/globocom/thumbor
pip install thumbor
My conf:
upstream thumbor {
server 127.0.0.1:9990;
server 127.0.0.1:9991;
server 127.0.0.1:9992;
server 127.0.0.1:9993;
server 127.0.0.1:9994;
}
location / {
if ($http_accept ~* "webp") {
set $webp "T";
}
if ($uri ~* "(jpg|jpeg)$") {
set $webp "${webp}T";
}
proxy_cache_key $host$request_uri$webp;
if ($webp = "TT") {
rewrite ^(.*)$ "/unsafe/smart/filters:format(webp)/exemple.com$uri" break;
proxy_pass http://thumbor;
add_header Content-Disposition "inline; filename=image.webp";
}
if ($webp != "TT") {
proxy_pass http://exemple.com;
}
}
For a while now, thumbor supports automatic webp conversion:
https://github.com/thumbor/thumbor/wiki/Configuration#auto_webp
You'll still have to configure the load balancer to pass the webp accepts header, but other than that, thumbor will take care of everything for you.
Hope that helps!

Nginx Joomla Internationalization URL rewriting

I'm using Joomla in combination with Nginx, and I'm currently trying to achieve some URL rewriting for a website that has several langages supported (italian, french, chinese, and deutch)
The urls have the country code after the domain name, like so :
http://www.example.com/fr/test/test.html
or
http://www.example.com/de/test/test.html
I'm looking to rewrite the urls so the country code is part of the subdomain :
so
http://www.example.com/fr/test/test.html
becomes
http://fr.example.com/test/test.html
Is there a way to achieve this with Nginx or should I look into a third party extension for Joomla (not my favorite choice).
Thanks !!
Update :
I wasn't clear enough : I wanted the redirection from the rewrited URL to be transparent. Here is what I came up with, thanks to VBart help :
server {
server_name ~^(?<lang>.+)\.example\.com$;
location / {
rewrite /(.*)$ /$lang/$1 break;
proxy_pass http://www.example.com;
proxy_redirect http://www.example.com http://$lang.example.com/$request_uri;
}
}
Now, is there a way for Nginx to modify links on the fly in the served content ? ie: I want all the link in the generated page to look like http://fr... instead of http://.../fr/... ?
server {
server_name ~^(?<lang>.+)\.example\.com$;
...
}
server {
server_name www.example.com;
rewrite ^/(?<lang>[a-z]+)(?<rest>.+)$ http://$lang.example.com$rest? permanent;
}
opposite example:
server {
server_name ~^(?<lang>.+)\.example\.com$;
return 301 http://www.example.com/$lang$request_uri;
}
server {
server_name www.example.com;
...
}

nginx rewrite rules

I'm trying to implement nginx rewrite rules for the following situtation :
- Request /testfa/styles/style.css should be redirected to /testfa/templates/styles/style.css
I've enabled rewrite logging for my server, created following rules:
location /testfa {
rewrite ^/styles/(.+)?$ /testfa/templates/styles/$1 last;
}
but when I'm trying to perform request, I'm getting 404 error from server, and log file doesn't contain any info about rewriting, only following message:
open() "......../testfa/styles/style.css" failed (2: No such file or directory)
What is the correct way to perform such a rewrite for nginx ?
location /testfa/ {
rewrite ^/testfa/styles/(.+)$ /testfa/templates/styles/$1 last;
}
does this work for you ?
my tested virtual >
server {
listen ...ip...:80;
server_name sub.domain.com;
root /usr/local/www/test;
error_log /usr/local/www/test/error_debug.log debug;
rewrite_log on;
location /testfa/ {
rewrite ^/testfa/styles/(.+)$ /testfa/templates/styles/$1 last;
}
}
this works. even log has reported :
2011/11/25 01:06:52 [notice] 35208#0: *456705 rewritten data: "/testfa/templates/styles/test.css", args: "", client: IP, server: sub.domain.com, request: "GET /testfa/styles/test.css HTTP/1.1", host: "sub.domain.com"

Resources