capistrano : un outil pour déployer vos applications php | php tour nantes 2012
DESCRIPTION
Version HTML accessible à http://gaspaio.github.com/capistranoPHPTour2012 Capistrano est un outil de gestion de tâches optimisé pour le déploiement continu. Bien qu'écrit en Ruby et développé initialement pour les besoins des applications Ruby On Rails, Capistrano est actuellement assez mur pour déployer tout type d'applications Web, dont celles en PHP. Il s'agit peut-être même du meilleur outil disponible pour le faire. Cette présentation propose d'explorer les fonctionnalités qui font de Capistrano un tel outil d'exception pour les déploiements PHP.TRANSCRIPT
Rodolfo RipadoDéveloppeur PHP depuis 6 ans
Membre actif de la communauté Drupal
Son dada : l'Industrialisation/DevOps/Automation
Consultant Drupal chez Alter Way
Qu'est-ce que Capistrano ?Moteur d'exécution de tâches à distance
Connections via SSH
Execution en parallèle
(S')écrit en ruby
Open-source ( )et bien documenté ( )
Mais ... à quoi ça sert, en gros ?
GitHubCapistranorb.com
Déploiement Continu
pour la petite histoire ...
Installer Capistrano : dépendancesSur la machine locale :
Ruby (incl. rubygems)
Client SSH
Sur les machines cible :Server SSH (compatible OpenSSH)
Environnement Linux-like
Installer Capistrano : sur Ubuntu
Capfile
Tâches
Actions
Rôles
Variables
Les concepts de baseFichier de configuration avec la définition destâches et leurs variables de configuration. Appeléaussi la "recipe".
Un groupe d'actions.
Opérations à effectuer sur un ensemble deserveurs.
Un groupe de serveurs.
Définissent les paramètres de connexion, lesaccès VCS, etc.
L'exemple habituel : Hello World!set :user, "vagrant"
desc "My remote hello world task."task :hello_world, :hosts => ["misc.vt", "ddev.vt"] do run "echo 'Hello World'"end
Les variablesPour manipuler des variables :set(), unset(), exists(), ...
# This is ruby, so this :set :user, "vagrant"
# is the same as this :set(:password, "vagrant")
Quelques unes des variables disponibles
Il y en a plein d'autres :
# SSH connection parametersset :user, "vagrant"set :password, "vagrant"
set :ssh_options, { 'port': 8881,}
set :default_environment, { 'ENVVAR' => 'somevalue',}
# Set a gateway thought which to tunnel the connectionsset :gateway, "www.mygateway.org"
2.x Significant Configuration Variables
Les roles et les serversrole(name, *servers, attributes={}, &block)
server(host, *roles, attributes={})
set :user, "vagrant"
#Set 2 roles : web and db serversrole :web, "server1.com", "server2.com"role :web, "server3.com", :master => truerole :db, "server4.com", "server5.com"
#Add a server to both rolesserver "server6.com", :db, :web
desc "My remote hello world task on the master web server only."task :hello_world, :roles => :web, :only => {:master => true} do run "echo 'Hello World'"end
Les actions : exécution de commandesrun(cmd, options={}, &block)
Execute cmd en parallèle sur un ensemble de serveurs
L'alternative run_locally permet d'exécuter une commande
localement
sudo(options={})
Retourne une string pour composer des commandes sudo
run "someCommand someParam", :roles => :webrun "someCommand someParam", :once => true
run "#{sudo :as => 'manuel'} someCommand someParam"
Les actions : transfert de donnéesput(data, path, options={})
get(from, to, options={}, &block)
upload(from, to, options={}, &block)
download(from, to, options={}, &block)
put "file contents", "/etc/someapp/config", :roles => :web
get "/etc/someapp/config", "downloads/someapp_config"
upload "data/someDir", "/var", :recursive => true
download "/var/someDir", "/data/someDir/$CAPISTRANO:HOST$"
Les tâchestask(name, options={}, &block)
before(task_name, *tasks, &block)
after(task_name, *tasks, &block)
desc "Saying hello is easy."task :hello_world, :roles => :web do run "#{sudo} service apache2 stop" run "#{sudo} service apache2 start"end
after :hello_world, :myNameIs
after :hello_world do run "echo 'Goodbye all.'"end
Les namespacesnamespace(name, &block)
# Namespaces allow you to group your tasksnamespace :deploy do task :hello_world, :roles => :web do #some commands endend
# You can reopen a namespace anytime. You can# override previously defined tasks and/or add new ones.namespace :deploy do task :my_name_is, :roles => :web do #some commands endend
Contrôle d'exécutionQue fait-on si une commande échoue ?transaction(&block)
on_rollback(&block)
# Déployer une nouvelle version de l'applicationtask :deploy do transaction do update_code endend
# Placer une nouvelle version du code dans un nouveau répertoiretask :update_code do on_rollback do run "rm rf #{release_path}" end source.checkout(release_path)end
Les composants de nos Recipes :Variables de configuration
Serveurs, rôles, attributs
Actions
Transactions, Tâches, Namespaces
Railsless-deployUne recipe générique de déploiement :
Installation via Rubygems :
Et dans note Capfile :
# Include the alternative deploy recepyrequire 'rubygems'require 'railslessdeploy'
# Custom definitions here
Les tâches par défaut :user@server:~/cap T
[...]
cap deploy # Deploys your project.
cap deploy:cleanup # Clean up old releases.
cap deploy:pending # Displays the commits since your last deploy.
cap deploy:pending:diff # Displays the ̀diff' since your last deploy.
cap deploy:rollback # Rolls back to a previous version and restarts.
cap deploy:rollback:code # Rolls back to the previously deployed version.
cap deploy:setup # Prepares one or more servers for deployment.
cap deploy:symlink # Updates the symlink to the most recently ...
cap deploy:update # Copies your project and updates the symlink.
cap deploy:update_code # Copies your project to the remote servers.
[...]
Comment ça marche ?Sur le(s) serveur(s) cible :
Il faudra définir :La stratégie de déploiment
Le système de contrôle de version utilisé
Et un tas de petites choses ...
[deploy_to][deploy_to]/releases/20080819001122[deploy_to]/releases/...[deploy_to]/shared/...[deploy_to]/current > [deploy_to]/releases/20100819001122
Un Capfile simple :require "rubygems"require "railslessdeploy"
role :web, "webserver"
set :user, "vagrant"
# Required : used for all sorts of default valuesset :application, "MyApplication"
# Requires : The repository from which to checkout the application codeset :repository, "git://github.com/someone/somerepo"
# The VCS identifiersset :scm, :gitset :scm_user, "me"
# The deployment strategy# Possible values : copy, checkout, export, remote_cache, ...set :deploy_via, :remote_cacheset :copy_exclude, "someDir/nonWebData"
# The deployment base directoryset :deploy_to, "/var/www/#{application}"
Démo !
L'interface web : WebistranoApplication RoR, installable via bundler
Disponible sur GitHub :
Comment faire :
Utile mais ...
Très spécifique RoR.
Plus maintenue ?
De nombreux forks "vivants" existent...
https://github.com/peritor/webistrano
Web Application DeploymentUsing Webistrano and Capistrano
Alternatives à WebistranoStrano
Disponible sur
Toujours en Ruby/RoR
Pour des déploiments à partir de Gitub
Plus d'infos :
JenkinsEnvisageable si vous l'utilisez déjà pour l'IC de vos projets
GitHub
http://developwithstyle.com/strano
Extensions à CapistranoCapistrano Multistage
Définition de roles et serveurs par stage
Fait désormais partie de Capistrano.
CapifonyInstallation via Rubygems
Tâches, variables et répertoires conçus
pour déployer des projets Symfony 1 & 2.
Plus d'informations :
user@server:~/cap production deploy
http://capifony.org/
Extensions à CapistranoDrupal
Disponible sur GitHub :
Et autres encore :
https://github.com/gaspaio/Drupal-Capistrano-Deploy
capcake
capistrano_rsync_with_remote_cache
capistrano-deploytags
capistrano-windows-server
Vous n'aimez vraiment pas Ruby ? :-(
Une alternative solide, en Python.
Sur GitHub :
Crée par Rasmus Lerdorf pour les besoins de .
Clone simplifié de Capistrano en PHP.
Aucun commit fait depuis 2 ans.
Et autres encore : , ,
Fabricfrom fabric.api import env, run
def set_hosts(): env.hosts = ['host1', 'host2']
def mytask(): run('ls /var/www')
https://github.com/fabric/fabric
Ploy & WePloyWePay
Control Tier Func Mcollective
Merci !Des questions ?
Retrouver les slides :
Me suivre :
Me joindre :
http://www.slideshare.net/rodolforipado
@gaspaio