Drupal and Wordpress on Apache and Nginx

By devin, 6 March, 2014

My two favourite CMSes and my two favourite web servers. Here are four config files for the same website. Let's assume we have a user devin with two directories in his public_html folder:

/home/devin/public_html/drupal
/home/devin/public_html/wordpress

And then has already created the following logs folders (nginx and Apache have a habit of crashing when you try to specify a non-existent logging directory):

/home/devin/logs/apache/drupal
/home/devin/logs/apache/wordpress
/home/devin/logs/nginx/drupal
/home/devin/logs/nginx/wordpress

And that you've got the following four domains:

WA.devinhoward.ca
DA.devinhoward.ca
WN.devinhoward.ca
DN.devinhoward.ca

Then here are the configuration files that should work to host Drupal or Wordpress on Nginx or Apache:

Wordpress on Apache:

<VirtualHost *:80>
  ServerName WA.devinhoward.ca
  DocumentRoot /home/devin/public_html/wordpress
  ErrorLog /home/devin/logs/apache/wordpress/error.log
  CustomLog /home/devin/logs/apache/wordpress/access.log combined env=!justtesting

  <Directory /home/devin/public_html/wordpress>
    suPHP_Engine on
    AddHandler application/x-httpd-suphp .php .php3 .php4 .php5
    suPHP_AddHandler application/x-httpd-suphp

    AllowOverride All

    <Limit GET POST OPTIONS PROPFIND>
      Order allow,deny
      Allow from all
    </Limit>
    <Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>
      Order deny,allow
      Deny from all
    </Limit>
  </Directory>
</VirtualHost>

Drupal on Apache:

<VirtualHost *:80>
  ServerName DA.devinhoward.ca
  DocumentRoot /home/devin/public_html/drupal
  ErrorLog /home/devin/logs/apache/drupal/error.log
  CustomLog /home/devin/logs/apache/drupal/access.log combined env=!justtesting

  <Directory /home/devin/public_html/drupal>
    suPHP_Engine on
    AddHandler application/x-httpd-suphp .php .php3 .php4 .php5
    suPHP_AddHandler application/x-httpd-suphp

    AllowOverride All

    <Limit GET POST OPTIONS PROPFIND>
      Order allow,deny
      Allow from all
    </Limit>
    <Limit PUT DELETE PATCH PROPPATCH MKCOL COPY MOVE LOCK UNLOCK>
      Order deny,allow
      Deny from all
    </Limit>
  </Directory>
</VirtualHost>

Wordpress on Nginx:

server {
        listen   80;
    
        ## Your website name goes here.
        server_name WN.devinhoward.ca;

        ## Your only path reference.
        root /home/devin/public_html/wordpress;
        access_log /home/devin/logs/nginx/wordpress/access.log;
        error_log /home/devin/logs/nginx/wordpress/error.log error;

        ## This should be in your http block and if it is, it's not needed here.
        index index.php index.html index.htm;

        location / {
                try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        error_page 404 /404.html;

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
                #fastcgi_pass 127.0.0.1:9000;
                # With php5-fpm:
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

Drupal on Nginx:

server {
        server_name DN.devinhoward.ca;
        root /home/devin/public_html/drupal;
        access_log /home/devin/logs/apache/drupal/access.log;
        error_log /home/devin/logs/apache/drupal/error.log error;

        # Enable compression, this will help by serving Gzip versions of files.
        gzip_static on;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        # Very rarely should these ever be accessed outside of your lan
        location ~* \.(txt|log)$ {
                deny all;
        }

        location ~ \..*/.*\.php$ {
                return 403;
        }

        # No no for private
        location ~ ^/sites/.*/private/ {
                return 403;
        }

        # Block access to "hidden" files and directories whose names begin with a
        # period. This includes directories used by version control systems such
        # as Subversion or Git to store control files.
        location ~ (^|/)\. {
                return 403;
        }

        location / {
                # This is cool because no php is touched for static content
                try_files $uri @rewrite;
        }

        location @rewrite {
                # You have 2 options here
                # For D7 and above:
                # Clean URLs are handled in drupal_environment_initialize().
                rewrite ^ /index.php;
                # For Drupal 6 and bwlow:
                # Some modules enforce no slash (/) at the end of the URL
                # Else this rewrite block wouldn't be needed (GlobalRedirect)
                #rewrite ^/(.*)$ /index.php?q=$1;
        }

        location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_intercept_errors on;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
        }

        # Fighting with Styles? This little gem is amazing.
        # This is for D6
        #location ~ ^/sites/.*/files/imagecache/ {
        # This is for D7 and D8
        location ~ ^/sites/.*/files/styles/ {
                try_files $uri @rewrite;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

Note: the nginx stuff was plagiarized and adapted, here are my sources:

 

Plain text

  • No HTML tags allowed.
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.