Clean-URL rewrite rule with nested "location" and alias directive

Francis Daly francis at daoine.org
Fri Nov 22 02:16:22 UTC 2013


On Thu, Nov 21, 2013 at 08:45:02PM +0000, Francis Daly wrote:
> On Wed, Nov 20, 2013 at 10:31:07PM -0500, Ben Johnson wrote:

...and one more possibility...

If your application directory structure is such that:

  /var/www/myapp/web/

contains only static files that should be served as-is if requested,
with appropriate "index" files for some directories if wanted; and

  /var/www/myapp/php/

contains "myapp.php", which is the single controlling script that will
always be called if the web request is not for a static file; and

whatever other scripts, templates, and other things that are necessary
for myapp.php to refer to are here, or are anywhere other than in
/var/www/myapp/web/,

and the application should be accessible from the web url "/app1/",

then possibly all the locations you need are

===
    # all requests for this app
    location ^~ /app1/ {
      alias /var/www/myapp/web/;
      error_page 404 403 = @app1;
    }
    # the main controller. Set whatever you want in the include file
    location @app1 {
      fastcgi_pass unix:php.sock;
      fastcgi_param SCRIPT_FILENAME /var/www/myapp/php/myapp.php;
      include fastcgi_params;
    }
===

> > 	if ($uri ~ '/download/.*/$') {
> > 		rewrite ^/(.*)/$ /$1 permanent;

> > 	if ($uri !~ '(/|\.[a-zA-Z0-9]{1,12}|/download/.*)$') {
> > 		return 301 $uri/$is_args$args;

> > 	if ($uri ~ '(/|/download/.*|/css2/.*|/js2/.*)$') {
> > 		rewrite  ^(.*)$  /index.php?q=$1  last;

If you want to keep those "rewrites" within nginx.conf, just use the
first two directly within @app1, and I think the third will not be needed.

myapp.php should be able to find all it needs in _SERVER["DOCUMENT_URI"],
so it shouldn't need _REQUEST["q"].

And a staging version would merely be another application -- copy the
two locations, change the prefix and name, change the alias, error_page,
and SCRIPT_FILENAME. All done.

An application at / or at /sub/url/ would be no different. You might be
able to use "root" instead of "alias" in some cases, but I don't think
it matters here.

> > If there is a better, more concise, or more secure way to accomplish the
> > above, then I am eager to learn.

The above is more concise -- partly because it tries to do less. The
previous version allowed you to access the urls /app1/one.php
and /app1/two.php in the client, and the separate files would be
processed. This version would return the php files directly from web/,
or would let php/myapp.php decide what to do if the files aren't in web/.

That's the key to the smaller config -- nginx only tells the fastcgi
server to process a single file.

	f
-- 
Francis Daly        francis at daoine.org



More information about the nginx mailing list