Drupal deployment met Capistrano

Capistrano?

Capistrano is a remote server automation and deployment tool written in Ruby.

Zoals gezegd is het een tool waarmee de uitrol van een site naar 'een omgeving' kan worden gedaan. Naast het fijne uitrollen, geeft het ook de mogelijkheid om een uitrol ongedaan te maken (bijv. bij fouten in upload of testen) en om eigen taken uit te laten voeren op een remote server. Met dat laatste kun je je voorstellen dat je na een uitrol bijv. de site offline wilt zetten, updates uitvoeren, Features terugzetten, site cache legen en vervolgens de site weer online zetten. Dit kan natuurlijk vanuit de Drupal UI of vanuit de shell met Drush (mits je SSH toegang hebt) maar Capistrano kan dat ook regelen.

Het werkt als volgt: 

  • De code staat in een online repository, zoals Github of Bitbucket. Bij Capistrano 3.x wordt momenteel alleen Git ondersteund, maar men ontwikkeld aan de plugins voor SVN, Mercury, etc. 
  • Bij het uitrollen kiest Capistrano de aangewezen branch (instelbaar per omgeving) en doet zijn ding. Op de server wordt in een /releases/ map een verse checkout van de code geplaatst. Gedeelde mappen (zoals https://backend.web-beest.nl/sites/default/files) worden in een /shared/ map geplaatst en gelinked. 
  • Bob's your uncle :)

Installatie

Om Capistrano te installeren heb je Ruby nodig. Als dat draait op je omgeving is het een kwestie van de gem installeren:

gem install capistrano

De Ruby gem wordt geïnstalleerd en is klaar voor gebruik.

Een project starten

Vervolgens vertellen we Capistrano dat we een nieuw project willen. Dat gebeurt als volgt:

cap install

Dit commando genereert de bestanden en mappen die nodig zijn voor het uitrollen naar meerdere omgevingen

/
| config
| |- deploy
|     |- production.rb
|     |- staging.rb
| | - deploy.rb
| lib
| |- capistrano
|     |- tasks
| Capfile

De map /deploy bevat het algemene bestand (deploy.rb) met configuratie van het project en taken die moeten worden uitgevoerd en een map met omgevingen (production.rb / staging.rb). Hier kun je alle omgevingen definiëren die nodig zijn, zoals een test, acceptatie en productie-omgeving. In de /lib/capistrano/tasks map kunnen project-specifieke taken worden geplaatst. De Capfile tenslotte bevat alles om Capistrano te kunnen initialiseren.

Configuratie

Allereerst moet Capistrano weten waar hij moet kijken. Dat wordt ingesteld in de deploy.rb

Hierin staat waar de repository staat, welke branch gebruikt moet worden (deze kan verplaatst worden naar de omgeving-configuratie) en wat de taken zijn die moeten worden uitgevoerd. Voor een Drupal site heb ik deze configuratie voor de acceptatie omgeving:

set :repo_url, 'git@bitbucket.org:[username]/[repository-name].git'

# Default branch is :master
set :branch, 'accept'

# Default value for linked_dirs is []
set :linked_dirs, ['sites/default/files']

Daarnaast heb ik nog wat custom tasks die moeten worden uitgevoerd na deployment:

namespace :deploy do
  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      # Your restart mechanism here, for example:
      # execute :touch, release_path.join('tmp/restart.txt')
    end
  end

  after :publishing, :restart

  after :restart, :clear_cache do
    invoke 'drush:site_offline'
    invoke 'drush:cache_clear'
    invoke 'drush:backupdb'
    invoke 'drush:updatedb'
    invoke 'drush:features_revert_all'
    invoke 'drush:site_online'
  end
end

Deze zorgen er voor dat met elke deployment de site offline wordt gezet, de cache geleegd, een backup van de database, database update, features reverten en daarna de site weer online.

De omgeving-configuratie is vrij eenvoudig:

server 'example.com', user: 'username', roles: %w{web app}
set :deploy_to, '/var/www/project-dir/www'

Het is het makkelijkste als de gebruiker via SSH public-key access heeft tot de server. Hierover kun je hier meer lezen. Als dat is ingesteld kan er gedeployed worden.

Deployment

Het uitrollen gaat kinderlijk eenvoudig:

cap staging deploy

En dat is het. Je ziet in de terminal alle opgegeven commando's voorbij komen die nodig zijn voor het uitrollen naar de gekozen omgeving. Lean back and get some coffee :)

Update :)

Op het moment dat ik van development machine wisselde merkte ik dat dit nog niet helemaal compleet was. Voor het gebruik van de Drush commando's moet een gem en rake file worden gemaakt. 

De gem komt in /Library/Ruby/Gems/2.0.0/gems/capistrano-[v]/lib/capistrano/drush.rb

require 'capistrano/framework'
load File.expand_path('../tasks/drush.rake', __FILE__)

De rake-file in /Library/Ruby/Gems/2.0.0/gems/capistrano-[v]/lib/capistrano/tasks/drush.rake

namespace :drush do
  desc "Cache clear"
  task :cache_clear do
    on roles(:web) do
      execute "drush -r #{current_path} cc all"
    end
  end
end

back_blog