Foire aux questions — webmaster

Pourquoi devoir utiliser un sous-domaine (virtualhost) pour Paheko, par exemple "gestion.monassociation.fr" ? Pourquoi est-ce qu'il n'est pas possible d'installer Paheko dans un sous-répertoire comme "monassociation.fr/gestion/" ?

Paheko stocke l'intégralité de ses données dans une base de données SQLite, enregistrée sur le disque dans le fichier "association.sqlite" qui est situé à la racine de l'installation de Paheko. Ce fichier contient l'intégralité de vos données : liste des membres (avec leurs coordonnées notamment), cotisations, comptabilité, etc.

De plus à la racine de Paheko sont également stockées des informations sensibles : cache, plugins, templates, version de Paheko, etc.

Tout cela est normalement protégé par des directives dans le fichier .htaccess à la racine de Paheko, mais si vous n'utilisez pas Apache (par exemple nginx ou lighttpd) ou n'avez pas activé le module "mod_alias" la protection ne fonctionnera pas et toutes ces données seront accessibles à tous.

Enfin, cela rajoute un sous-répertoire "/www/" disgracieux à l'adresse des pages.

Pour toutes ces raisons, il est préférable d'éviter de mettre Paheko dans un sous-répertoire et d'utiliser un sous-domaine, à moins de savoir ce que vous faites.

Ma base de données (fichier association.sqlite) est tombé dans de mauvaises mains, qu'est-ce que je risque ?

Le risque principal est de voir vos données adhérents revendues ou utilisées pour du spam ou autres fraudes. Les mots de passe permettant de se connecter sont chiffrés et hashés, et il est impossible de les retrouver sans utiliser du bruteforce (essayer toutes les combinaisons possibles), mais pour être sûr il vaut mieux changer le mot de passe de tous les adhérents qui avaient le droit de se connecter.

J'ai perdu l'accès à mon compte (mot de passe ou email oublié), comment faire ?

Si vous avez installé Paheko sur votre serveur il vous suffit de créer un fichier config.local.php à la racine de Paheko et d'y inscrire :

<?php
namespace Garradin;
const LOCAL_LOGIN = 1;

Ceci vous permettra d'être connecté en tant que membre n°1 (normalement c'est le premier créé, donc l'administrateur). Si votre membre n°1 n'est pas administrateur il faudra modifier le chiffre 1 par le numéro d'un membre administrateur.

Effacez ce fichier ou supprimer la ligne const LOCAL_LOGIN = … après avoir créé un nouveau membre administrateur.

Comment configurer X-SendFile avec Apache ?

Paheko peut utiliser l'extension Apache X-SendFile pour permettre de télécharger les fichiers plus rapidement en prenant moins de ressources sur le serveur. Pour cela il faut ajouter ceci dans le fichier config.local.php:

define('Garradin\ENABLE_XSENDFILE', true);

Ensuite installez et activez le module apache (ici la commande pour Debian/Ubuntu) :

sudo apt-get install libapache2-mod-xsendfile
sudo a2enmod xsendfile

Et dans votre configuration Apache ajouter une section pour activer X-SendFile sur votre instance Paheko (attention ne marche pas dans un fichier .htaccess, il faut obligatoirement modifier la configuration serveur du vhost) :

 <Directory /path/to/paheko/www>
    XSendFile On
    XSendFilePath /path/to/paheko
</Directory>

Le répertoire pointé par XSendFilePath doit obligatoirement être le répertoire parent de Paheko.

Rechargez la configuration Apache (sudo service apache2 reload) et faites un essai en téléchargeant un fichier dans Paheko plusieurs fois : si vous obtenez un fichier de 0 octets c'est que X-SendFile n'est pas activé correctement.

Comment fonctionne la mise à jour ?

Paheko dispose de plusieurs mécanismes pour que la mise à jour soit la plus sûre possible :

  • avant la mise à jour, un fichier de verrouillage (lock) est créé, ce qui fait qu'une seule mise à jour peut être effectuée en même temps ;
  • avant la mise à jour, une sauvegarde de la base de données est effectué proprement (association.pre-upgrade-1.3.4.sqlite par exemple), permettant de revenir en arrière juste en recopiant ce fichier à la place de association.sqlite. Ce fichier est conservé après la mise à jour même si elle s'est bien passé ;
  • si la mise à jour échoue, le backup (…pre-upgrade…sqlite) est restauré à la place de association.sqlite : on peux donc ré-essayer la mise à jour sans souci ;
  • à la fin de la mise à jour, une vérification de l'intégrité de la base de données est réalisée, s'il y a le moindre souci la mise à jour échoue, la sauvegarde est restaurée.

Il est donc très difficile de corrompre une mise à jour. Dans le pire des cas, il y a un bug dans le code qui empêche la mise à jour de s'effectuer : tu es bloqué, mais tu peux revenir à la version d'avant, et tu n'as perdu aucune donnée.

Comment sauvegarder le fichier association.sqlite ?

Si vous ne gérez qu'une seule association, le meilleur moyen est d'utiliser l'interface de Paheko pour créer une sauvegarde :-)

La théorie : il ne faut pas faire juste une copie du fichier .sqlite car il peut être écrit en même temps et donc tu peux copier un fichier corrompu.

C'est documenté dans la doc SQLite : https://www.sqlite.org/howtocorrupt.html et ici : https://litestream.io/alternatives/cron/

Donc la bonne méthode est de créer une copie via l'API de backup de SQLite :

sqlite3 association.sqlite "VACUUM INTO 'backup.sqlite'"

Et ensuite faire un backup de ce fichier "backup.sqlite". De cette manière on aura 100% de chances que le fichier "backup.sqlite" n'est pas corrompu.

On peux aussi préférer faire un dump :

sqlite3 association.sqlite .dump > backup.sql

Qui donnera toutes les commandes SQL pour re-créer la BDD.

Si on fait un snapshot (par exemple avec btrfs, ZFS ou LVM) et non un "cp" (ou rsync/borg/etc.) alors ce n'est pas nécessaire, le risque étant qu'avec une copie normale, on commence à copier le fichier, mais avant que la copie ne soit terminée, un autre process modifie le reste du fichier : on se retrouve avec des bouts de l'ancienne version et des bouts de la nouvelle version.

Avec un snapshot instantané type copy-on-write, le problème n'existe pas. Donc une autre solution c'est de faire un snapshot et de faire un backup de ce snapshot, vu qu'il ne peut plus être modifié.

Ça t'évite de faire un script qui fait un "VACUUM INTO" de chaque base de données.

Il est conseillé de toutes façons d'utiliser le snapshot, car tu peux aussi avoir des problèmes de synchro avec les fichier du cache, ou les fichiers de l'association si on a choisi de les stocker en dehors de SQLite.

Il est à noter que tout cela ne concerne que les fichier "association.sqlite". Tous les autres fichiers ".sqlite" sont des sauvegardes créées par Paheko (via la copie "propre" mentionnée plus haut), aucun processus n'écrit dedans, donc il est possible de juste les copier/rsync/etc. sans risque.

À quoi sert le lien symbolique www/.cache ?

Le répertoire .cache stocke le cache statique du site web.

Par défaut, si on utilise Apache, quand on consulte une page du site web en mode visiteur (sans être connecté à l'admin), la page générée (le HTML) est stocké dans le cache web, par défaut data/cache/web/[hash du host]/[hash de l'URL].html

Si on consulte un fichier public (image, document, etc.), un lien symbolique est créé dans data/cache/web/[hash du host]/[hash de l'URL].

Ensuite via ce qui est indiqué dans le .htaccess par Paheko, Apache va détecter que la page HTML, ou le fichier en lien symbolique, existe dans le cache, et le renvoyer directement, sans faire appel à PHP.

Ça permet à Paheko d'être extrêmement rapide et léger, si une association voit un afflux soudain de visites sur son site, le serveur ne sera pas aussi surchargé.

En effet utiliser le cache web permet de diviser la charge par 10 à 20.

Note : le cache ne concerne pas les utilisateurs connectés, et le cache des pages web est mis à jour toutes les heures.

Pour que ça fonctionne cependant, il faut que Apache puisse accéder au fichier, et pour cela il faut qu'il soit dans le DOCUMENT_ROOT. D'où le lien symbolique dans www/.cache

La configuration par défaut de Paheko est conçue pour fonctionner "sans rien faire" sur un hébergement mutualisé type Ouvaton, OVH, etc. D'où le fait que Paheko essaye de créer le lien symbolique par lui-même s'il n'existe pas.

Si on héberge plusieurs instances Paheko et qu'on veut garder le répertoire du code de Paheko en lecture seule, alors il est plus intéressant d'utiliser un cache web partagé, en configurant la constante WEB_CACHE_ROOT :

const WEB_CACHE_ROOT = '/path/to/hosted/pahekos/cache/web/%host%';

Il faut ensuite créer le lien symbolique manuellement, si Paheko n'a pas le droit de le faire automatiquement.

Pourquoi ça n'est pas un sous-répertoire du cache partagé (data/cache/shared) ?

Le cache partagé mentionné stocke des fichiers PHP, générés à partir du code Smarty ou Brindille. Cela évite de re-parser les templates à chaque fois.

Lors d'une mise à jour, on efface ce cache, pour être sûr que si un template à changé, on n'utilise pas une ancienne version encore en cache qui provoquerait éventuellement des erreurs. Donc on ne veut pas forcément effacer le cache web en même temps.