WordPress, Git and Capistrano v3

I’m writing this blog post because I’ve had to add a WordPress site into a Magento site which uses Capistrano 3 as it’s deployment framework. I was trying to work out the best way to set it all up and Googling it resulted in a right load of shit. No disrespect to the authors (many of whom are clearly very talented) but a lot of it was;

  • – Old, out of date
  • – Overly complicated
  • – Using Capistrano v2
  • – Fundamentally disagrees with how I think it should be done

Let me look at that last point. There are a lot of people who think WordPress core should be in your repo. I don’t agree with this at all, I don’t want WordPress or ANY 3rd party plugin in my repo. WordPress is updated all the time, so are the main plugins I’d use.

I don’t want to have to commit constant changes, I will never look at the code changes, I will never roll it back. Why the fuck would I want any of it in my repo? If in the highly unlikely event I want an old version and go to the trouble of trying to roll back a site then I can get the code easily from the archives.

All it will do is get in the way and create noise which increases the likelihood that I will miss any genuine errors from code I am actually changing myself and responsible for – a file accidentally added for example.

This post shows how you can very easily use Capistrano 3 to deploy a WordPress site with ONLY YOUR THEME IN THE REPO

The file paths will be different for your setup of course but it is just not difficult.

The idea is that in the current directory on your live site everything in WordPress – the files in the root, the wp-admin and wp-includes, wp-content/plugins and wp-content/uploads directories are all symlinked to a full WordPress install in the shared directory that is only missing it’s wp-content/themes directory.

The only WordPress stuff in your /current/ directory is wp-content/themes/your-theme – everything else is symlinked.

.gitignore everything except your theme

This assumes your git directory is above your public root by one level. It ignores everything except your theme so you can update WordPress and plugins on your dev site without your repo being polluted.

!/public/
/public/*
!/public/wp-content
/public/wp-content/*
!/public/wp-content/themes
/public/wp-content/themes/*
!public/wp-content/themes/your-theme

Set up your Symlinks

In /var/www/vhosts/www.yoursite.com/site/current/public/ Directory

ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-admin wp-admin
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-includes wp-includes
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/index.php index.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-activate.php wp-activate.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-blog-header.php wp-blog-header.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-comments-post.php wp-comments-post.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-config.php wp-config.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-cron.php wp-cron.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-links-opml.php wp-links-opml.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-load.php wp-load.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-login.php wp-login.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-mail.php wp-mail.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-settings.php wp-settings.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-signup.php wp-signup.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-trackback.php wp-trackback.php
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/xmlrpc.php xmlrpc.php

in /var/www/vhosts/www.yoursite.com/site/current/public/wp-content/ Directory

ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-content/plugins plugins
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-content/uploads uploads
ln -s /var/www/vhosts/www.yoursite.com/site/shared/public/wp-content/index.php index.php

Tell WordPress where to find the wp-content directory

You need to add a config setting in wp-config.php so that WordPress in the shared directory knows where to find the wp-content directory in the current directory;

In /var/www/vhosts/www.yoursite.com/site/shared/public/wp-config.php

define('WP_DEBUG', false);
define('WP_CONTENT_DIR', '/var/www/vhosts/www.yoursite.com/site/current/public/wp-content');

Capistrano deploy.rb file

set :app_symlinks, ["/public/wp-content/plugins", "/public/wp-content/uploads", "/public/wp-admin", "/public/wp-includes"]
set :app_shared_dirs, ["/public/wp-content", "/public/wp-content/plugins", "/public/wp-content/uploads", "/public/wp-content/themes", "/public/wp-admin", "/public/wp-includes"]
set :app_shared_files, ["/public/wp-activate.php", "/public/wp-blog-header.php", "/public/wp-comments-post.php", "/public/wp-config.php", "/public/wp-cron.php", "/public/wp-links-opml.php", "/public/wp-load.php", "/public/wp-login.php", "/public/wp-mail.php", "/public/wp-settings.php", "/public/wp-signup.php", "/public/wp-trackback.php", "/public/xmlrpc.php", "/public/wp-content/index.php", "/public/wp-content/themes/index.php"]

And that’s it. WordPress exists in the shared directory. The core updates fine, user uploads go to the uploads directory in shared. None of it is in your repo and Capistrano handles the deploy beautifully by making sure WordPress itself isn’t touched and the symlinks are all set up again in the new release.