450 lines
13 KiB
Markdown
450 lines
13 KiB
Markdown
---
|
|
categories: web CMS
|
|
title: Howto Drupal
|
|
---
|
|
|
|
* Documentation : <https://www.drupal.org/documentation>
|
|
|
|
[Drupal](https://www.drupal.org/) est un CMS libre écrit en PHP.
|
|
|
|
## Pré-requis
|
|
|
|
* Un serveur web (Apache/Nginx/...)
|
|
* Une base de données MySQL/Mariadb ou PostgreSQL
|
|
* PHP 8.1 (Drupal 10), PHP 7.4/8.0/8.1 (Drupal 9), PHP 7.3/7.4 (Drupal 7 et 8)
|
|
* Pour Drush : /home en `exec` et `mariadb-client` installé
|
|
|
|
Pour plus de détails, voir [la documentation de Drupal](https://www.drupal.org/docs/user_guide/en/install-requirements.html) notamment :
|
|
|
|
* [pré-requis pour Drupal 7](https://www.drupal.org/docs/7/system-requirements/)
|
|
* [pré-requis pour Drupal 8 et versions suivantes](https://www.drupal.org/docs/system-requirements/)
|
|
|
|
### Apache
|
|
|
|
Drupal est livré avec des fichiers `.htaccess` qui utilisent un nombre varié de directives.
|
|
La configuration Apache doit donc contenir au minimum :
|
|
|
|
~~~{.apache}
|
|
AllowOverride AuthConfig Limit FileInfo Indexes Options=Indexes,MultiViews,ExecCGI,Includes
|
|
~~~
|
|
|
|
Le `DocumentRoot` d'Apache doit correspondre au dossier `web` qui se trouve à la racine du dossier du projet
|
|
|
|
### Nginx
|
|
|
|
Un exemple complet de vhost Nginx pour Drupal est accessible sur [dans la documentation de Nginx](https://www.nginx.com/resources/wiki/start/topics/recipes/drupal/)
|
|
|
|
### PHP
|
|
|
|
Certains ajustements sont nécessaires
|
|
|
|
#### Web ( FPM / libapache2-mod-php )
|
|
|
|
*TODO?*
|
|
|
|
#### CLI
|
|
|
|
C'est surtout pour `composer` et `drush` qui nécessitent :
|
|
|
|
* (composer) Le non blocage de la fonction `putenv()`
|
|
* (composer) Autoriser l'ouverture d'url (allow_url_fopen)
|
|
* (drush) Aucune fonction désactivée (ie: disable_functions vide) sinon drush refuse de fonctionner....
|
|
|
|
## Installation
|
|
|
|
Il existe [plusieurs méthodes pour installer Drupal](https://www.drupal.org/docs/getting-started/installing-drupal/get-the-code).
|
|
La méthode conseillée est d'utiliser [composer](HowtoPHP#composer)
|
|
|
|
Ainsi, une installation par défaut va se faire avec la commande suivante va créer une nouvelle installation et récupérer toutes les dépendances avec composer.
|
|
|
|
~~~
|
|
$ mkdir www/
|
|
$ composer create-project drupal/recommended-project www
|
|
$ cd www/
|
|
$ composer show | grep ^drupal
|
|
drupal/core 10.2.1 Drupal is an open source content management platform powering millions of websites and applications.
|
|
drupal/core-composer-scaffold 10.2.1 A flexible Composer project scaffold builder.
|
|
drupal/core-project-message 10.2.1 Adds a message after Composer installation.
|
|
drupal/core-recommended 10.2.1 Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.
|
|
~~~
|
|
|
|
On peut en suite, aller directement à l'addresse du site (DocumentRoot qui pointe vers `/home/foo/www/web/`) pour obtenir l'interface de finalisation du site.
|
|
On aura notamment besoin d'avoir des identifiants pour accéder à une base de données.
|
|
|
|
On peut également finaliser l'installation avec Drush (cf plus bas) :
|
|
|
|
~~~
|
|
$ cd $ROOT
|
|
$ drush site:install standard
|
|
|
|
Database name [drupal]:
|
|
> foo
|
|
|
|
Database driver [mysql]:
|
|
>
|
|
|
|
Database username [drupal]:
|
|
> foo
|
|
|
|
Database password [drupal]:
|
|
> PASSWORD
|
|
|
|
Database host [127.0.0.1]:
|
|
>
|
|
|
|
Database port [3306]:
|
|
>
|
|
|
|
You are about to:
|
|
* DROP all tables in your 'foo' database.
|
|
|
|
Do you want to continue? (yes/no) [yes]:
|
|
>
|
|
|
|
[notice] Starting Drupal installation. This takes a while.
|
|
[notice] Performed install task: install_select_language
|
|
[notice] Performed install task: install_select_profile
|
|
[notice] Performed install task: install_load_profile
|
|
[notice] Performed install task: install_verify_requirements
|
|
[notice] Performed install task: install_settings_form
|
|
[notice] Performed install task: install_verify_database_ready
|
|
[notice] Performed install task: install_base_system
|
|
[notice] Performed install task: install_bootstrap_full
|
|
[notice] Performed install task: install_profile_modules
|
|
[notice] Performed install task: install_profile_themes
|
|
[notice] Performed install task: install_install_profile
|
|
[notice] Performed install task: install_configure_form
|
|
[notice] Performed install task: install_finished
|
|
[success] Installation complete. User name: admin User password: PASSWORD
|
|
|
|
$ cd /web/sites/default/
|
|
|
|
$ drush sql-connect
|
|
mysql --user=foo --password='PASSWORD' --database=foo --host=127.0.0.1 --port=3306 -A
|
|
|
|
$ drush status
|
|
Drupal version : 10.2.1
|
|
Site URI : http://default
|
|
DB driver : mysql
|
|
DB hostname : 127.0.0.1
|
|
[…]
|
|
~~~
|
|
|
|
|
|
### Cron
|
|
|
|
~~~
|
|
$ crontab -l
|
|
|
|
42 * * * * php /home/foo/www/vendor/bin/drush cron --root /home/foo/www/ 2&>1 >/dev/null
|
|
~~~
|
|
|
|
## drush
|
|
|
|
[Drush](https://www.drush.org/) est un outil en ligne de commande pour installer/gérer des sites Drupal.
|
|
|
|
Liste des commandes disponibles par défaut : <https://www.drush.org/12.x/commands/all/>
|
|
|
|
### Installation
|
|
|
|
Pour installer la dernière version :
|
|
|
|
~~~
|
|
$ cd $ROOT
|
|
$ composer require drush/drush
|
|
$ composer require symfony/http-kernel
|
|
$ composer show drush/drush | grep ^version
|
|
versions : * 12.4.3
|
|
|
|
$ php ./vendor/bin/drush version
|
|
Drush version : 12.4.3.0
|
|
~~~
|
|
|
|
Pour installer une ancienne version :
|
|
|
|
~~~
|
|
$ composer global require drush/drush:8.4.8
|
|
|
|
$ php ./.composer/vendor/bin/drush version
|
|
Drush Version : 8.4.8
|
|
~~~
|
|
|
|
ou
|
|
|
|
~~~
|
|
$ composer require drush/drush:8.4.8
|
|
|
|
$ php ./vendor/bin/drush version
|
|
Drush Version : 8.4.8
|
|
~~~
|
|
|
|
|
|
### Utilisation
|
|
|
|
Au sein d'un site Drupal, on peut vérifier/collecter différentes informations :
|
|
|
|
~~~
|
|
$ cd $ROOT
|
|
|
|
$ drush sql-connect
|
|
|
|
$ drush status
|
|
Drupal version : 10.2.1
|
|
Site URI : http://default
|
|
PHP binary : /usr/bin/php8.2
|
|
PHP config : /etc/php/8.2/cli/php.ini
|
|
PHP OS : Linux
|
|
PHP version : 8.2.7
|
|
Drush script : /home/foo/www/vendor/bin/drush
|
|
Drush version : 12.4.3.0
|
|
Drush temp : /tmp
|
|
Drush configs : /home/foo/www/vendor/drush/drush/drush.yml
|
|
Drupal root : /home/foo/www/web
|
|
Site path : sites/default
|
|
~~~
|
|
|
|
### Alias
|
|
|
|
Fichiers dans le répertoire `~/.drush/` :
|
|
|
|
* `local.drushrc.php` : configuration générale
|
|
* `FOO.alias.drushrc.php` : contexte spécifique pour la commande `drush @FOO`
|
|
* `BAR.alias.drushrc.php` : contexte spécifique pour la commande `drush @BAR`
|
|
|
|
~~~
|
|
$ cat ~/.drush/FOO.alias.drushrc.php
|
|
|
|
$aliases['FOO'] = array (
|
|
'uri' => 'foo.example.com',
|
|
'root' => '/home/foo/www/web',
|
|
...
|
|
~~~
|
|
|
|
## Configuration
|
|
|
|
### Configuration derrière un reverse-proxy
|
|
|
|
Dans la configuration de Drupal, des directives sont à activer pour la prise en compte des headers HTTP X-Forwarded-For).
|
|
|
|
~~~php
|
|
$settings['reverse_proxy'] = TRUE;
|
|
|
|
$settings['reverse_proxy_addresses'] = ['192.0.2.1'];
|
|
~~~
|
|
|
|
Pour le HTTPS (signalé via X-Forwarded-Proto), il y a déjà des directives de configuration pour prendre ce réglage en compte.
|
|
Elles ressemblent à :
|
|
|
|
~~~php
|
|
/**
|
|
* If external request was HTTPS but internal request is HTTP, set $_SERVER['HTTPS'] so Drupal detects the right scheme.
|
|
*/
|
|
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && isset($_SERVER['REQUEST_SCHEME'])) {
|
|
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' && $_SERVER["REQUEST_SCHEME"] == 'http') {
|
|
$_SERVER['HTTPS'] = 'on';
|
|
}
|
|
}
|
|
~~~
|
|
|
|
## Multisite
|
|
|
|
<https://www.drupal.org/docs/getting-started/multisite-drupal/>
|
|
|
|
Il est possible de créer différents sites Drupal à partir d'une même installation.
|
|
Cela permet d'avoir une seule fois le code source de Drupal et donc une gestion simplifiée.
|
|
Cela peut avoir des inconvénients si besoin de gérer finement des ensembles de personnalisations différentes par site.
|
|
|
|
On suppose qu'une installation de base de Drupal a été faite, et Drush également installé.
|
|
|
|
> *Note* : il est nécessaire d'avoir la commande `mysql` installée, donc `mariadb-client` doit être installé là où tourne PHP
|
|
|
|
Pour l'installation d'un premier site distinct du `default` créé à l'installation de Drupal :
|
|
|
|
~~~
|
|
$ cd $ROOT
|
|
|
|
$ drush site:install standard --sites-subdir=test1
|
|
|
|
Database name [drupal]:
|
|
> foo_test1
|
|
|
|
Database driver [mysql]:
|
|
>
|
|
|
|
Database username [drupal]:
|
|
> foo
|
|
|
|
Database password [drupal]:
|
|
> PASSWORD
|
|
|
|
Database host [127.0.0.1]:
|
|
>
|
|
|
|
Database port [3306]:
|
|
>
|
|
|
|
You are about to:
|
|
* Create a sites/test1/settings.php file
|
|
* Create a sites/sites.php file
|
|
* DROP all tables in your 'foo_test1' database.
|
|
|
|
Do you want to continue? (yes/no) [yes]:
|
|
>
|
|
|
|
[notice] Starting Drupal installation. This takes a while.
|
|
[notice] Performed install task: install_select_language
|
|
[notice] Performed install task: install_select_profile
|
|
[notice] Performed install task: install_load_profile
|
|
[notice] Performed install task: install_verify_requirements
|
|
[notice] Performed install task: install_settings_form
|
|
[notice] Performed install task: install_verify_database_ready
|
|
[notice] Performed install task: install_base_system
|
|
[notice] Performed install task: install_bootstrap_full
|
|
[notice] Performed install task: install_profile_modules
|
|
[notice] Performed install task: install_profile_themes
|
|
[notice] Performed install task: install_install_profile
|
|
[notice] Performed install task: install_configure_form
|
|
[notice] Performed install task: install_finished
|
|
[success] Installation complete. User name: admin User password: PASSWORD
|
|
~~~
|
|
|
|
Cela crée donc un fichier `web/sites/sites.php` pour gérer plusieurs sites.
|
|
|
|
Et les sites sont « crées » dans des répertoires `web/sites/SITE/`
|
|
contenant principalement un fichier `settings.php` contenant notamment les paramètres de base de données du site.
|
|
|
|
~~~
|
|
$ cd web/sites/test1/
|
|
|
|
$ drush sql-connect
|
|
mysql --user=foo --password='PASSWORD' --database=foo_test1 --host=127.0.0.1 --port=3306 -A
|
|
|
|
$ drush status
|
|
Drupal version : 10.2.1
|
|
Site URI : http://test1
|
|
DB driver : mysql
|
|
DB hostname : 127.0.0.1
|
|
[…]
|
|
~~~
|
|
|
|
Il suffit ensuite de créer la configuration Apache ou Nginx pour les FQDN souhaités avec un DocumentRoot dans `web/`
|
|
et de bien configurer le fichier `web/sites/sites.php` par exemple :
|
|
|
|
~~~
|
|
$sites['test1.example.com'] = 'test1';
|
|
$sites['test2.example.com'] = 'test2';
|
|
~~~
|
|
|
|
On peut utiliser la commande Drush sur un site en particulier via l'argument `-l` :
|
|
|
|
~~~
|
|
$ drush -l test1 status
|
|
$ drush -l test1 updatedb
|
|
~~~
|
|
|
|
|
|
|
|
## Optimisation
|
|
|
|
* Drupal 7 : <https://www.drupal.org/docs/7/managing-site-performance-and-scalability/optimizing-drupal-to-load-faster-server-mysql>
|
|
* Drupal 8 : <https://www.valuebound.com/resources/blog/a-beginners-guide-to-performance-optimization-drupal-8>
|
|
|
|
### watchdog
|
|
|
|
Désactiver le logging non nécessaire en prod... surtout dans la base de données : <https://www.karelbemelmans.com/2015/05/drupal-watchdog-logging-dblog-vs-syslog/>
|
|
|
|
<https://www.drush.org/12.x/commands/watchdog_show/>
|
|
<https://www.drush.org/12.x/commands/watchdog_delete/>
|
|
|
|
À noter que l'on peut lire, supprimer, etc. avec Drush :
|
|
|
|
https://www.drush.org/12.x/commands/watchdog_delete/
|
|
https://www.drush.org/12.x/commands/watchdog_list/
|
|
https://www.drush.org/12.x/commands/watchdog_show/
|
|
|
|
### cache
|
|
|
|
Dans les versions récentes, Drupal génère du cache, notamment via Twig.
|
|
Cela peut générer des entrées dans les tables MySQL cache_page, cache_date, etc.
|
|
|
|
On peut lire la configuration courant de Twig via :
|
|
|
|
~~~
|
|
$ drush php:eval "var_export(\Drupal::getContainer()->getParameter('twig.config'));"
|
|
|
|
array (
|
|
'debug' => true,
|
|
'auto_load' => true,
|
|
'cache' => true,
|
|
)
|
|
~~~
|
|
|
|
#### désactiver le cache Twig
|
|
|
|
<https://www.drupal.org/docs/develop/development-tools/disable-caching>
|
|
|
|
Dans `sites/default/` (ou le répertoire du site ciblé) on crée un fichier `service.yml` contenant notamment :
|
|
|
|
~~~
|
|
parameters:
|
|
twig.config:
|
|
cache: false
|
|
~~~
|
|
|
|
On crée également un fichier `settings.local.php` contenant notamment :
|
|
|
|
~~~
|
|
$settings['cache']['bins']['render'] = 'cache.backend.null';
|
|
$settings['cache']['bins']['page'] = 'cache.backend.null';
|
|
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
|
|
~~~
|
|
|
|
Ce fichier `settings.local.php` doit être inclus dans `settings.php` :
|
|
|
|
~~~
|
|
if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
|
|
include $app_root . '/' . $site_path . '/settings.local.php';
|
|
}
|
|
~~~
|
|
|
|
Enfin, n'oubliez pas de vider le cache via Drush après tout changement de configuration :
|
|
|
|
~~~
|
|
$ drush cache:rebuild
|
|
$ drush php:eval "var_export(\Drupal::getContainer()->getParameter('twig.config'));"
|
|
~~~
|
|
|
|
À noter que dans les versions les plus récentes, on peut forcer via des variables :
|
|
|
|
~~~
|
|
$ drush state:set twig_cache_disable 1 --input-format=integer
|
|
$ drush state:set disable_rendered_output_cache_bins 1 --input-format=integer
|
|
$ drush cache:rebuild
|
|
~~~
|
|
|
|
|
|
|
|
|
|
## Sécurité
|
|
|
|
### Annonces de sécurité
|
|
|
|
Nous recommandons aux développeurs de garder un oeuil sur [les annonces de sécurité](https://www.drupal.org/security) faites par l'équipe Drupal.
|
|
|
|
|
|
### CVE-2018-7600 // SA-CORE-2018-002
|
|
|
|
Règle mod_security de protection (théorique)
|
|
|
|
~~~
|
|
SecRule ARGS_GET_NAMES|ARGS_POST_NAMES|REQUEST_COOKIES_NAMES "^#" "t:none,log,deny,msg:'CVE-2018-7600/Drupal-SA-CORE-2018-002 -- Deny # in (cookie|query|post) names',id:300000001"
|
|
~~~
|
|
|
|
## Plomberie
|
|
|
|
### An automated attempt to create the directory ../config/sync failed, possibly due to a permissions problem.
|
|
|
|
Ça arrive quand on a initialisé un projet Drupal depuis composer. Il semble que ce soit [un vieux bug non corrigé](https://github.com/drupal-composer/drupal-project/issues/274)
|
|
|
|
La solution est de créer un dossier `config/sync` a la racine du projet, avec des droits d'écritures pour le serveur web.
|