Versioni di Capifony

Capifony, come sapete, è ormai lo standard de facto per il deploy con Symfony. È un bel progetto, mantenuto attivamente, che quindi spesso viene aggiornato. Dal canto suo, anche Capistrano (a cui Capifony si appoggia), riceve vari aggiornamenti. E qui purtroppo arrivano i problemi: più di una volta mi è capitato di trovarmi con un Capifony non funzionante, a causa di stretti requisiti (un po’ troppo stretti, a mio parere) sulle dipendenze.
Prendiamo come esempio le ultime versioni al momento disponibili: aggiornando oggi le gemme di ruby, ho avuto questa brutta sorpresa:

/usr/local/lib/site_ruby/1.8/rubygems/dependency.rb:247:in `to_specs': Could not find capistrano (<= 2.14.1, >= 2.13.5) amongst [capifony-2.2.7, capistrano-2.14.2, capistrano-maintenance-0.0.2, colored-1.2, highline-1.6.15, inifile-2.0.2, net-scp-1.1.0, net-sftp-2.1.1, net-ssh-2.6.5, net-ssh-gateway-1.2.0] (Gem::LoadError)

La versione più recente di Capifony richiede Capistrano non più nuovo di 2.14.1, ma il Capistrano più recente è 2.14.2.
Ecco come ho risolto (i comandi sono stati dati su Ubuntu Linux 12.10, your mileage may vary)

sudo gem uninstall capistrano -v 2.14.2
sudo gem install capistrano -v 2.14.1

L’ultimo comando serve solo se in precedenza è stata fatta una pulizia delle gemme, tramite sudo gem clean. Purtroppo anche questa va fatta, perché spesso le versioni diverse sono in conflitto tra di loro.

velocizzare il deploy con capifony

Come probabilmente saprete, Capifony (per chi non lo conoscesse, è lo standard de facto per gestire i deploy su Symfony2) purtroppo ha un’impostazione predefinita che reinstalla tutti i vendor a ogni deploy. Questo vuol dire che ogni volta che facciamo un deploy dobbiamo aspettare che il server di produzione (o comunque il server su cui stiamo eseguendo il deploy stesso) scarichi da github tutte le librerie necessarie. Ogni volta, anche se molto probabilmente le librerie dei vendor non sono state modificate dal deploy precedente. In realtà, quando anche fossero state modificate, per esempio per un aggiornamento di Symfony, non sarebbe più efficiente scaricare solo le modifiche, piuttosto che tutto quanto? Dopotutto, è esattamente ciò che facciamo sulle nostre macchine di sviluppo.
Ecco una possibile soluzione, da riportare nel proprio file di configurazione deploy.rb.

# app/config/deploy.rb
# [...]
set :vendors_mode, "install"
set :update_vendors, true
before "symfony:vendors:install", "symfony:copy_vendors"
 
namespace :symfony do
  desc "Copy vendors from previous release"
  task :copy_vendors, :except => { :no_release => true } do
    pretty_print "--> Copying vendors from previous release"
    run "cp -a #{previous_release}/vendor/* #{latest_release}/vendor/"
    puts_ok
  end
end

Aggiornamento: il codice, ampliato e migliorato, è stato pubblicato come ricetta sul sito di Capifony.

deploy semplificato con Symfony2

Come probabilmente saprete, l’attuale standard de facto per il deploy con Symfony2 è Capifony.
Può capitare però, di avere esigenze di deploy molto più semplici, oppure di non voler usare ruby, o ancora non avere la possibilità di configurare il server remoto per utilizzarlo.
Perché allora non riciclare la semplice strategia utilizzata dal caro vecchio symfony 1? Ecco qui un semplicissimo script shell, da inserire per esempio in bin/deploy.sh:

#!/bin/bash
 
# adattare queste tre variabili
user='nome_utente'
server='nome_server'
dir='nome_sito'
 
/usr/bin/rsync -azC --force --delete --progress --exclude-from=app/config/rsync_exclude.txt -e ssh . $user@$server:$dir
 
/usr/bin/ssh $user@$server 'cd '$dir'; /usr/bin/php app/console cache:clear --env=prod --no-debug'

Basterà copiare e adattare un file rsync_exclude.txt da un vecchio progetto symfony (o usare quello della sandbox) nella cartella app/config e sostituire ai vari nome_utente, nome_server e nome_sito i valori adeguati.
Ovviamente, si possono personalizzare i comandi da eseguire dopo aver eseguito rsync, basta aggiungerli all’interno degli apici singoli, dopo quello di pulizia della cache, separati da puntoevirgola.