NginX, Multisite and Rewrite rules

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
ahankinson's picture

I'm looking for some help with rewrite rules and multisite. I would like to have the following set up:

  1. The "Main" Drupal site, hosted at www.example.com and with all of its modules and themes at /sites/example.com
  2. A "Sub" Drupal site, hosted at www.example.com/subsite and with all of its modules and themes at /sites/example.com.subsite

So far #1 works beautifully with the following rewrite rule:

location / {
                root /www/example;
                index index.php index.html;

                if (!-e $request_filename) {
                        rewrite ^/(.*)$ /index.php?q=$1 last;
                        break;
                }
        }

I haven't been able to get #2 working, though. I've tried many different rewrite rules, most of which give me a "404" or "no input file specified. I was thinking it would be something like:

location ~^ /subsite/ {
             root /www/example;
             rewrite ^/subsite/(.*)$ ^/index.php?q=$1 last;
}

but that doesn't seem to work.

Any pointers out there?

Comments

That's an unusual setup. Can

brianmercer's picture

That's an unusual setup. Can Drupal's multisite feature handle that situation in Apache? A primary install in the root of a domain and a separate install in a subdirectory?

From reading INSTALL.txt it

ahankinson's picture

From reading INSTALL.txt it would seem it should:

Sites do not have to have a different domain. You can also use subdomains and
subdirectories for Drupal sites. For example, example.com, sub.example.com,
and sub.example.com/site3 can all be defined as independent Drupal sites. The
setup for a configuration such as this would look like the following:

sites/default/settings.php
sites/example.com/settings.php
sites/sub.example.com/settings.php
sites/sub.example.com.site3/settings.php

When searching for a site configuration (for example www.sub.example.com/site3),
Drupal will search for configuration files in the following order, using the
first configuration it finds:

sites/www.sub.example.com.site3/settings.php
sites/sub.example.com.site3/settings.php
sites/example.com.site3/settings.php
sites/www.sub.example.com/settings.php
sites/sub.example.com/settings.php
sites/example.com/settings.php
sites/default/settings.php

Unless I'm reading it wrong?

Apparently that structure is

brianmercer's picture

Apparently that structure is supported for subdirectories. Live and learn.

This fellow suggests symlinks from the subdirectories back to the document root without any special rewrites.

http://www.suffix.be/blog/drupal-multi-site/

So maybe comment out that /subsite/ block and try

ln -s /www/example /www/example/subsite

Assuming that your subsite

macedigital's picture

Assuming that your subsite has its own settings and is supposed to be particularly different from "main" site, a symlink is probably not an option.

Out of curiosity I setup the following sites folders (each with different settings.php files outputting debug info)
/sites/8080.www.example.com
/sites/8080.www.example.com.mysite
/sites/8080.www.example.com.mysite.test

Now, according to the comments from the top any settings.php, drupal should be using the third site when an request like http://www.example.com:8080/mysite/test/ comes in. But in fact it does not, it will joyfully use the first site and put out e.g. a 404-page. I can reproduce this behavior with apache 2.2.14 and drupal 6.15 as well, so this does not appear to be a problem with nginx per se.

For the time being I cannot provide a solution, but I'll continue to check things out over the course of the weekend ... stay tuned

I meant to report back: I

ahankinson's picture

I meant to report back: I tried the symlink option and it worked partially. I managed to get it to an install page and run through the installer, but afterwards all the paths to the themes were broken. It seemed like the paths to the modules and themes were broken, as madler suggests.

Madler: does a one-level subfolder work in Apache, e.g. /sites/8080.www.example.com.mysite? The behaviour you're describing is exactly what I see: the "main" site is giving me a 404 when it should be forwarding to the subfolder site.

As a quick follow-up, the

macedigital's picture

As a quick follow-up, the workaround presented in http://www.suffix.be/blog/drupal-multi-site/ works, because you're actually having sort of a 'folder' with respective subsite url-argument in you're webroot, so mod_rewrite/nginx rewrite rules aren't triggered.
@ahankinson
if you can live with that, I'd recommend you just symlink [docroot]/subsite -> [docroot] and everything should be working as expected (you won't have to put any rewrite rules in place for your subsite, then, as mentioned above).

UPDATE: input-filters stripped [docroot] string ...

Thanks! I just had a quick

ahankinson's picture

Thanks! I'm guessing this won't work with pretty URLs, though?

I just had a quick look at the conf_path function in includes/bootstrap.inc, and it seems like it only supports one level of subdirectories:

--- snip ---
      if (file_exists("$confdir/$dir/settings.php") || (!$require_settings && file_exists("$confdir/$dir"))) {
        $conf = "$confdir/$dir";
        return $conf;
      }
--- snip ---

no,

macedigital's picture

no, /sites/8080.www.example.com.mysite did not work either, it will fallback to /sites/8080.www.example.com regardless.

To solve your theme / module path issues, uncomment the $base_url declaration in your subsite's settings.php and use an url like :
$base_url = 'http://www.example.com/subsite';

This way drupal will prefix all links outtputted with this base url so all content (incl. css/js-files, etc) is pulled from your subsite

You're right. I set it up

brianmercer's picture

You're right. I set it up and no clean URLs with just the symlink.

If you're just doing the one subdirectory, this seems to work fine for clean URLs:

location / {
  root /www/example;
  index index.php index.html;

  if (!-e $request_filename) {
    rewrite ^/subsite(/|)(.*)$ /subsite/index.php?q=$2 last; 
    rewrite ^/(.*)$ /index.php?q=$1 last;
    break;
  }
}

If you're doing it often, I'll try to think of a more generic approach.

BTW, these days (post version 0.7.21 or so) I use try_files, i.e.:

server {
  ...
  root /www/example;
  index index.php index.html;

  location / {
    try_files $uri @drupal;
  }

  location @drupal {
    rewrite ^/test(/|)(.*)$ /test/index.php?q=$2 last;
    rewrite ^/(.*)$ /index.php?q=$1 last;
  }

  ...
}

Works great. Thanks for

haagendazs's picture

Works great. Thanks for sharing!

With that extra rewrite,

brianmercer's picture

With that extra rewrite, everything is working fine for me using the /sites/example.com.subsite format; clean urls, themes, images, aggregated css/js, etc.

If you're still having problems, please post your entire nginx server config.

Edit: I did not have to change the $base_url, though that's a good suggestion.

my bad, like brianmercer

macedigital's picture

my bad, like brianmercer said, you have to put those rewrite rules into effect and then everything works as expected with nginx. Changing $base_url also is somewhat redundant, but I'd do it anyways for good measure.

Last time around I was kind of lazy and just used apache w/ mod_php and option +follow_symlink. sorry for that.

My rewrite isn't perfect. If

brianmercer's picture

My rewrite isn't perfect. If you have a page called http://www.example.com/testing-page on the main site, you'd get a 404 from the subsite. Still looking for a foolproof rewrite.

The question is, should

brianmercer's picture

The question is, should http://www.example.com/test go to a page on the main site or to the root of the subsite?

If the first, then you can use:

   rewrite ^/test/(.*)$ /test/index.php?q=$1 last;

but if the second case, then add:

rewrite ^/test$ /test/ permanent;

to redirect /test to /test/ with a 301 and avoid a duplicate content penalty for seo.

@brianmercer: I tried the

ahankinson's picture

@brianmercer: I tried the second case, and I get a 404 from the main site. I tried the first case, and I get the "no input file found" error.

Here's my nginx virtual host config. I've had to obfuscate the real names & addresses, since I don't want Google picking up this site yet, but I've tried to be consistent:

server {
listen      111.222.33.44:80;
  server_name     www.example.com;

  access_log  /var/log/httpd/example.com/access_log;
error_log   /var/log/httpd/example.com/error_log debug;

   root        /mnt/example.com;
        index     index.php index.html;

## Deny some crawlers
      if ($http_user_agent ~* (HTTrack|HTMLParser|libwww) ) {
            return 444;
        }
      ## Deny certain Referers (case insensitive)
        if ($http_referer ~* (poker|sex|girl) ) {
          return 444;
        }
 
   location / {
       try_files $uri @drupal;
   }

location @drupal {
     # rewrite ^/subsite$ /subsite/ permanent;
      rewrite ^/subsite(/|)(.)$ /subsite/index.php?q=$2 last;
       rewrite ^/(.
)$ /index.php?q=$1 last;
  }
 
   # hide protected files
        location ~* .(engine|inc|info|install|module|profile|po|sh|.sql|theme|tpl(.php)?|xtmpl)$|^(code-style.pl|Entries.|Repository|Root|Tag|Template)$ {
             deny all;
  }  
  
   location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|flv|mp4|mp3|m4v|mov|pdf)$ {
      root        /mnt/example.com;
      access_log  off;
       expires     30d;
   }
     
   error_page 404 /index.php;
error_page 500 502 503 504 /index.php;

   location ~ .php$ {
        fastcgi_pass    127.0.0.1:9000;
       fastcgi_index   index.php;
     fastcgi_param   SCRIPT_FILENAME /mnt/example.com$fastcgi_script_name;
      include     /usr/local/etc/nginx/fastcgi_params;
   }
}

server {
  listen 111.222.33.44:80;
   server_name example.com;
   rewrite ^/(.)$ http://www.example.com/$1 permanent;
}

server {
   listen 111.222.33.44:80;
   server_name example.net www.example.net;
   rewrite ^/(.
)$ http://www.example.com/$1 permanent;
}

In the root (/mnt/example.com) I have a symlink "subsite" pointing to /mnt/example.com/sites/example.com.subsite. The main NginX file is largely the default, and it Includes this virtualhost definition at the end. (e.g. "Include /usr/local/etc/nginx/sites/example.com.conf")

The symlink should not point

brianmercer's picture

The symlink should not point to the drupal sites subdirectory. It should point to the domain's document root. So:

ln -s /mnt/example.com /mnt/example.com/subsite

Sorry, I went back and edited

brianmercer's picture

Sorry, I went back and edited those other rewrites to this:

  location @drupal {
    # rewrite ^/subsite$ /subsite/ permanent;
    rewrite ^/subsite/(.*)$ /subsite/index.php?q=$1 last;
    rewrite ^/(.)$ /index.php?q=$1 last;
  }

That's just fine for functionality.

Uncomment the first rewrite (keep all three) if you want http://www.example.com/subsite to go to the root of the subdirectory install. I was trying to streamline it into one directive, but for SEO purposes you would want it to be a 301 redirect (permanent) from http://www.example.com/subsite to http://www.example.com/subsite/ (or the other way, arguably) to avoid /subsite and /subsite/ having identical content and being penalized by some stupid search bot that doesn't account for the trailing slash.

I'm obviously missing

ahankinson's picture

I'm obviously missing something here.

I fixed the symlink to point /mnt/example.com/subdir to /mnt/example.com, e.g.

$ ls /mnt/example.com/subdir
lrwxr-xr-x  1 www  www    23B Dec 19 17:08 /mnt/example.com/subdir -> /mnt/example.com

I've also set the $base_url directive in /sites/example.com.subdir/settings.php to "http://www.example.com/subdir"

I can now successfully load the sub-site, except without any theming, and with constant PHP errors, e.g:

warning: array_map() [function.array-map]: Argument #2 should be an array in /mnt/example.com/modules/system/system.module on line 1059.
warning: array_keys() [function.array-keys]: The first argument should be an array in /mnt/example.com/includes/theme.inc on line 1771.
warning: Invalid argument supplied for foreach() in /mnt/example.com/includes/theme.inc on line 1771.

and

warning: array_map() [function.array-map]: Argument #2 should be an array in /mnt/example.com/modules/system/system.module on line 1059.
warning: array_keys() [function.array-keys]: The first argument should be an array in /mnt/example.com/includes/theme.inc on line 1771.
warning: Invalid argument supplied for foreach() in /mnt/example.com/includes/theme.inc on line 1771.
user warning: Duplicate entry 'themes/bluemarine/bluemarine.info' for key 1 query: INSERT INTO system (filename,name,type,owner,bootstrap,info) VALUES ('themes/bluemarine/bluemarine.info','bluemarine','','themes/engines/phptemplate/phptemplate.engine',0,'a:13:{s:4:\"name\";s:10:\"Bluemarine\";s:11:\"description\";s:66:\"Table-based multi-column theme with a marine and ash color scheme.\";s:7:\"version\";s:4:\"6.15\";s:4:\"core\";s:3:\"6.x\";s:6:\"engine\";s:11:\"phptemplate\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1260996916\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:9:\"style.css\";s:27:\"themes/bluemarine/style.css\";}}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:27:\"themes/bluemarine/script.js\";}s:10:\"screenshot\";s:32:\"themes/bluemarine/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}') in /mnt/example.com/modules/system/system.module on line 863.
user warning: Duplicate entry 'themes/chameleon/chameleon.info' for key 1 query: INSERT INTO system (filename,name,type,owner,bootstrap,info) VALUES ('themes/chameleon/chameleon.info','chameleon','','themes/chameleon/chameleon.theme',0,'a:12:{s:4:\"name\";s:9:\"Chameleon\";s:11:\"description\";s:42:\"Minimalist tabled theme with light colors.\";s:7:\"regions\";a:2:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";}s:8:\"features\";a:4:{i:0;s:4:\"logo\";i:1;s:7:\"favicon\";i:2;s:4:\"name\";i:3;s:6:\"slogan\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:2:{s:9:\"style.css\";s:26:\"themes/chameleon/style.css\";s:10:\"common.css\";s:27:\"themes/chameleon/common.css\";}}s:7:\"version\";s:4:\"6.15\";s:4:\"core\";s:3:\"6.x\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1260996916\";s:7:\"scripts\";a:1:{s:9:\"script.js\";s:26:\"themes/chameleon/script.js\";}s:10:\"screenshot\";s:31:\"themes/chameleon/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}') in /mnt/example.com/modules/system/system.module on line 863.
user warning: Duplicate entry 'themes/garland/garland.info' for key 1 query: INSERT INTO system (filename,name,type,owner,bootstrap,info) VALUES ('themes/garland/garland.info','garland','','themes/engines/phptemplate/phptemplate.engine',0,'a:13:{s:4:\"name\";s:7:\"Garland\";s:11:\"description\";s:66:\"Tableless, recolorable, multi-column, fluid width theme (default).\";s:7:\"version\";s:4:\"6.15\";s:4:\"core\";s:3:\"6.x\";s:6:\"engine\";s:11:\"phptemplate\";s:11:\"stylesheets\";a:2:{s:3:\"all\";a:1:{s:9:\"style.css\";s:24:\"themes/garland/style.css\";}s:5:\"print\";a:1:{s:9:\"print.css\";s:24:\"themes/garland/print.css\";}}s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1260996916\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:24:\"themes/garland/script.js\";}s:10:\"screenshot\";s:29:\"themes/garland/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}') in /mnt/example.com/modules/system/system.module on line 863.
user warning: Duplicate entry 'themes/chameleon/marvin/marvin.info' for key 1 query: INSERT INTO system (filename,name,type,owner,bootstrap,info) VALUES ('themes/chameleon/marvin/marvin.info','marvin','','',0,'a:13:{s:4:\"name\";s:6:\"Marvin\";s:11:\"description\";s:31:\"Boxy tabled theme in all grays.\";s:7:\"regions\";a:2:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";}s:7:\"version\";s:4:\"6.15\";s:4:\"core\";s:3:\"6.x\";s:10:\"base theme\";s:9:\"chameleon\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1260996916\";s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:9:\"style.css\";s:33:\"themes/chameleon/marvin/style.css\";}}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:33:\"themes/chameleon/marvin/script.js\";}s:10:\"screenshot\";s:38:\"themes/chameleon/marvin/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}') in /mnt/example.com/modules/system/system.module on line 863.
user warning: Duplicate entry 'themes/garland/minnelli/minnelli.info' for key 1 query: INSERT INTO system (filename,name,type,owner,bootstrap,info) VALUES ('themes/garland/minnelli/minnelli.info','minnelli','','themes/engines/phptemplate/phptemplate.engine',0,'a:14:{s:4:\"name\";s:8:\"Minnelli\";s:11:\"description\";s:56:\"Tableless, recolorable, multi-column, fixed width theme.\";s:7:\"version\";s:4:\"6.15\";s:4:\"core\";s:3:\"6.x\";s:10:\"base theme\";s:7:\"garland\";s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:12:\"minnelli.css\";s:36:\"themes/garland/minnelli/minnelli.css\";}}s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1260996916\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:33:\"themes/garland/minnelli/script.js\";}s:10:\"screenshot\";s:38:\"themes/garland/minnelli/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";s:6:\"engine\";s:11:\"phptemplate\";}') in /mnt/example.com/modules/system/system.module on line 863.
user warning: Duplicate entry 'themes/pushbutton/pushbutton.info' for key 1 query: INSERT INTO system (filename,name,type,owner,bootstrap,info) VALUES ('themes/pushbutton/pushbutton.info','pushbutton','','themes/engines/phptemplate/phptemplate.engine',0,'a:13:{s:4:\"name\";s:10:\"Pushbutton\";s:11:\"description\";s:52:\"Tabled, multi-column theme in blue and orange tones.\";s:7:\"version\";s:4:\"6.15\";s:4:\"core\";s:3:\"6.x\";s:6:\"engine\";s:11:\"phptemplate\";s:7:\"project\";s:6:\"drupal\";s:9:\"datestamp\";s:10:\"1260996916\";s:7:\"regions\";a:5:{s:4:\"left\";s:12:\"Left sidebar\";s:5:\"right\";s:13:\"Right sidebar\";s:7:\"content\";s:7:\"Content\";s:6:\"header\";s:6:\"Header\";s:6:\"footer\";s:6:\"Footer\";}s:8:\"features\";a:10:{i:0;s:20:\"comment_user_picture\";i:1;s:7:\"favicon\";i:2;s:7:\"mission\";i:3;s:4:\"logo\";i:4;s:4:\"name\";i:5;s:17:\"node_user_picture\";i:6;s:6:\"search\";i:7;s:6:\"slogan\";i:8;s:13:\"primary_links\";i:9;s:15:\"secondary_links\";}s:11:\"stylesheets\";a:1:{s:3:\"all\";a:1:{s:9:\"style.css\";s:27:\"themes/pushbutton/style.css\";}}s:7:\"scripts\";a:1:{s:9:\"script.js\";s:27:\"themes/pushbutton/script.js\";}s:10:\"screenshot\";s:32:\"themes/pushbutton/screenshot.png\";s:3:\"php\";s:5:\"4.3.5\";}') in /mnt/example.com/modules/system/system.module on line 863.

I've tried going in to the admin themes section, but no luck. All of the base themes show up, but if I try to set one as enabled it does not save.

What's even stranger is if I use your first rewrite rule (the 'permanent' redirect) I can access the site (without themeing but through the 'dirty' url, e.g. index.php?q=admin, and the clean URLs show as being 'not supported by my server.'

If I change it to the second option (with 'index.php?q=') in it, suddenly the clean URLs will work in the sub-site, but it will still be displayed without themes and with the PHP errors.

In the head of the front page of the sub-site instance (www.example.com/subdir) I have this, which may shed some light on it:

<link type="text/css" rel="stylesheet" media="all" href="/subdir/modules/node/node.css?U" />
<link type="text/css" rel="stylesheet" media="all" href="/subdir/modules/system/defaults.css?U" />
<link type="text/css" rel="stylesheet" media="all" href="/subdir/modules/system/system.css?U" />
<link type="text/css" rel="stylesheet" media="all" href="/subdir/modules/system/system-menus.css?U" />
<link type="text/css" rel="stylesheet" media="all" href="/subdir/modules/user/user.css?U" />

I checked my php error log and it's absolutely silent on this matter.

Just for completeness, here's my nginx.conf file:

user  www www;
worker_processes  4;
worker_rlimit_nofile 8192;

events {
   worker_connections 2048;
}


http {
   include       mime.types;
   default_type  application/octet-stream;

   log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
      '$status $body_bytes_sent "$http_referer" '
      '"$http_user_agent" "$http_x_forwarded_for"';

   ## Size Limits
   client_body_buffer_size   8k;
   client_header_buffer_size 1k;
   large_client_header_buffers 4 4k;

   ## Timeouts
   client_body_timeout   5;
   client_header_timeout 5;
   keepalive_timeout     5 5;
   send_timeout          5;

   ## General Options
   ignore_invalid_headers   on;
   limit_zone gulag $binary_remote_addr 1m;
   recursive_error_pages    on;
   sendfile                 on;
   #server_name_in_redirect off;
   #server_tokens           off;

   ## TCP options 
   tcp_nodelay on;
   tcp_nopush  on;

   ## Compression
   gzip              on;
   gzip_buffers      16 8k;
   gzip_comp_level   9;
   gzip_http_version 1.0;
   gzip_min_length   0;
   gzip_types        text/plain text/html text/css image/x-icon image/bmp text/javascript application/json application/x-javascript application/xml application/xml+rss;
   gzip_vary         on;
  
   #server {
   #   server_name  _;  #default
   #   return 444;
   #}
  
  
   include /usr/local/etc/nginx/sites/*;

}

First, regarding the

brianmercer's picture

First, regarding the rewrites, the second and third lines here must always be present:

  location @drupal {
    rewrite ^/subsite$ /subsite/ permanent;
    rewrite ^/subsite/(.*)$ /subsite/index.php?q=$1 last;
    rewrite ^/(.)$ /index.php?q=$1 last;
  }

The first line is optional, and can be used IN ADDITION TO the second and third, but is not a substitute for the second.

I recommend that you simply use all three.

Second, make sure that you clear caches between any changes. Nine times out of ten, that's what causes theme errors. You can either go to the "Performance" page at http://www.example.com/admin/settings/performance and press the clear cache button at the bottom, or if things get very wonky you can always go to http://www.example.com/update.php and run the script there and that will always clear caches even if there are no updates to run. Another method is to install the devel module and put the development menu in the footer and then you'll have always have a nice menu link for clearing caches on every page. Then you can disable the module when you go to production. (devel also has a setting to clear caches on every page load which is very handy for development, but must be turned off for production)

Thirdly, if your theme isn't showing up, then read the source of the page and look at where the theme file links are pointing. If you've got firebug loaded, you can go to the net tab and look at the address it is using for the css files. If not, then open the source of the front page and the css file links will be in the "head" section at the top. See what address is listed there. It must be pointing to the wrong address, but if you see where it actually is pointing, it can tell you what's causing the problem.

The subdirectory multisite feature does seem a bit obscure and poorly documented, but since it's working on my test server, it does work.

Works for single directory

alex.cunha's picture

Works for single directory but not when:

location @d6rewrite {
    rewrite ^/dir/subsite$ /dir/subsite/ permanent;
    rewrite ^/dir/subsite/(.*)$ /dir/subsite/index.php?q=$1 last;
    rewrite ^/(.)$ /index.php?q=$1 last;
  }

Is there any regex that can handle any directory and multiple sites like:
dir/subsite1
dir/subsite2

whitout hardcode subsite1, 2, etc..

thanks

Maybe...

aharown07's picture

Haven't tested in that situation (yet) but you might check this tutorial at vpsBible...
http://vpsbible.com/content-management/drupal7-nginx-curls/

He has a particular directory structure in mind:
home/username/public_html/sitename.com/public

There's another tutorial there that might be closer to what you're doing...
http://vpsbible.com/content-management/drupal-nginx-multi-domains/

Some of this is premium content I think.
His rules...

if (!-e $request_filename)
                {
                    rewrite ^/(.*)$ /index.php?q=$1 last;
                }

I'm too much of a noob to know if this helps you but if you sign up, there's a pretty good forum there and someone might have the info you're after

Well if you have "/dir/" in

brianmercer's picture

Hmm

Well if you have "/dir/" in there you could do something like this:

location @d6rewrite {
    rewrite ^/dir/([a-z]+)$ /dir/$1/ permanent;
    rewrite ^/dir/([a-z]+)/(.*)$ /dir/$1/index.php?q=$2 last;
    rewrite ^/(.)$ /index.php?q=$1 last;
  }

Without some kind of marker like that, I'm not sure how you'd differentiate it from your regular paths.

That [a-z]+ is not the ideal regex since it excludes numbers and periods and other things legitimate in urls. I forget the "correct" regex at the moment.

Thank you all so very much.

ahankinson's picture

Thank you all so very much. It's working now. It turned out that the theming issue was unrelated to NginX

For interest's sake, it was this bug: http://drupal.org/node/307756. The "type" column for each theme was blank for some reason, so I inserted "theme" in there and then everything worked beautifully.

Patch

mikeytown2's picture

Does the patch at 307756 (Backport of #147000: Unify and rewrite module_rebuild_cache() and system_theme_data()) fix the error? if so, say so on that issue; the more people we have saying a patch has been tested and works in that issue, the better chance we have of it making into core.

I'm glad things are working.

brianmercer's picture

I'm glad things are working. I always use Pressflow these days. Unfortunately, they don't list all the patches they apply.

dynamic subsites

bonn's picture

Hi, i'm building a drupal module which allows drupal to automatically create subsite (by subfolder method)

so: mysite.com will mapped to folder default, and mysite.com/site1 will mapped to folder mysite.com.site1. My custom drupal module automate the creation of foldermysite.com.site1 via GUI interface from my main drupal site (mysite.com).

The problem is, if I use Apache, all this clean urls are working out of the box (main site and subsites), now I use nginx and having this difficulties.

The nginx rewrite rules above, need subsite rule to be added each time a subsite is created, so my automatic subsites module, will not work unless the subfolder rule is added to my nginx virtual site rule.

Any suggestions?

I got a working subfolder

bonn's picture

I got a working subfolder from here: http://wiki.nginx.org/Drupal

location / {
  # This is cool because no php is touched for static content
  try_files $uri @rewrite;
}
location @rewrite {
  # Drupal in a subdirectory
  rewrite ^/([^/])/(.)(/?)$ /$1/index.php?q=$2&$args;
}

It works with dynamic subsites (subfolder), but now the main site is not working

Two level subfolder

ranm's picture

Hi,
I've written a rewrite for two level subfolder if anyone needs it :

location / {
  try_files $uri @drupal;
}

location @drupal {
  rewrite ^/([^/])/([^/])([/])(.)$ /index.php?q=$4&$args;
}

ranm

There's no need for any rewrite

perusio's picture

you just have to set the proper fastcgi_param in the PHP handling location. Or re-define the root directive.

Sure, I needed it since this

ranm's picture

Sure, I needed it since this directory was directed from other server via proxy, so, for that it's useful if required (-: