Nous allons décrire ici le déploiement d’une application Symfony 2 sur une serveur distant avec NGinx et MySQL. Le code est contrôlé en source par Git, avec des repos managés par GitLab.

Pour simplifier, toutes les machines tournent en Débian. Le tutorial s’adapte facilement pour des OS différents. De même, il est facile de remplacer le GitLab par tout autre serveur Git, comme GitHub.

Nous nous plaçons ici dans l’exemple d’un déploiement simple sur un unique domaine.

On a donc le schéma suivant

capifony-architectureNotons que deux ou les trois instances peuvent être sur la même machine physique.

Installation du Poste de déploiement

Installation de Capifony

L’installation de Capifony sur le poste de déploiement nécessite Ruby. Ensuite Capifony s’installe sous forme de Gem:

sudo apt-get install ruby1.9.1-full  
sudo update-alternatives --config ruby  
sudo gem install capifony sudo gem install capistrano_rsync_with_remote_cache  

Initialisation de Capifony

Une fois l’installation terminée, l’initialisation est très simple:

cd path/to/your/project capifony .  

A ce moment là, Capifony va créer deux fichiers:

  • Capfile à la racine du projet
  • deploy.rb dans app/config

Paramétrage

Maintenant, il faut éditer le fichier deploy.rb avec les paramètre de notre déploiement:

 set :application, "nom de l'application"
 set :domain,      "monappli.mondomaine.com"
 set :deploy_to,   "/chemin de déploiement"
 set :app_path,    "app"
 set :use_sudo,    false
 # The WebServer User
 set :user,        "UserWeb"
 # Different temporary directory for when you deploy on the same machine: uncomment
 # set :copy_dir,        "~/tmp"
 # set :remote_copy_dir, "/tmp"
 # You might want to change this to other branch e.g. "master"
 set :branch,      "release"
 set :repository,  "ssh://git@mongit.mondomaine.com:<Port SSH du serveur Git>/pathtoproject/monproject.git"
 set :scm,         :git
 ssh_options[:forward_agent] = true
 ssh_options[:port]          = "Port SSH du serveur Web"
 ssh_options[:config]        = false
 set :deploy_via,    :remote_cache
 set :model_manager, "doctrine"                   # Or: `propel`
 role :web,        domain                         # Your HTTP server, Apache/etc
 role :app,        domain, :primary => true       # This may be the same as your `Web` server
 set  :keep_releases,  3
 # Be more verbose by uncommenting the following line
 logger.level = Logger::MAX_LEVEL
 set :use_composer, true
 # after first deployment you might want to change this to false. Setting to true will always install vendors each time
 set :update_vendors,  true
 set :dump_assetic_assets, true
 # Copy Shared paramters.yml to deployment set :shared_files,          ["app/config/parameters.yml"]
 # update database schema
 # you can use migrate or anything else before
 "symfony:cache:warmup", "symfony:doctrine:schema:update"

Clés SSH

Créer une clé SSH pour l’utilisateur de déploiement (cf, par exemple http://prendreuncafe.com/blog/post/2005/08/29/262-installer-sa-cle-ssh-sur-un-serveur-distant ).

Une fois cette clé créée, il faut déployer la clé publique sur les serveurs. Ci-dessous une procédure pour GitLab et le serveur Web.

Ajouter la clé publique dans GitLab

GitLabAddSSHKeyDans l’URL /profile/keys, choisir Add SHH Key et coller la clé publique ( cat ~/.ssh/id_rsa.pub ).

Ajouter la clé publique pour l’utilisateur Web

Plusieurs solutions sont possibles.

Ne pas oublier également d’autoriser SSH pour cet utilisateur en éditant le fichier /etc/ssh/sshd_config, et en ajoutant l’utilisateur pour la balise  “AllowUsers“. Puis faire

sudo service ssh restart  

Si on a le mot de passe de l’utilisateur Web, alors la commande suivante fait le travail:

ssh-copy-id -i $HOME/.ssh/id_rsa.pub UserWeb@monappli.mondomaine.com  

Sinon, il faut ajouter cette clé publique pour UserWeb au fichier ~/.ssh/authorized_keys sur le serveur Web. Créer ce fichier si nécessaire avec l’utilisateur web comme propriétaire. Faire attention aux droits du fichier (600).

Attention, si comme moi vous protégez les file systems de vos utilisateurs Web en écriture, il faut d’abord déprotéger, créer/modifier le fichier, puis reprotéger:

sudo chattr -i /home directory du UserWeb .... sudo chattr +i /home directory du UserWeb  

Voilà, une fois toutes ces étapes terminée, vous devez pouvoir faire un SSH depuis votre machine de déploiement vers  celles qui hébergent GitLab et le serveur Web, avec les utilisateurs respectifs.

Initialiser le déploiement

Une fois les connexions SSH paramétrées et Capifony installé, il suffit de lancer, à la racine du projet:

cap deploy:setup  

Cette commande va créer le système de fichier sur le serveur Web, à la racine de “/chemin de déploiement” (cf. deploy.rb).

Les recommandations de Symfony sont de ne pas source contrôler le fichier* parameters.yml. Il faut donc ensuite créer un fichier *parameters.yml avec les élément de connexion à la base dans le répertoire “/chemin de déploiement/shared/app/config“. Ce fichier sera utilisé et déployé (cf. deploy.rb).

Déployer

Le déploiement se fait très simplement, depuis la racine du projet:

ap deploy  

Si on souhaite revenir en arrière:

cap deploy:rollback  

cf. http://capifony.org/

Paramétrer NGinx

Avec les éléments utilisés plus haut, voici un exemple simple de fichier pour Nginx:

upstream phpfcgimonappli {  
     server 127.0.0.1:<Port>;
    # server unix:/var/run/php5-fpm.sock; #for PHP-FPM running on UNIX socket
 }
 server {
         listen *:80;
         server_name monappli.mondomaine.com;
          root   /Chemin de déploiement/current/web;
   # strip app.php/ prefix if it is present
     rewrite ^/app\.php/?(.*)$ /$1 permanent;
       location / {
         index app.php;
         try_files $uri @rewriteapp;
     }
       location @rewriteapp {
         rewrite ^(.*)$ /app.php/$1 last;
     }
       # pass the PHP scripts to FastCGI server from upstream phpfcgi
     location ~ ^/(app|app_dev|config)\.php(/|$) {
         fastcgi_pass phpfcgimonappli;
         fastcgi_split_path_info ^(.+\.php)(/.*)$;
          include /etc/nginx/fastcgi_params;
         fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
         fastcgi_param  HTTPS off;
     }
 }

Problèmes

Composer API limit at GitHub

Lors d’un “composer update” , on peut atteindre l’API limit de GitHub. Pour résoudre ce problème il suffit de créer un “Personnal Access Token” dans son compte GitHub:

Dans GitHub, menu: Account Settings -> Applications -> Personal Access Tokens (cf. https://help.github.com/articles/creating-an-access-token-for-command-line-use )

Ensuite modifier le fichier composer.json:

...
"config" : {
        ....,
         "github-oauth":{
         "github.com":"votre token"
      }
     },
..

Pour aller plus loin

Faire des notifications dans HipChat

Installer le Gem hipchat:

gem install hipchat  

Ajouter ensuite au script de déploiement:

require 'hipchat/capistrano'  
set :hipchat_token, "Votre Token"  
set :hipchat_room_name, "votre room"  
set :hipchat_announce, false # notify users?  

Sources

http://konradpodgorski.com/blog/284/how-to-deploy-symfony-2-0-project-to-production-server/
http://capifony.org/
https://github.com/everzet/capifony
http://symfony.com/doc/current/cookbook/deployment/tools.html
http://tech.joro.fr/retour-dexperience-capifony/