nginx multiple domain virtual host configuration - nginx

I'm setting up nginx with multiple domain or wildcard support for convenience sake, rather than setting up 50+ different sites-available/* files. Hopefully this is enough to show you what I'm trying to do. Some are static sites, some are dynamic with usually wordpress installed.
If an index.php exists, everything works as expected.
If a file is requested that does not exist (missing.html), a 500 error is given due to the rewrite. The logged error is:
*112 rewrite or internal redirection cycle while processing "/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/missing.html"
The basic nginx configuration I'm currently using is:
`
listen 80 default;
server _;
...
location / {
root /var/www/$host;
if (-f $request_filename) {
expires max;
break;
}
# problem, what if index.php does not exist?
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
}
}
...
`
If an index.php does not exist, and the file also does not exist, I would like it to error 404. Currently, nginx does not support multiple condition if's or nested if so I need a workaround.

if ($_SERVER['HTTP_HOST'] == 'desideshat.com')
{
$vboptions['bburl'] = 'http://www.desideshat.com';
}
else
{
$vboptions['bburl'] = 'http://www.vedesi.com';
}
?>

Related

Nginx - config to route to single page app

I'm using nginx with the deployment of my website on my local server.
The website is a single page create react app running on the server. I have a domain, www.test.com for example, and i want the single page app to be found on www.test.com/first-website. From reading online I'm supposed to use the rewrite directive.
This is my current config:
http {
upstream sensory-showcase {
server 127.0.0.1:5000;
}
server {
listen 80;
location /sensory-solution-for-firefighters {
rewrite ^/sensory-solution-for-firefighters $1 break;
proxy_pass http://sensory-showcase/;
}
}
}
events { }
From this the url resolves without an nginx 500 error however it just shows a blank white page.
And i have to have a trailing /, eg www.test.com/first-website/ . Without the trailing / it errors.
I just note, when I didnt have the rewrite directive in, and left the location at just / the site loaded fine.
Try this, it will fallback to the index.html of your single page app, which will do the routing:
location /first-website {
try_files $uri $uri.html $uri/ /first-website/index.html;
}

Nginx Location based try files?

I was reading this page here https://help.sorryapp.com/en/articles/2783542-install-maintenance-pages-on-nginx that had a nifty idea of having a file present means nginx would route to a maintenance html page.
But then reading through the nginx docs it seems like if statements within the location block are not ideal, and instead to use try files. Whats the proper way to rewrite whats in the above to how nginx would like it? https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
I assume is something like: but what about a rewrite?
try_files /my/file/path/maint.on
error_page 503 #maintenance_page;
location #maintenance_page {
rewrite ^(.*)$ /maintenance_page.html break;
?
UPDATE 1
this is my current config snippit, which happens to for some reason result in a 404 even through the maint.on file doesn't exist.
location / {
if (-f /opt/staytus/staytus/maint.on) {
return 503;
}
port_in_redirect off;
proxy_pass http://example.com:8787/;
}
error_page 503 #Performing-Maintenance;
location #Performing-Maintenance {
rewrite ^(.*)$ Performing-Maintenance.html break;
}
}
any thought on the issue?
As the same article states,
The only 100% safe things which may be done inside if in a location context are:
return ...;
rewrite ... last;
so the example you're found can be considered completely safe. (I'd say it is safe to use any directive from ngx_http_rewrite_module inside the if block which extends this list to break, return, rewrite and set). You can't do what you want with the try_files directive because it is requires at least one file argument before the last uri (or the name of named location or HTTP error code) argument which would be used if none of the files/directories from the list are actually exists. Well, I could imagine something like
location / {
try_files /maintenance.html #default;
}
location #default {
...
}
but you can't make it serving some location like
location = /maintenance.html {
...
}
, it would just return the contents of maintenance.html file. And if maintenance.html page would refer to some additional assets (like CSS, JS etc.) all user browser requests for that assets would lead to the maintenance.html contents (because that file exists and passed the try_files check). Just FYI, this directive
location / {
try_files $uri $uri/index.php =404;
}
...
location ~ \.php$ {
...
}
won't serve the $uri/index.php file through the PHP location handler (it just return its raw content), while this
location / {
index index.php;
try_files $uri $uri/ =404;
}
would.
However example you provided would have some performance impact (especially on the high-load servers) due to the extra stat kernel call made for every incoming request. I'd recommend this method of enabling maintenance mode with nginx.

Removing path from urls in Nginx

My site works correctly as
https://example.com/website/page/Home
https://example.com/website/page/AboutUs
I would like to remove the /website/page part so that end users would see https://example.com/Home etc.
I read on Nginx website that rewrites are not preferred so I tried:
Location / {
try_files $uri /website/page$uri;
}
I get an internal serval error. What is the right way?
Consider using a rewrite like:
# rewrite example.com/awesome to example.com/website/page/awesome
rewrite ^(/.*) /website/page$1 break;
This should work similarly:
rewrite ^/(.*) /website/page/$1 break;

nginx - Serve file conditionally without redirection

I'm currently building a multi-domain cms in rails. Since this content is the same until the next change I'd like to do caching via static files.
The public directory with some cached pages of foo.com and baz.com (/ and /asdf in both cases):
public/
assets/
cms.css
sites/
foo.com/
assets/
screen-some-hash.min.css
index.html
asdf/
index.html
baz.com/
assets/
screen-some-hash.min.css
index.html
asdf/
index.html
What I want to do is the following:
redirect www to non-www (works)
If the requests contains a subdomain (cms, admin, whatever):
If the path contains /assets serve the file in public/assets and set the expire stuff to 30d or so. No problem here since /assets = public/assets and public/ is the passenger root.
Everything else: handle it via rails, no special caching or anything required.
For all other requests (meaning no subdomain):
If the path contains /assets serve the file in public/sites/$host$request_uri and set the expire stuff to 30d or so. Everything else: check for public/sites/$host$request_uri or fall back to the rails app.
I have never worked with nginx conditionals other than the www/non-www redirects and don't really know what I have to do for the conditions mentioned above. If at all possible, I don't want to use redirects for the cached stuff (ie redirection to /sites/foo.com/asdf), instead I'd like to have nginx serve this file directly when going to http://foo.com/asdf.
Further: I don't want to hardcode the hostnames as I'd like to handle an unknown amount of domains. I also don't want to use more than a single rails application for this.
Got something that works, not 100% but good enough for now.
server {
listen 80;
server_name *IP*;
if ($host ~* www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ http://$host_without_www$1 permanent;
}
location ~ ^/(assets)/ {
try_files /sites/$host$uri $uri #passenger;
root /home/cms/app/current/public;
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
try_files /sites/$host$uri/index.html /sites/$host$uri $uri #passenger;
root /home/cms/app/current/public;
}
location #passenger {
access_log /home/cms/app/shared/log/access.log;
error_log /home/cms/app/shared/log/error.log;
root /home/cms/app/current/public;
passenger_enabled on;
}
}
For subdomains, this should do the trick:
server {
server_name ~^(?<subdomain>.+)\.example\.com$;
access_log /var/log/nginx/$subdomain/access.log;
location /assets {
expires max;
}
location / {
proxy_pass http://your_rails_app;
}
}
Not really sure about the proxy_pass setting as my only experience with Ruby apps is Gitlab, which I'm running this way. I hope this helps at least a little.
server {
server_name example.com;
location /assets {
root /public/sites/$hostname/$request_uri;
expires max;
}
}
You'll have to add your own settings and play with it a little as I don't have a chance to actually test it now. But it should show you the way.

Nginx rewrite omitting port

I've got a an nginx setup that's proxying all requests to a rails app. I would like to have a some kind of "maintenance-mode", so that if I use a different nginx-config, all incoming requests should return a local maintenance.html page.
Here's what I've come up with:
server {
listen 3000;
server_name localhost;
root html/; #maintenance.html resides here
location / {
# redirect everything not already going to maintenance.html
if ($request_uri !~ ^.*/maintenance.html$ ) {
rewrite ^(.*)$ /maintenance.html break;
}
}
}
With this setup, I am able to directly access http://localhost:3000/maintenance.html. However, if I trigger the rewrite rule, the new URL results in localhost/maintenance.html instead of http://localhost:3000/maintenance.html.
This results in a completely empty page being rendered.
nginx version: nginx/1.0.6 on Windows 7
thx for any help
UPDATE:
I just noticed, it works fine with Internet Explorer and also with Chrome. Only Firefox seems to have that problem.
location / {
try_files /maintenance.html $uri =404;
}

Resources