Automating TYPO3 Deployment with Capistrano
In my previous article I covered the basics of Capistrano and deploying simple PHP based applications. This time I’ll go into a bit more detail about how we use Capistrano to deploy TYPO3 based sites specifically.
Some Background
I’ll be taking you through a cut-down version of our set up, which should give you a starting point for your own projects.
The picture to the right shows the root directory of a typical TYPO3 project, you can ignore most of the directories, you mainly just need to know that src is the root directory of the website. This is where the TYPO3 files go. The other important directory to remember about for now is config.
Let’s recap the directory structure I talked about in the last article and expand on how we’re using it here. In the appname directory we create a shared directory and a releases directory. When we cap deploy, Capistrano will put a copy of our repository into the releases folder in a date and timestamped folder. It will then create a symbolic link from it to the current directory. The shared directory is for the files that must remain from release to release, this holds directories like fileadmin, typo3temp and uploads. During the deploy step we will create symbolic links to these directories in the current release. We also use this location for some configuration and the Apache log files.
our project structure
You’ll notice that typo3conf is conspicuously missing. That’s the one directory which is actually held in our VCS and is what changes from release to release, i.e. what we’re deploying. We create an extension which contains all the html and css which make up the templates as well as the TYPOScript configuration so it’s not spread out across multiple places. We version all extensions we use in a project to ensure we always have a complete copy of all files for any given client. However, we don’t typically version the TYPO3 source. This is kept on the server in a separate location and then symbolically linked into the current release by the Capistrano recipe on each deploy.
in the source directory
We all run our own individual copies of the site on our computers so in the config directory we have two localconf files—these are both versioned. The development one is used as a kind of template-cum-starting-point for each developer to create their own copy of localconf.php (which is thus not versioned) and the production one which contains the appropriate settings for the production servers.
Similarly the db_settings.php is not versioned, whilst the example one is. They contain just the database connection variables from localconf.php. This is separated out so that we can each have our own database settings and so that the production database details aren’t stored in the VCS. A db_settings.php is created in the shared directory on the production server which is referenced in the localconf.production.php.
the config directory
Here’s what a typical localconf file contains.
When we add a new extension we manually adjust the extList and add any specific extension configuration variables in localconf.production.php so that we stay in full control of what’s installed during the development process.
Setup
Firstly we need to tell Capistrano a few things:
In the config directory, you’ll find the deploy.rb file where we configure Capistrano to do our bidding.
:application is the name for your project and will be used in the :deploy_to setting. The important thing here is that the :deploy_to determines where the files are put on the remote servers. So in our case ultimately our Apache webserver config file for the site would have the DocumentRoot set to: /var/apps/appname/current/src
:repository is the location of your project in your version control system. It needs to be accessible to the servers you’re deploying to. In our case we use GitHub as our preferred version control system. If you’re using a different VCS don’t worry, Capistrano supports quite a few different ones. You can even choose to not use a VCS, but seriously, if you’re not you should be!
The next block of options are specific to Git. You’ll need to set these according to your VCS and your preferences. As are the ssh options. We each have a user on the remote servers that are named the same as our workstation accounts so Capistrano uses that as the username it connects with (though you can specify a specific account username and password if you wish) and we use ssh keys to authenticate. Finally the roles specify which server/s do what. In most cases you’ll be running everything on one box so just set them all to the same hostname.
The rest of the script
Here’s the rest of the deploy.rb file which contains the tasks to deploy the basic site.
The first task we override is the deploy:setup task which you saw last time, the only addition is the creation of the TYPO3 “local” folders in the shared directory (actually we do more such as creating the db_settings.php file in the shared directory but I left it out for brevity).
The standard Capistrano deploy task does what we want which is to simply get the latest copy from the repository as specified earlier and link up the various directories, once this is done we then ask Capistrano to run the typo3:fix_perms task we have written to set the correct permissions on the newly created release structure so that our admin group and the webserver user have the correct access permissions for serving the site and the next deployment.
Capistrano is set up for deploying Rails applications by default with the deploy:set_permissions, deploy:restart and deploy:migrate tasks. We don’t need those things to happen so we simply override them to do nothing.
Getting Fancy
I’ve skipped a number of things we do to try and simplify the recipe down to its barest forms to keep this article short and demonstrate the concepts but once you have the basics set up, you can start to use Capistrano to automate things like setting up Apache and its config files for a new site, restarting Apache, updating the database and the list goes on. You’ll almost never need to log onto the servers remotely again. Just to give you a little taste I’ve included a bonus recipe for you below, absolutely free! :)
Free Bonus Recipe1
Stick this code in your deploy.rb to enable and disable the Install Tool by typing cap typo3:eit and cap typo3:dit
namespace :typo3 do
task :eit do
eit=<<-EIT
Enabled:
EIT
put eit, "#{current_path}/src/typo3conf/ENABLE_INSTALL_TOOL"
end
task :dit do
run "rm #{current_path}/src/typo3conf/ENABLE_INSTALL_TOOL"
end
end
1 This only works in the recent versions of TYPO3, it doesn’t work for the earlier versions where you had to edit the TYPO3 source directly