Drupal 7 and nginx on Virtualmin

I have installed nginx 1.2.7 using the nginx repo on my CentOS box that also uses Virtualmin Pro. Ideally I’ll have multiple Virtualmin shared hosts using nginx and no apache; some vhosts running Drupal 6 and 7, some not. I can get almost everything to work at once but usually what happens is if I get one thing to work, something else breaks.

I’ve based my config mostly on the Drupal boost example because that seems the simplest and at this point I just want it to work. Here is my nginx config file, a sample vhost file, and the drupal include I’m using (in any vhost running Drupal 7). Any help would be much appreciated. mysite.com represents my domain, and represents my public IP.

Basically what’s happening now is I can get to the clean-url test page, (and can check the box! as in, the test succeeds) but all else fails after checking the box. I get an empty 1x1 location (as specified in the config) upon submitting that form. Below these 3 config files is my latest error message I can’t seem to deal with.


user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;

events {
worker_connections 768;

http {
include /etc/nginx/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"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
#tcp_nopush     on;

keepalive_timeout  65;

#gzip  on;

include /etc/nginx/conf.d/*.conf;
server_names_hash_bucket_size 128;
index "index.php index.html";



server {
server_name mysite.com www.mysite.com;
root /home/mysite.com/public_html;
index index.php index.html;
access_log /var/log/virtualmin/mysite.com_access_log;
error_log /var/log/virtualmin/mysite.com_error_log;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME /home/mysite.com/public_html$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT /home/mysite.com/public_html;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https;
location ~ .php$ {
try_files $uri =404;
error_page 404 = @rewrite; # $uri =404;
fastcgi_pass unix:/var/php-nginx/13627035037928.sock/socket;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
include drupal7;
listen default ssl;
ssl_certificate /home/mysite.com/ssl.cert;
ssl_certificate_key /home/mysite.com/ssl.key;

the /etc/nginx/drupal7 file:

charset utf-8;

search for already compressed files

gzip_static on;
gzip on;

some images have no mime type

default_type image/jpeg;

Buffers definition. allows of up to 260k to be passed in memory.

client_body_buffer_size 1m;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 32k;

404 generated from php can be rather slow. Uncomment with care

#error_page 404 /index.php;

disallow access to version control directory, but return 404, not to disclose information

location /.git {
return 404;

robots.txt is important for search engines

location /robots.txt {
access_log off;

This is mostly based on Drupal’s stock .htaccess

location ~* ^.+(.(txt|engine|inc|info|install|module|profile|po|sh|.sql|theme|tpl(.php)?|xtmpl)|code-style.pl|/Entries.|/Repository|/Root|/Tag|/Template)$ {
return 404;

serve imagecache files directly or redirect to drupal if they do not exist

location ~* imagecache {
access_log off;
expires 30d;
try_files $uri @drupal;

Drupal 7 image stylef

location ~* image/generate {
access_log off;
expires 30d;
try_files $uri @drupal;

serve static files directly

location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|swf|flv)$ {
access_log off;
expires 30d;

This rewrites pages to be sent to PHP processing

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

#location = /index.php {

if ($arg_q !~ files/imagecache) {

return 403;


include fastcgi_params;


location ~* ^/(apc|info).php$ {
auth_basic “Restricted Area”;
auth_basic_user_file htpasswd;
include fastcgi_params;

location ~* ^.+.php$ {
return 404;

error_page 404 = @empty;

location @empty {

only a few php files are allowed, this increases the overall server security

location ~* ^/(index|boost_stats|cron|xmlrpc).php$ {
include fastcgi_params;

internal pages are protected with a simple htpasswd

location ~* ^/(install|update|memcached|apc|info).php$ {
auth_basic “Restricted Area”;
auth_basic_user_file htpasswd;
include fastcgi_params;

location ~* ^.+.php$ {
return 404;

And the elusive error in /var/log/virtualmin/mysite.com_error_log:

[error] 7733#0: *2 open() “/home/mysite.com/public_html/admin/config/search/clean-urls/check” failed (2: No such file or directory), client:, server: mysite.com, request: “GET /admin/config/search/clean-urls/check HTTP/1.0”, host: “mysite.com

Again, any help will be super appreciated. I would love to return the favour if you’re able to help me.

You can try to use perusio’s config:

I’ve configured server with that config and it works perfect.
I can post my nginx config.