Published by Mijingo

movie icon image

ExpressionEngine How-to Articles

Topics range from beginner to advanced, but are all born out of real world, professional, day-to-day use of ExpressionEngine. Need more information? Get training videos and ebooks on ExpressionEngine from Mijingo.

Multi-server Setup for EE 2

Now that ExpressionEngine 2 is at a non-beta release, and EllisLab has published a timeline for phasing out new distributions of ExpressionEngine 1, we at Vector Media Group have been choosing EE2 for more and more client projects. One of the first difficulties we ran into when we started using EE2 was the same one we ran into when we started using EE1 many years ago—how to handle our multiple server environments gracefully.

At Vector (like many other development shops) we’re typically concerned with three primary servers: the local machines we use for day-to-day coding, the staging site where we deploy releases for the client to see and build new features, and the production server where the live site actually exists. These machines all typically have completely different URLs and file paths. While one common approach is to keep different config.php files on each server, we’ve found a single dynamic configuration file works better for our workflow.

We’ve also added a lot of settings to config.php that aren’t usually in there. We find that it can be useful to use a file for these instead of having to login to the backend. (Remember that anything set in config.php will override whatever’s been set in the Control Panel.)

Let’s start with five quick notes:

  1. The file I’m editing is the config.php located in system/expressionengine/config1. This corresponds to EE1’s system/config.php file. It’s not the Config.php file located in the “core” folder.
  2. These modifications should be done after going through the actual ExpressionEngine installation. If you’re setting up a sandbox that you copy for each new site, go through the full installation on that before starting these modifications.
  3. If you are accessing your site in a subdirectory some of this may need to be modified (we always favor subdomains over subdirectories for development). The same goes for masked CPs.
  4. In some cases I’ll be using PHP that’s more verbose than strictly necessary. We prioritize human reading clarity, but feel free to adjust as you see fit.
  5. Some of the path options here were originally based on this article about EE1 from Kenn Wilson. We’ve made some major changes and additions, though.
Site-wide Settings

Start by opening up your config.php file; the section we’re concentrating on is in the first 25 or so lines—everything on top of // END EE config items. With one exception that I’ll mention later, you’ll never want to touch anything below that commented line.

I like to begin the file by declaring a few major site-wide settings and temporarily moving out some of the path configuration. Here’s my first section:

$config['app_version']          "202pb01";
$config['install_lock']         "";
$config['license_number']       "";
$config['doc_url']              "";
$config['is_system_on']         "y";
$config['site_label']           'Test Site';
$config['cookie_prefix']        '';
$config['allow_extensions']     "y";
$config['hidden_template_indicator']    "_";
$config['autosave_interval_seconds']    "0"# Disabling entry autosave 

View code as Gist

The first 3 lines are from the default. I’ve removed the next two — cp_url and debug because I’m going to set them later in more relevant sections. I changed the doc url to point to our domain because if clients need help, they’ll typically want to reach out to us instead of reading the docs. The next 3 — is_system_on, site_label, and cookie_prefix are all standard.

We’re now up to our first two major customizations. hidden_template_indicator allows us to changes the character that signifies a hidden template from its default (the period). Many file/FTP browsers default to hiding any file that begins with a period so we change it to the more lovable underscore.

autosave_interval_seconds sets the amount of time, in seconds, between each autosave of channel entry content you have open. Setting it to 0 disables autosave completely (the default is 60 seconds). We’ve unfortunately found autosaving buggy and confusing for our clients so continue to disable it on EE2 builds. This is a decision you should make for yourself.

At this point you’ll want to look down a few lines in your config.php file—past the // END EE config items part—and find $config[‘base_url’] = ‘’. Remove it; we’ll add our own in a second and don’t want our value getting overwritten.

Server Settings

Here’s the next section of our config.php. This section is the key to letting your site work across multiple servers. We start by setting a few variables that won’t be fed directly to EE but will be used as a base to build on further down.:

// Dynamic paths for cross-server compatibility

$protocol                       = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"== "on") ? "https://" "http://";

switch (
case '':
$base_url $protocol '';
$base_url $protocol '';
$base_url $protocol '';
$base_url $protocol 'local.domain';

$system_folder                  "system";
$images_folder                  "images";
$images_path                    $base_path "/" $images_folder;
$images_url                     $base_url "/" $images_folder;

$config['index_page']           "";
$config['base_url']             $base_url "/";
$config['site_url']             $config['base_url'];
$config['cp_url']               $config['base_url'$system_folder "/index.php";
$config['theme_folder_path']    $base_path "/themes/";
$config['theme_folder_url']     $base_url "/themes/";
$config['tmpl_file_basepath']   APPPATH "templates/";

$config['emoticon_path']        $images_url "/smileys/";
$config['captcha_path']         $images_path "/captchas/";
$config['captcha_url']          $images_url "/captchas/";
$config['avatar_path']            $images_path "/avatars/";
$config['avatar_url']            $images_url "/avatars/";
$config['photo_path']            $images_path "/member_photos/";
$config['photo_url']            $images_url "/member_photos/";
$config['sig_img_path']         $images_path "/signature_attachments/";
$config['sig_img_url']          $images_url "/signature_attachments/";
$config['prv_msg_upload_path']  $images_path "/pm_attachments/"

View code as gist

First, we check if the current request is over SSL, set the base url using the current domain name, the base file path using the document root (typically your public_html or httpdocs folder), and then our system and main images folders. EE needs separate URLs and file paths for most image-related directories, so we add the image folder name to our previously set $base_url and $base_path to make our full image path and URL.

Most of the other paths here are self explanatory. We set the main site and control panel URLs, the theme and template information, and then cycle through the various image upload directories—emoticon, captcha, avatar, photo, signature image, and private message. Most need a URL *and* path. Remember that these are our settings; change this as necessary if you organize your folders a different way.

Debugging and Performance Settings

The last part of our customizations are to set some global debugging and performance options:

// Debugging and performance
$config['show_profiler']        'n'# y/n
$config['template_debugging']   'n'# y/n
$config['debug']                '1'# 0: no PHP/SQL errors shown. 1: Errors shown to Super Admins. 2: Errors shown to everyone.
$config['disable_all_tracking''y'# y/n
$config['enable_sql_caching']   'n'# Cache Dynamic Channel Queries?
$config['email_debug']          'n'# y/n 

View code as gist

“Show Profiler” and “Template Debugging” turn on those relevant outputs to logged-in Super Admins browsing the site. We’ve always found it far more convenient to set them inside config.php, where they can be easily turned on and off if the site’s having any trouble. Make sure to use “y” and “n” to toggle these.

The debug mode sets who sees PHP and MySQL errors that pop up on the site. We usually set it to “1” so our Super Admins can be aware of any problems.

“Disable all tracking” turns off items like online user tracking, template hit tracking, and channel entry view tracking. We rarely use these functions and so don’t want the processing and query overhead they add. On a similar note, “enable_sql_caching” corresponds to the Cache Dynamic Channel Queries preference in the control panel. Use this caching wisely; it can have nasty side effects with things like future entries and author_id=“CURRENT_USER”.

And, finally, “email_debug” is just a quick way to toggle the “Enable Email Debugging?” Control Panel preference.


That’s it—the config.php file we use on every ExpressionEngine 2 site we work on. It’s a standard part of our base sandbox install and saves a lot of headaches when developing and moving across servers. With it, no matter what server you’re running the site from, all the important paths will continue to work—and all you’ll have to worry about is copying the database.

1 Note: this path may be changing in EE 2.1 according to a recent EllisLab blog post, however, the key is to find it in the main expressionengine/config directory.

Posted on Jul 13, 2010

Filed Under: How-To, Deployment, ExpressionEngine Development,

Matt Weinberg
About Matt Weinberg

Matt Weinberg is the President of Vector Media Group, a full service web development and marketing agency based in New York City. At Vector he's developed sites ranging from large publishing platforms to full-featured eCommerce stores.