Skip to main content

Serving Sites from the Web Subdirectory

Learn how to create and use a nested docroot to serve your Pantheon site.

The docroot is the directory from which your site is served. On Pantheon, this defaults to the root directory of the site's codebase (code). Specifying web_docroot: true in your pantheon.yml file or in the pantheon.upstream.yml file in your upstream allows you to serve site files from the web subdirectory of your site's code repository on all Pantheon environments (for example code/web).


Using Pantheon's one-click Dashboard updates feature depends on a correctly set the web_docroot property.

  • Composer-managed sites, including Integrated Composer sites, require you to set the web_docroot property in the pantheon.upstream.yml file.
  • Sites that use a Custom Upstream require you to set the web_docroot property in the pantheon.upstream.yml file.
  • Sites that do not use Composer and do not use a Custom Upstream should not set the web_docroot property, if one-click Dashboard updates are desired.

Advantages and Use Cases

While URLs are limited to the web docroot, PHP is not. Using a nested docroot allows you to put PHP files for use in your web application one level above the web docroot so they are accessible via PHP but not from the web.

This is especially useful for third party dependencies, such as those installed and managed via Composer.

Disable One-click Updates

If you wish to stop using one-click Dashboard updates on a particular site, and instead intend to update your site with Composer, switch the site's upstream to an empty repository using Terminus:

terminus site:upstream:set <site> empty-7

Enable Nested Docroot

Enable nested docroot by adjusting your site's pantheon.yml file. Below we recommend using Git, but you can also use SFTP to set up your site.

  1. Set the Dev environment's connection mode to Git from within the Site Dashboard or via Terminus:

    terminus connection:set <site>.<env> git
  2. Clone the site's codebase, if you haven't already.

  3. Create a pantheon.yml file if it doesn't already exist.

  4. Add the line web_docroot: true to the top level of the YAML file, typically after api_version. For example:

      api_version: 1
      web_docroot: true
  5. Add, commit, and push the pantheon.yml file using Git.

  6. Follow the instructions in either Create a New Site with a Nested Docroot or Convert an Existing Site to Use a Nested Docroot below.

Create a New Site

Your site should use a Custom Upstream with a pantheon.upstream.yml file that enables nested docroot and the CMS code is in a web subdirectory. If not, create a new site using the steps below.

Convert an Existing Site

You'll need to move the CMS code into the web subdirectory, either manually or by using one of the commands below.

The command below uses find to select all files at the document root, including "dot" files, but skips all directories and all files explicitly excluded in the egrep section. It then lists the specific core directories to move into the nested docroot. This may or may not produce the correct results, depending on what files you or your team has added. You can add files to be excluded in the list after egrep, and use the -n flag for git mv to perform a dry run first.

Clone the site's codebase, then execute the following from the project root directory:

mkdir web
git mv -k $(find . -maxdepth 1 -type f | egrep -v 'pantheon.yml|.gitignore||pantheon.upstream.yml') includes/ misc/ modules/ profiles/ scripts/ sites/ themes/ index.php web

These commands create the web subdirectory, then use Git to move required files into the nested docroot.

Your directory structure should look like this afterwards:

├── web
  ├── includes
  ├── index.php
  ├── misc
  ├── modules
  ├── profiles
  ├── scripts
  ├── sites
      └── all
          ├── modules
          └── themes
          └── default
          └── settings.php
  └── themes

After using one of these commands, verify the new file locations with git status before committing and pushing.

FAQ and Troubleshooting

Quicksilver Script Location

If you are using a Quicksilver platform hook with the type webphp, make sure that the path to the script is relative to the web docroot and not the project root.

For example, if your pantheon.yml has a script location definition of private/scripts/my_quicksilver_script.php, the file needs to be located at web/private/scripts/my_quicksilver_script.php. This is because webphp scripts are run with Nginx, which is serving from the nested docroot.

Can I specify a subdirectory other than web?

The directory name is not configurable, but you can create a symlink from some other directory to web.