PixelfearWeb Development by Jason Varga

Bootstrapping Multiple Site Manager

Tips, Workflow, ExpressionEngine, MSM

I had a hard time finding a good way to bootstrap MSM. There were a number of different suggestions, but because of the different ways you can set up your directory structure, there is no one way to do it.

This is how I set mine up, and it’s working so far.
It’s also more of my way of documenting what I did, so your mileage may (almost definitely will) vary.

My directory structure is a little different than you might see. I’ve adapted this approach from Justin of Objective HTML. It makes maintenance and updating EE much simpler.

- sitename/        # root
  - addons/        # /system/expressionengine/third_party
  - config/        # focuslabs master config bootrap files
  - db/            # db backups
  - html/          # document root
    - assets/      # static files
      - addons/    # /themes/third_party/
      - css/
      - fonts/
      - img/
      - js/
      - min/       # minified files
      - sass/
      - uploads/   # user/cp uploads
    - images/
    - themes/
    - index.php
    - admin.php
  - msm/           # keep clutter out of the root folder
    - site_two/
      - index.php
    - site_three/
      - index.php
  - system/
  - templates/
    - stash/
    - low_variables/
    - default_site/
      - site_two/
      - site_three/

I set the site up as you would using the default bootstrap files.

Prepare for MSM

In preparation for MSM you need to edit some files (Adapted from this gist)


html/index.php, html/admin.php and system/index.php
Just before the ‘end of user configurable settings’ comments.

define('FLC_PATH', $_SERVER['DOCUMENT_ROOT'].'/../config');


system/expressionengine/config/config.php and database.php Replace the bootstrap’s require line with:

require FLC_PATH . '/config.master.php';


config/config.master.php Remove the relative link from the document root. Not sure why this was needed to begin with?


require $_SERVER['DOCUMENT_ROOT'] . '/../config/config.' . ENV . '.php';


require 'config.' . ENV . '.php';

Enter MSM

Once MSM comes into the picture, I created the site in the CP then copy html/index.php to /msm/site_name/index.php.

Since the MSM sites are a level deeper, update the system path and the reference made earlier.

$system_path = '../../system';

define('FLC_PATH', $_SERVER['DOCUMENT_ROOT'].'/../../config');

Also, in the MSM section of the same file, I only uncommented the site_name config variable. The others will be set in the bootstrap.

$assign_to_config['site_name']  = 'site_two';

Not so fast

This is where I started to have trouble.
One site would show errors like not being able to find the correct addons directory. The second site would be trying to serve theme files from its own domain - but since they are all in the default site’s directory, everything was 404ing.

To remedy this, I had to let the other sites know of the default site’s URL.

Modify the bootstrap

I modified config/config.env.php to:

  • include definitions for each of the default site’s names, and added them to the environment declarations.
  • define the document root of the default site

 * MSM Specific Settings
 * The default_site needs to be set so that subsequent sites know how to serve
 * the appropriate URLs. They should be mapped in the Environment Declaration below.
 * The $_SERVER['DOCUMENT_ROOT'] folder *name* should be define below too.
 * eg. httpdocs, public_html, etc.



 * Environment Declaration
 * This switch statement sets our environment. The environment is used primarily
 * in our custom config file setup. It is also used, however, in the front-end
 * index.php file and the back-end admin.php file to set the debug mode

if ( ! defined('ENV'))
    switch ($_SERVER['HTTP_HOST']) {
        case DEFAULT_SITE_PROD :
        case 'sitetwo.com'
            define('ENV', 'prod');
            define('ENV_FULL', 'Production');
            define('ENV_DEBUG', FALSE);
            define('DEFAULT_SITE', DEFAULT_SITE_PROD);

        case 'sitetwo.staging'
            define('ENV', 'stage');
            define('ENV_FULL', 'Staging');
            define('ENV_DEBUG', FALSE);

        case DEFAULT_SITE_DEV :
        case 'sitetwo.dev'
            define('ENV', 'dev');
            define('ENV_FULL', 'Development');
            define('ENV_DEBUG', FALSE);
            define('DEFAULT_SITE', DEFAULT_SITE_DEV);

        default :
            define('ENV', 'local');
            define('ENV_FULL', 'Local');
            define('ENV_DEBUG', TRUE);
            define('DEFAULT_SITE', DEFAULT_SITE_LOCAL);

/* End of file config.env.php */
/* Location: ./config/config.env.php */

I also modified config/config.master.php:

if (isset($config))
 * MSM Settings
 * Determine if we are on the default site or not, so we can set the appropriate
 * URLs.


and in the ‘Dynamic path settings’ section

$base_url    = $protocol . $msm_base_url;
$base_path   = APPPATH . '../../' . DEFAULT_SITE_DOCROOT_FOLDER;

If you are moving the addons directories like I have, you may need to add this to the same section:

$assets_path                       = $base_path . '/assets';
$assets_url                        = $base_url . '/assets';

$env_config['third_party_path']    = $base_path . '/../addons/';
$env_config['path_third_themes']   = $assets_path . '/addons/';
$env_config['url_third_themes']    = $assets_url . '/addons/';


blog comments powered by Disqus