AD7six.com

Production setup revisited

24 August, 2007

Show comments

A while ago I wrote about how to have a [production setup on a shared host][Production style on a shared host], an insightful comment from CraZyLeGs pointed out that the same idea could be extended (on either a shared of dedicated machine) to allow multiple applications to be installed on the same server, and have multiple parallel versions of cake installed as well. For some time, and in reality probably since before the time of writing the initial post, I have been doing exactly that and as it's come up in discussion a few times here's an explanation of exactly how to have multiple applications, with multiple cake installations and mix and match them however you like. First I'll explain where files go, and then show the index.php file that allows you to make it work.

The principle§

If you haven't read it already, have a browse of [the previous post][Prevent Robots from accessing an action] as the basic idea is the same. I will make one assumption: The document root for each domain on the server is under one common root - the name of the folders isn't important, but the convention I will follow is that the root folder for a domain should be named the same as the associated app folder - in the below example they are named after the domain to which they belong. Therefore for a server running a few domains the server should look a litte like this:

  • var
    • www
      • www.blog.com
      • www.business.com
      • www.fun.com
      • www.experiments.tv

The web accessible files and folders§

Ordinarily everything for each domain would be under these folders, which is good for separating the files for each domain but not so good for maintainability of multiple installs. Within each domain to have multiple installs only the web accessible files (the original contents of the webroot) will go in the domain folders like so:

  • var
    • www
      • www.blog.com
        • css
        • js
        • .htaccess
        • index.php (*)
      • www.business.com
        • css
        • js
        • .htaccess
        • index.php (*)
      • www.fun.com
        • css
        • js
        • .htaccess
        • index.php (*)
      • www.experiments.tv
        • css
        • js
        • .htaccess
        • index.php (*)

The index files marked with a star are, as we shall see later, in most cases identical - which is great should you find you need to edit your generic index file as you can edit any one of them and just copy over the other index.php files to reap the benefit on all domains.

The private files and folders§

With the web-accessible file and folder locations clear, we now create a folder to house all those files that should not be web accessible namely your app files, cake files and any vendors. Have a look at the following folder structure:

  • var
    • www
      • _website_files
        • apps
          • 1_1
          • 1_2
          • 1_2_branch
          • www.blog.com
          • www.business.com
          • www.fun.com
          • www.experiments.tv
        • cakes
          • 1_1
          • 1_2
          • 1_2_branch
          • 1_2_rev1234_patched
        • vendors
      • 1_1
      • 1_2
      • 1_2_branch
      • www.blog.com
      • www.business.com
      • www.fun.com
      • www.experiments.tv

I have added three new 'domains' which will only be accessible when developing locally and are used to double check that the cake core file are present and correct.

Within a none-web-accessible folder are three folders, apps, cakes and vendors. The latter you may feel is misplaced but I'll explain that in a second.

Apps folder contents§

Under apps are all the 'app' folders. I find it a good practice to have a template app folder to copy hence there are three app folders (named 1_1, 1_2 and 1_2_branch) which aswell as allowing localhost testing are there for that purpose. Any file or folder which is present for a standard development install can be deleted, therefore, using one domain as an example, the folders under an app should look like this:

  • var
    • www
      • _website_files
        • apps
          • 1_1
          • 1_2
          • 1_2_branch
          • www.blog.com
            • config
            • controllers
            • locale
            • models
            • plugins
            • tests
            • tmp
            • vendors
            • views
          • www.business.com
          • www.fun.com
          • www.experiments.tv
        • cakes
          • 1_1
          • 1_2
          • 1_2_branch
          • 1_2_rev1234_patched
        • vendors
      • 1_1
      • 1_2
      • 1_2_branch
      • www.blog.com
      • www.business.com
      • www.fun.com
      • www.experiments.tv

Cakes folder contents§

The best way to get your cakephp source is to check out via svn. The urls to do so are pretty much the first thing mentioned on Cake's trac site. Therefore, for example if you run svn co https://svn.cakephp.org/repo/branch/cake/1.2.x.x /var/www/_website_files/cakes/1_2_branch you will get or update to the following:

  • var
    • www
      • _website_files
        • apps
          • 1_1
            • 1_2
            • 1_2_branch
            • www.blog.com
            • www.business.com
            • www.fun.com
            • www.experiments.tv
          • cakes
            • 1_1
            • 1_2
            • 1_2_branch
              • app
              • cake
              • docs
              • vendors
              • .htaccess
              • index.php
            • 1_2_rev1234_patched
          • vendors
        • 1_1
        • 1_2
        • 1_2_branch
        • www.blog.com
        • www.business.com
        • www.fun.com
        • www.experiments.tv

It is best not to modify the cake folder contents at all hence the index.php and .htaccess files (etc.) will be present but aren't used or referred to.

Vendors folder contents§

There are typically many vendor packages that are common across several domains, a good example will be whichever javascript library is your preference. The folder named vendors under _website_files will not be directly queried by cake, but by putting all of these common vendor files and folders in a single place, this gives you the option to either copy (boo) or symlink (yay) libraries into place for either a version of cake (by copying/symlinking to that version of cake's vendor folder) or a specific domain (by copying/symlinking to that domain's vendor folder or directly to the webroot as appropriate).

Incidentally, for super brownie points, you can make (for example) /var/www/_website_files/apps/1_2_branch a symlink to /var/www/_website_files/cakes/1_2_branch/app, and in that way, should anything new appear under the app folder, when you update your cake source your 'template' 1.2 branch app folder will also be updated.

Editing the index file§

If you have followed the instructions this far, you are one file edit away from a multiple-application and multiple-version-of-cake working setup. There is a single constant which can change, and that is the name of the folder containing the domains version of cake to use. If you use the same cake version and revision for all of your domains (note that the 1.1 index.php file is slightly different, the changes to make to the constant definitions is however the same. Also note that it is not possible to 'upgrade' by only changing the constant to point a 1.1 application at 1.2 cake source) this means the index.php files is the same for all domains. By using relative file paths for these definitions it is possible to have exactly the same index file for all domains irrespective of the file locations so long as the generic directory structure is maintained. The complete file is below, only the ROOT, APP_DIR and CAKE_CORE_INCLUDE_PATH definitions have been changed:

To summarize what that does: ROOT is defined as the apps folder, APP_DIR is defined to be the name of the containing folder (the name of the domain), and the CAKE_CORE_INCLUDE_PATH is defined to find the appropriate cake version.

Real life, local development and deployment§

I use the same setup on both my local development machine (quick and dirty access to a development domain via http:/localhost/www.domain.com) and the server. Stable apps run of the 1_2 install and only active projects runs of the branch for testing out what's coming around the corner. If after updating the branch source files something goes amiss, by accessing the http://localhost/1_2_branch/test.php and running the core tests it can quickly be determined if it's a new project-specific problem or a blip in the matrix as cake continues it's march on to greatness. A decision can then be made to revert, create a domain specific cake version either temporarily or permanently, or open up those app files to find and fix whichever naughty line of code is causing a problem.

If you have a few domains running of the same cake source, but one of them needs a different revision to take advantage of new developments or circumvent a temporary bug, by editing the CAKE_CORE_INCLUDE_PATH constant in that domain's index to point to say, 1_2_branch or 1_2_rev1234_patched (while some work is done identifying or fixing a problem), you can temporarily or permanently use a different version of cake only for that domain without affecting your other installs at all. You are then free to switch back at any time, and you could even make it logic driven such that you can see your live site using a different version of cake than the public (although I don't see much of a benefit of that :D ).

By using rsync (fantastic tool) or something similar an application folder, a version of cake, or the whole lot can by moved/updated from a development environment to the test/live server with ease.

Wrapping Up§

The setup described here allows you to have multiple domains/applications installed on the same server with multiple versions of cake available in parallel without having duplicate files. This flexibility is possible with only minor changes to folder setups and with only slight changes to your index.php file. Comments welcome.

Bake on!