Moving a CakePHP app

This weekend I had to move some small to medium sized CakePHPs from one server to another.
Basically, I had to switch hosting for them (web space and database).

I haven’t had the time to write a lot lately. But once in a while – even if only for later reference – doesn’t hurt.
So here a small real-life progress report about an app migration the Cake way 🙂

Key goals

  • Moving the app including non-version-controlled files and database
  • Keeping the downtime to a minimum
  • Once migration has started, source must not be modified (database, files).
  • Target should only allow modification after migration is complete and verified.

Requirements

All shells used are part of my Setup plugin.
For the MaintenanceMode to work you need the following snippet added to the end of your bootstrap file:

if (php_sapi_name() !== 'cli') {
    App::uses('MaintenanceLib', 'Setup.Lib');
    $Maintenance = new MaintenanceLib();
    $Maintenance->checkMaintenance();
}

I don’t have to add that the plugin needs to be loaded first, of course 🙂

Initial Steps

The following needs to be done, already, of course:

  • The target server needs to be set up properly, including PHP, MySQL including the proper Apache/environment settings.
  • The target htdocs folder is already prepared using "svn checkout repo-url" or "git checkout repo-url" depending on the type of version control in use. It also has already basic "writable" TMP dirs and other things that can already be applied beforehand.

Since I already did that I just copied over the vhost setup and reloaded Apache:

/etc/init.d/apache2 force-reload

Up until this point the source is still up and running.

Moving on

Now it’s time to put the source into "maintenance mode". Once we move files we don’t want the source to be modified again afterwards and to compromise a clean switch.

I used my MaintenanceMode shell to quickly enable it:

cake Setup.MaintenanceMode activate

Optionally, one can also whitelist the own IP first:

cake Setup.MaintenanceMode whitelist 123.123.123.123

This way you will still be able to navigate normally (remember: read only!), while all others will see the 503 maintenance error message.

Now, no-one can change the source anymore.
Let’s start to backup the DB.

Using my Setup plugin shell "DbDump", I could back-up the whole database in seconds.

cake Setup.DbDump create

The idea is not use DBO access and single queries but the MySQL internal command line tools. This works even with larger DB.
It will store a complete dump file in the APP/files/backup/ folder of the application.
We can copy that over to the same folder on the target server using the CLI command scp:

scp -r -C /path/to/backup/file user@otherserver:/path/to/backup/file

Final steps

After the migration seemed to be complete, I checked if the shells in CLI work using the CurrentConfig shell:

cake Setup.CurrentConfig

This would tell me if the database is found, valid and accessible. Also if cache is setup and running properly.

I could (thanks to my whitelisted IP) also already browse the new site even in maintenance mode.
I also tested upload forms and other potentially broken functionality due to missing/wrong permissions.

Then it’s time that we imported the database content using the DbDump shell:

cake Setup.DbDump restore

It will find this copied file in the backup folder and upon confirmation will import the whole dump into the new DB.

Tip: If the shell on the new server doesn’t work, make sure you got the execution rights (-x) set for the cake file.

You can also make sure your code is up to date by using "git pull", "svn update" etc.
Don’t forget to clear the persistent and model cache after such changes:

cake Setup.Clear cache

You should then be able to browse the website again and see both content and images/filesystem data.

When everything looked fine, I just had to disable the maintenance mode again:

cake Setup.MaintenanceMode deactivate

Some typical problems you might run into

Depending on whether you also have the tmp dirs in version control, you might have to create them (or raise debug level for a sec to automatically trigger that).
It is also a good idea to flush the tmp again before going live again to avoid any accidentally copied files to cause trouble. So basically I raise debug to 2 then (still in maintenance mode) and quickly afterwards set it back to default 0.

Result

With almost zero preparation (OK, I had to get one of the shells working again) I had a total downtime of 4 hours in the middle of the night – which is acceptable. Especially with a proper 503 header for search engines and a small note for visitors.

Note: Ideally, you would also notify users in advance about the maintenance window and its scheduled length.

Vista

One could have reduced the downtime further by packing and the files instead of using rsync and multi-file-transfer.
There are also a lot of server tools and other helpers available that will easy migration for larger applications. But for smaller apps that is usually out of scope or simply unnecessary. Depending on source and target OS that can also be simplified by moving the complete image or something.
Hope this still helps some of you as a guideline or checklist.

Update 2014-12 CakePHP 3.0

For CakePHP 3.x the docs can directly be found in the plugin branch.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.