Moving Joomla from subdir to root -> rewrite / redirect problem

Francis Daly francis at
Sat Dec 23 12:27:43 UTC 2017

On Fri, Dec 22, 2017 at 07:57:16PM +0100, Johannes Rohr wrote:
> Am 18.12.2017 um 20:36 schrieb Francis Daly:
> > On Fri, Dec 15, 2017 at 03:25:20PM +0100, Johannes Rohr wrote:

Hi there,

> > As in: when I request /web/something, should I get a http redirect so
> > that I next request /something; or should I get something else?
> Yes, sure, that's precisely what I want to achive


  location ^~ /web/ { rewrite /web(/.*) $1 permanent; }

to your previously-working nginx config. Report if anything now does
not work as you want it to.

The rest of this mail is background information; the above config addition
might be all that you need.

> > Without knowing joomla... why is this obvious? Why would arguments to
> > index.php include /web/?
> Because that is the subdir where it is currently installed. (which I
> want to change)

Ok. I still don't understand why arguments to index.php would include
/web/, but I guess that I don't need to understand it.

> >> location / {
> >>     rewrite ^/web/(.*)$ /$1;
> >>   try_files $uri $uri/ /index.php?$args;
> >> }
> >>
> >> thinking that the first line would modify the URI, taking away the /web/
> >> part so that in the next line the changed uri would be fed to the
> >> try_files command.


Your "rewrite" will start with /web/something and end with /something,
and then nginx will find the correct location{} to handle /something,
which may or may not be this location{}, depending on what other
location{}s are defined.

> > (I'd probably include "break" on the rewrite line; but it might depend
> > on what the rest of your config says.)
> Why? Doesn't "break" mean that processing is ended after the current
> line? What I want is that the re-written url is then fed to the
> try_files directive below, which calls joomla's index.php

"break" says "stops processing the current set of ngx_http_rewrite_module
directives" with "If a directive is specified inside the location,
further processing of the request continues in this location.". And you
want the processing to be in this location, and not start the normal
search for the correct location for the new subrequest /something.

>         location / {
> if ($request_uri ~* "^/web/(.*/)$") {
>         return 301 $1;
>     }
>                 try_files $uri $uri/ /index.php?$args;
>         }
> I kind of hoped this would would catch each request that contails /web/
> and rewrite it into something with /web/ stripped and then feed it to
> try_files directive below.

If this location{} is used for /web/something, then the browser gets a
301 redirect and makes a whole new request for /something.

If this location{} is used for /something, then the try_files will be used.

> But in the nginx log I see:
> 2017/12/22 19:43:55 [error] 21149#21149: *19151503 FastCGI sent in
> stderr: "Unable to open primary script:
> /var/www/chrooted/jrweb/htdocs/ (No such file
> or directory)" while reading response header from upstream, client:
>, server:, request: "GET
> /web/index.php?format=feed&type=rss HTTP/1.1", upstream:
> "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: ""
> So, somehow, the rewrite is not happening, nginx still looks for
> /web/index.php instead of /index.php

Is the location{} above used for the request /web/index.php?

I suspect you may have another location like

  location ~ php

that means that your "location /" will not be used for the request

> I find this topic so confusing (and reading the official nginx docs does
> not make the confusion go away), would be grateful if anyone could
> enlighten me!

In nginx, one request is handled in one location.

Under certain circumstances, including "rewrite", one http request might
lead to an nginx request followed by an nginx subrequest; that subrequest,
in general, counts as a new request to nginx.

Something like "grep location nginx.conf" might show all of the
location{}s that are defined for this server{}; given that, and the
documented rules, it should be possible to see which one location a
specific request is handled in.

(Note: "rewrite"-module directives can change the logic, so it is not
necessarily as straightforward as described there.)

Francis Daly        francis at

More information about the nginx mailing list