I'm trying to set up a multisite subdirectory install on NGINX, with WordPress core in its own subdirectory, and running into some trouble.

I'm using this file structure:

/home/site/dev.site.com/current/public/ --- path to webroot /home/site/dev.site.com/current/public/wp/ --- path to WP root /home/site/dev.site.com/current/public/wp/wp-admin/ --- path to WP admin root

My desired URL structure is:

dev.site.com/wp-admin/network/ --- network admin dev.site.com/ --- root site dev.site.com/wp-admin/ --- root site admin dev.site.com/[sitename] --- additional sites dev.site.com/[sitename]/wp-admin --- additional site admin

My NGINX multisite rewrites are:

rewrite ^/([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) /wp/$2 last; rewrite ^/([_0-9a-zA-Z-]+/)?(.*\.php)$ /wp/$2 last;

My full NGINX config is here.

Currently, I can access the network admin (at dev.site.com/wp-admin/network/), the root site (at dev.site.com), and the root site admin dashboard (at dev.site.com/wp-admin/).

When I try to access any of the additional sites (dev.site.com/[sitename]) I get 404s (handled by WordPress). When I try to access their admin panels (dev.site.com/[sitename]/wp-admin/) I get the root site's admin dashboard (at the URL that includes the [sitename]).

I'm a bit baffled as to why this isn't working - everything seems correct, but clearly I'm missing some essential bit. My assumption is that this is related to my nginx configuration, but I'm not entirely sure.

Anyone have experience with this type of configuration? Help is greatly appreciated!

EDIT: I've checked my rewrite log and nginx seems to be handling the rewrite correctly, and passes the correct GET URL and all:

2014/09/22 10:38:35 [notice] 4857#0: *54 rewritten data: "/wp/wp-admin/index.php", args: "", client:, server: dev.site.com, request: "GET /subsite/wp-admin/ HTTP/1.1", host: "dev.site.com", referrer: "http://dev.site.com/wp/wp-admin/"

For some reason, WP admin isn't picking up that the request is for the subsite, and just returning the site root instead...

EDIT 2: I set up a mu-plugin that just spits out get_admin_url(), and it appears WordPress definitely thinks it's in a different place than the URL it's actually returning. When I hit dev.site.com/subsite/wp-admin/, get_admin_url() returns http://dev.site.com/wp-admin/, the path to the root site admin. The plot thickens...

EDIT 3: (Sorry for all the edits.) I can force the correct blog to load by writing a function that hooks into init and runs switch_to_blog( $id ), but that's obviously a brute-force solution. WordPress should know which blog to load, and just load it, gosh darnit.

  • well, that tip to log get_admin_url showed me i was missing a / in the nginx rewrites! thanks!
    – pcarvalho
    Commented Mar 15, 2020 at 2:39

1 Answer 1


I'm not 100% sure how I fixed this, but I did.

A few things I did:

Make sure you clear your cookies, or test in an incognito window. Login cookies caused me some problems.

I replaced my nginx rewrites with:

rewrite ^/(site1/|site2/|site3/)?(wp-(content|admin|includes).*)$ /wp/$2 break; rewrite ^/(?!wp/)(site1/|site2/|site3/)?(.*\.php)$ /wp/$2 break;

Because I'm dealing with a small network with clearly defined sites, I was able to include them directly in the regex. You may need to do something more broad; ymmv.

After restarting my server and clearing cookies, this seemed to do the trick!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.