Directory fallback

Hello

I’m trying to come up with a nginx configuration file for a
fallback-like directory structure.

I have the following directories:
/var/www/base/ (generic files)
/var/www/site1/ (files specific to site1)

Given a request for /logo.png, I would like nginx to do the following:

  1. serve /var/www/site1/logo.png if exists; otherwise
  2. serve /var/www/base/logo.png.

The matter is complicated by the presence of PHP files. Given a request
for /index.php (possibly in the same directory as image files…) nginx
should:

  1. serve /var/www/site1/index.php through FastCGI, if the php file
    exists; otherwise
  2. serve /var/www/base/index.php through FastCGI.

Can anybody please suggest the optimal combination of document_root,
alias, location, rewrite, try_files or such options to use? I would like
to avoid client-side redirects. Everything else is ok.

Tobia

On Tue, Dec 29, 2009 at 9:56 AM, Tobia C.
[email protected] wrote:

  1. serve /var/www/base/logo.png.
    [email protected]
    nginx Info Page

Make an attempt at least! :slight_smile:

I’ll get you started… please note this is written for 0.8.30 and
above and I didn’t test this, but it should be close.

upstream php {
server 127.0.0.1:9000;
}

server {
listen 80;
server_name site1;
root /var/www/site1;
fastcgi_intercept_errors on;
location / {
try_files $uri /var/www/base$uri;
}
location ~ .php {
error_page 404 = @basephp
include fastcgi.conf;
fastcgi_pass php;
}
location @basephp {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/base$fastcgi_script_name;
fastcgi_pass php;
}
}

merlin corey wrote:

Make an attempt at least! :slight_smile:

Actually, I posted after 2 hours of failed attempts :frowning:

I’ll get you started… please note this is written for 0.8.30 and above and I didn’t test this, but it should be close.

Eh, I was using 0.6.32, maybe that’s why I wasn’t going far.
Thank you for your example, tomorrow I’ll work on it.

This, for example, I wouldn’t have guessed in a million years:

fastcgi_intercept_errors on;

error_page 404 = @basephp

This is also pretty ingenious:

fastcgi_param SCRIPT_FILENAME /var/www/base$fastcgi_script_name;

Many thanks!

Tobia

Eureka!

Final version, accomplishing all my objectives:

  • site dir, with fallback to base dir;
  • static files directly, php files through fastcgi;
  • not calling fastcgi on nonexistent files;
  • not using “if” (somebody mentioned performance problems?)

location / {
root /var/www/site1;
try_files $uri @base;
}
location @base {
root /var/www/base;
}
location ~ .php$ {
root /var/www/site1;
try_files $uri @basephp;
fastcgi_pass 127.0.0.1:9000;
}
location @basephp {
root /var/www/base;
try_files $uri ERROR;
fastcgi_pass 127.0.0.1:9000;
}

Is there anything nicer I can put in the last try_files, instead of the
nonexistent file “ERROR”?

Tobia

On Wed, Dec 30, 2009 at 3:39 AM, Tobia C.
[email protected] wrote:

try_files $uri @base;
root /var/www/base;
nginx Info Page

The final parameter for try_files SHOULD be a guaranteed to exist
location (such as your static 404 page).

if does indeed add a bit of overhead into things but there’s no real
numbers to suggest how much – for most purposes it’s obviously not
TOO much, but there’s no point in wasting resources just to waste
them, either.

– Merlin

`

On Tue, Dec 29, 2009 at 3:27 PM, Tobia C.
[email protected] wrote:

This, for example, I wouldn’t have guessed in a million years:

Tobia


nginx mailing list
[email protected]
nginx Info Page

You’re welcome. Please note a small typo, I did not end the
error_page declaration with a semicolon. There might be other small
errors I apologize for :). If you review the documentation at
http://wiki.nginx.org regarding these directives it should all be very
clear to you :).

Good luck!
– Merlin