Magento multiple environments using symbolic links

One of Magento’s strengths is its endless configurability, everything in Magento can be configured using .xml files with its database configuration settings in /app/etc/local.xml. While this is great for a single install, for Magento multiple environments this is problematic. Fortunately there’s an easy technique you can use to configure Magento to work easily in multiple environments.

Earlier this year we took on a Magento project for a long-standing client. This was a project that had been developed by a different firm and unfortunately it was in trouble, it was riddled with bugs, bad UI and it was several months late. While we’re not a Magento firm and definitely not Magento experts we were called in to save the project and get it launched.

 At Anecka, we ALWAYS use at least a three tier environment setup: local, stage, production. It helps us easily track changes and allows customers to help in testing and approving features. However we soon discovered that configuring Magento multiple environments would be a challenge as Magento is limited to one database configuration file, /app/etc/local.xml.

So how to make sure “local.xml” was customized to every environment, without having to worry about changing the local.xml file manually on each server?

The answer was pretty shockingly simple: symbolic links.

Using Symbolic Links to separate your environment configuration

Symbolic links are an amazing tool in Linux and Unix based operating systems to create shortcuts (also called “aliases”) to files or folders on your filesystem. Once you create the alias to a file, any changes to the original file will also be reflected in the alias.

For our Magento project, we created three configuration files under the project’s /app/etc folder:

     /app/etc

               -> local.xml.dev

               -> local.xml.stage

               -> local.xml.prod

Each file had separate database settings unique to their own environments. Since we had multiple developers working on the project we made sure that “local.xml.dev” was NOT checked into source control. Each developer had to create their own local.xml.dev file for their own machine. This ensured that we wouldn’t override each others configuration files by accident.

With our environment configuration files in place, first we deleted the existing “local.xml” file on our local development environments. Next, we made sure we were in the /app/etc directory in Terminal and run the following command.

     ln -s local.xml.dev local.xml

Now our /app/etc/ should look like this

magento multiple environments: adding the symbolic link

Magento doesn’t care that “local.xml” is an link. When it reads the file it will use the database options stored in local.xml.dev.

For staging and production, we SSH into the environments and run the “ln -s” command. Substituting “local.xml.dev” with the appropriate “stage” or “prod” file.

There’s one caveat to this technique. You must make sure that your server (and hosting provider) have “Options +FollowSymLinks” turned on in Apache. You can make sure this option is set yourself by adding this to your .htaccess file:

     Options +FollowSymLinks

If you’re in doubt or see an error when you add this to your .htaccess file, contact your hosting company. I haven’t run into a hosting provider that won’t let you use symbolic links if you explain you need to use them.

I think symbolic links are great, using them for configuring Magento multiple environments has some great advantages:

     – It doesn’t require any custom modules

     – You don’t need to change file paths or change Magento’s core code

     – It’s easy to setup and you only need to configure it once

What’s also great about this technique is that it can apply to other PHP projects as well. If you are working on some custom PHP code that loads database or configuration settings through a config file, you can use a symbolic link without modifying the application.

Configuring the Database:

There are two configuration values in the database you’ll need to update in Magento’s core_config_data table every time you restore the database from production. ‘web/secure/base_url’ and ‘web/unsecure/base_url’. It’s pretty easy to do, just save the following in a .sql script and run it after you do an import:

     update core_config_data set value = ‘http://mysite.dev‘ where path = ‘web/unsecure/base_url’;

     update core_config_data set value = ‘https://mysite.dev‘ where path = ‘web/secure/base_url’;

updating core_config_data for magento multiple environments

What we learned: