Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Deploying Drupal Like a Pro - Part 1: File Structure

Parent Feed: 

This article is part of the Deploying Drupal Like a Pro series.

Application Files and Content Files

If you have just started playing with Drupal you will have something like this in your site's directory structure:

sites/default/files

sites/default/files/tmp

sites/default/files/private

Do you recognize those paths? If so, you are either using symbolic links, or you have not correctly deployed your Drupal application. And that goes for all size and kind of projects.

To start with, you must know that every web application's files can be split into two basic categories: application and contents.

Application files:

  • They are usually backed by a source control, so if something happens to them in your production environment (not a good thing...) you are fully insured.
  • They do not change frequently, and when they do, it happens in a controlled manner.
  • They do not change as a result of usage of the application. These are "design time" files.
  • Size and disk usage of these files can be easily controlled and forecasted, and is usually so small that size is not a concern.

Content files:

  • They are created as a result of the interaction of users with your application.
  • Size requirements not easy to control and forecast. It can be from the few megabytes to the terabytes scale.
  • Frequently changed, or their changes and growth cannot be forecasted as part of the application's design.
  • Some of these files are meant to be publicly accesible while others not.

Sample Setup

There are many ways to properly deal with that scenario and this is one of them.

Drop your application files (source code) to the system disk, on a path such as

c:\inetpub\wwwroot\www.mywebsite.com\

Drop you content files on a separate data disk, on a path such as

d:\contents?\www.mywebsite.com\

Now create a symbolic link so that the contents directory is mapped to \sites\default

mklink -j "c:\inetpub\wwwroot\www.mywebsite.com\sites\default\files\" "d:\contents?\www.mywebsite.com\files"

?What we have just done is telling the operating system that whenever an application tries to acces the sites\default\files path they should actually access the contents folder you deployed on the data disk.

What about the settings.php file? It does not qualify as application or contents file: it's a hybrid between deployment settings and application configuration. If you have horizontally scaled your application you may have different settings.php files in every server, and probably this file will not be backed in your code repository.

What are the benefits of this setup?

  • Cloud SSD storage is x4 times more expensive than regular disks, so you are saving 3/4 of the storage bill (application file size is usually neglibile when compared to contents). Careful with this statement, you may identify that different parts of your contents have different speed requierements, and you could split them between SSD's and regular disks by also using symlinks.
  • You have an effective separation between contents and application files, so it is now easier to have different backup policies between them. You might indeed not even have regular backups of you application files because they are already backed up by the repository, so you only need to take care of backing up your contents.
  • You have eliminated the risk of a collapsing system disk due to unforcasted contents size growth. Of course you are monitoring disk usage, but the rush is less if you know that what is filling up is not the same disk that is holding the operating system and web server.
  • You have greater flexibilty and reduced downtime when performing server scaling on single server setups. Just dettach the contents drive from the old server and attach it to the new one. This takes less than 15 seconds on the Rackspace cloud.
  • On cloud deployments, storage blobs and content delivery networks are tightly integrated, so your contents file system can get out-of-the-box CDN capabilities.
  • On cloud deployments frontend machines can be volatile. Your application files can be part of the system disk image, and the contents can be shared accross frontend servers.

We haven't talked yet about security (permissions) and folder visibility.

On a regular setup, Drupal will need to modify files inside the files folder, so you need to grant the fast-cgi process identity full permissions on the "files" folder. This account is usually the IUSR account. PHP should not be able to modify the settings.php or application files.

Folder visibility is also very important here. If you left everything as is, you will be exposing to the whole world the private and temporary directories. These directories are meant to be private, and not visible to the outside world. To solve this issue you need to create a web.config inside the sites/default/files directory with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <location path="temp">
          <system.webServer>
                        <security>
                                <authorization>
                                  <deny users="*"/>
                          </authorization>
                        </security>
          </system.webServer>
  </location>
  <location path="private">
          <system.webServer>
                        <security>
                                <authorization>
                                  <deny users="*"/>
                          </authorization>
                        </security>
          </system.webServer>
  </location>
</configuration>

NOTICE: We just placed the web.config file inside a IUSR writable directory. Either move the file a level up (and change it's inners) or only give the IUSR specific permissions to the temp, private and public directories.

Although this is not the recommened deployment for all situations, you have an insight in what are the considerations you need to make and what tools you have at your hands to properly deploy your application's files.

Deploying using the PHP deployment tool

The PHP deployment tool automatically takes care of all the previously described setup. In the global.config define a default application root and a default contents root:

<Config_Global>
  <DefaultContentsRoot>D:\_Contents</DefaultContentsRoot>
  <DefaultApplicationRoot>D:\_Webs</DefaultApplicationRoot>
  <!--...-->
</Config_Global>

Now give your application an alias in the application.config.xml file, define any required symlinks and optionaly override the application and content files folder:

<?xml version="1.0" encoding="utf-8"?>
<Config_Application>
  <Alias>www.mywebsite.com</Alias>
  <ApplicationRoot></ApplicationRoot>
  <ContentsRoot></ContentsRoot>
  <Symlinks>
    <Config_SymlinkMapping>
          <ContentsRelativePath>/</ContentsRelativePath>
          <WebRelativePath>/sites/default/</WebRelativePath>
        </Config_SymlinkMapping>
  </Symlinks>
</Config_Application>

Use the Site/DeployStructure command to:

  • Create the application files folder if it does not exist.
  • Create the contents file folder if it does not exist.
  • Give the IUSR account the correct permissions on both folders.
  • Create the symlinks that will link you contents to you application files folder structure.

This article is part of the Deploying Drupal Like a Pro series.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web