Deploy Laravel Avec Capistrano 3

Le déploiement d’une application est souvent compliqué. Entre les releases foireuses, les migrations ratées et les downtimes qui n’en finissent pas…Bref vous voyez le genre.

Capistrano permet de résoudre tout ça et sans écrire un putain de script bash de merde qui prendra des dizaines de lignes, devra être exécuté directement sur le serveur etc.

Avec Capistrano vous allez pouvoir:

Installer Capistrano

Capistrano étant fait en ruby, vous comprendrez bien qu’il faut ruby d’installer! Je ne vais pas décrire la procédure pour installer ruby ici.

Pour installer Capistrano 3:

# gem install capistrano

Une fois la gem installée il faut mettre en place la config sur notre projet laravel.

Pour cela placez-vous à la racine de votre projet et faite un:

# cap install

Cette commande génère plusieurs fichiers pour nous. Notamment un dossier/fichier config/deploy.rb qui contient notre future configuration.

Préparer le terrain

Pour commencer nous allons définir deux serveurs de déploiements.

Un serveur de préproduction et un de production. Vous allez donc devoir mettre en place une connexion ssh via clés privée/publique sur ces deux serveurs.

Dans le dossier config/deploy/ vous trouverez deux fichiers. Il représente vos stage qui vous permettrons de deploy votre application de differentes façons.

Créer un fichier preprod.rb dans config/deploy/:

set :stage, :preprod

# Définit un serveur pour le déploiement préprod
# Vous pouvez en définir plusieurs si vous souhaitez 
# déployer sur plusieurs serveurs en meme temps
server 'example.com', user: 'deploy', roles: %w{web app}

Nos tasks

Maintenant que nous avons défini notre serveur nous allons configurer les différentes tasks.

Nous allons maintenant éditer le fichier config/deploy.rb.

Il se présente comme ceci:

# config valid only for Capistrano 3.1
lock '3.1.0'
 
set :application, "TestApp"  # Le nom de votre app
 
set :scm, :git
# L'url git de votre projet
set :repo_url, "git@github.com:test/test.git"

set :use_sudo, false # On est pas fou quand même
set :ssh_options, {
   :forward_agent => true
}

# On demande au serveur de garder 5 releases
# Pour une plus grande flexibilité lors des rollbacks
set :keep_releases, 5

# Lorsqu'on utilise le namespace deploy
namespace :deploy do
 
    after :finishing, "deploy:cleanup"
 
end

On a déjà un bon squelette, on va définir des tasks pour notre projet laravel:

On va donc définir des tasks pour tout ceci. Nous allons créer un namespace pour laravel et composer.

Je vais placer tout le code suivant dans le fichier config/deploy.rb, après la définition du ssh forward_agent.

Nous allons définir la task lançant le composer install.

namespace :composer do
	
    desc "Run composer install in release_path."
    task :install do
    	on roles(:all) do
        	within release_path do
            	execute "composer", "install", "-o"
            end
        end
    end
end

Le code ruby est plutôt clair et parlant. Je ne pense pas avoir besoin de l’expliquer ligne par ligne.

Création des tasks laravel:

namespace :laravel do
	
    desc "Setup Laravel folder permissions."
    task :permissions do
    	on roles(:all) do
			within release_path do
            	execute "chmod", "u+x", "artisan"
                execute "chmod", "-R", "w", "app/storage"
            end
        end
    end
    
    desc "Run Laravel Artisan migrate."
    task :migrate do
    	on roles(:all) do
        	wihtin release_path do
	        	execute "php", "artisan", "migrate"
        	end
        end
    end
    
    desc "Optimize Laravel Class Loader"
    task :optimize do
    	on roles(:all) do
        	within release_path do
            	execute "php", "artisan", "clear-compiled"
                execute "php", "artisan", "optimize"
            end
        end
    end
end

Vos tasks sont maintenant créés mais vous devez définir où les placer dans le processus.

Dans le namespace :deploy:

namespace :deploy do
	
	after :publishing, "composer:install"
    after :publishing, "laravel:permissions"
    after :publishing, "laravel:migrate"
    after :publishing, "laravel:optimize"
end

Il ne vous reste plus qu’a tester tout ceci!

# cap preprod deploy

Voila vous pouvez maintenant créer vos tasks et déployer vos releases!

Prochaine étape le rollback!

ps: Si vous avez des améliorations/suggestions n’hésitez pas à me contacter!