Symfony

DÉPLOYER UNE APPLICATION SYMFONY SUR LINUX

D

Dimanche 1 octobre 2017

Mis à jour le lundi 2 octobre 2017

Déployer une application Symfony sur Linux

Ce tutoriel va vous expliquer comment déployer une application Symfony sur un serveur Linux.
Pour cela, vous aurez besoin au préalable d'avoir installé PHP, MySQL, Nginx, Composer et éventuellement PhpMyAdmin sur votre serveur. Leurs installations ne sont pas expliqués ici.

Afficher les erreurs au premier déploiement

Si c'est la première fois que vous déployez votre application, je vous conseille d'afficher les erreurs même en production pour éviter d'avoir une erreur 500 pas très précise. Pour cela, dans le fichier /web/app.php, mettez le deuxième argument de cette fonction à true :
$kernel = new AppKernel('prod', true);
Une fois que vous avez déployé l'application une première fois, et qu'elle fonctionne correctement, n'oubliez pas de remettre ce second argument à false pour éviter d'afficher des informations sensibles au public.

Utiliser un serveur web Nginx

Nous allons utiliser Nginx comme serveur web. Nous aurions très bien pu utiliser Apache, mais Nginx étant de plus en plus utilisé et très simple, c'est lui que j'ai choisi.
Positionnez-vous dans le dossier /etc/nginx/conf.d/ et créer le fichier monsite.fr.conf :
cd /etc/nginx/conf.d
sudo vi monsite.fr.conf
Puis insérez-y ceci :
server {
    server_name domain.tld www.domain.tld;
    root /var/www/project/web;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /app.php$is_args$args;
    }
    # DEV
    # This rule should only be placed on your development environment
    # In production, don't include this and don't deploy app_dev.php or config.php
    location ~ ^/(app_dev|config)\.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }
    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
       # When you are using symlinks to link the document root to the
       # current version of your application, you should pass the real
       # application path instead of the path to the symlink to PHP
       # FPM.
       # Otherwise, PHP's OPcache may not properly detect changes to
       # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
       # for more information).
       fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
       fastcgi_param DOCUMENT_ROOT $realpath_root;
       # Prevents URIs that include the front controller. This will 404:
       # http://domain.tld/app.php/some-path
       # Remove the internal directive to allow URIs like this
       internal;
   }

   # return 404 for all other php files not matching the front controller
   # this prevents access to other php files you don't want to be accessible.
   location ~ \.php$ {
     return 404;
   }

   error_log /var/log/nginx/project_error.log;
   access_log /var/log/nginx/project_access.log;
}
Bien entendu, votre fichier peut s'appeler autrement que monsite.fr.conf, l'important, c'est qu'il finisse par .conf.
Remplacez :
server_name domain.tld www.domain.tld;
avec le nom de domaine de votre site, comme ceci :
server_name monsite.fr www.monsite.fr;

Remplacez :
root /var/www/project/web;
par le chemin qui pointe vers le dossier web de votre projet Symfony :
root /home/david/www/monsite.fr/web;

Pour finir, et seulement si vous avez installé PHP7 sur votre machine, remplacez la ligne :
fastcgi_pass unix:/var/run/php5-fpm.sock;
par :
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;


Donner les bons droits à votre projet

N'oubliez pas de donner les bons droits aux dossiers de votre projet Symfony, sinon, vous aurez des erreurs 404, des erreurs 500 ou des pages blanches et vous ne comprendrez pas pourquoi :
cd /home/david/www/
sudo chown -R www-data monsite.fr
chmod 777 -R *


Créer la base de données

N'oubliez pas de créer la base de données :
cd /home/david/www/monsite.fr
php bin/console doctrine:database:create
Et de créer sa structure :
php bin/console doctrine:schema:update --dump-sql
php bin/console doctrine:schema:update --force
Et éventuellement de charger vos fixtures si vous en avez :
php bin/console doctrine:fixtures:load


Charger les dépendances Composer

Sans vos dépendances, votre application ne peut rien faire, n'oubliez pas de les charger :
cd /home/david/www/monsite.fr
composer install


Vérifier la configuration du serveur

Symfony possède un petit fichier qui vérifie la configuration du serveur, autant en profiter.
Dans le fichier /web/config.php, commentez ce bloc :
if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
    '127.0.0.1',
    '::1',
))) {
    header('HTTP/1.0 403 Forbidden');
    exit('This script is only accessible from localhost.');
}
Puis, allez sur monsite.fr/config.php, vous devriez obtenir un écran similaire à celui-ci :

Vous y trouvez les Major problems qu'il faut corriger et les Recommendations que vous pouvez suivre.
Si vous obtenez un écran blanc à la place, c'est qu'une erreur se cache quelque part. Dans ce cas, consultez les logs pour avoir plus d'informations sur la provenance de l'erreur :
tail -10 /var/logs/nginx/project_error.log
Vous pourriez obtenir des erreurs de ce type :
2017/10/01 22:39:44 [error] 32629#0: *129 FastCGI sent in stderr: "PHP message: PHP Warning:  require_once(/home/david/www/monsite.fr/web/./SymfonyRequirements.php): failed to open stream: No such file or directory in /home/david/www/monsite.fr/web/config.php on line 25
PHP message: PHP Fatal error:  require_once(): Failed opening required '/home/david/www/monsite.fr/web/./SymfonyRequirements.php' (include_path='.:/usr/share/php') in /home/david/www/monsite.fr/web/config.php on line 25" while reading response header from upstream, client: 82.111.145.66, server: monsite.fr, request: "GET /config.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.0-fpm.sock:", host: "42.88.159.26"
J'ai remarqué que la commande Composer install ne faisait pas toujours les choses correctement. Dans mon cas, si je consultais la ligne 25 du fichier /web/config.php, elle ressemblait à ceci :
require_once dirname(__FILE__).'/../var/SymfonyRequirements.php';
Alors qu'il faut la modifier comme ceci :
require_once dirname(__FILE__).'/../var/SymfonyRequirements.php';

Une fois que vous avez fini de vérifier la configuration du serveur, n'oubliez pas de décommenter le bloc de code qu'on a commenté pour que le public n'ai pas accès à cette page :
if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
    '127.0.0.1',
    '::1',
))) {
    header('HTTP/1.0 403 Forbidden');
    exit('This script is only accessible from localhost.');
}


Mettre à jour l'application Symfony avec Git

Si vous mettez à jour votre application avec Git, n'oubliez pas de vider le cache, soit à la manière de Symfony qui le recréer immédiatement après :
cd /home/david/www/monsite.fr
php bin/console cache:clear --no-warmup --env=prod
Soit à la manière brute :
sudo rm -R var/cache/*
Et éventuellement de supprimer les fichiers de logs :
sudo rm -R var/logs/*



Une erreur ? une question ? une critique ? une faute ? un conseil ? ou tout simplement un merci ?

Lâche ton commentaire