Tiny Tiny RSS avec Nginx, PHP-FPM et MariaDB

RSS

Tiny Tiny RSS avantages et fonctionnalités :

  • Interface fluide et responsive
  • Multi-utilisateurs
  • Mode hors-connexion pour continuer à lire vos feeds
  • Multilingue
  • Gestion des tags et catégories
  • Moteur de recherche
  • Raccourcis clavier
  • Support du format OPML
  • Podcasts
  • Personnalisations via des plugins et des thèmes
  • Applications Android et iOS
  • Gratuit

Côté client, seul un navigateur est nécessaire, côté serveur, Tiny Tiny RSS a besoin d’un serveur web (Nginx), de PHP, d’une interface permettant la communication entre le serveur web et PHP (PHP-FPM) et d’une base de données (MariaDB). Amélioration des performances de tt-rss grâce à OPCache ,sécurisation des échanges grâce à un certificat SSL/TLS.

Prérequis

Avoir nginx, PHP7.0 et mariadb installés

Installation Tiny Tiny RSS

Passage en super utilisateur

sudo -s

Télécharger les sources de tt-rss :

cd /var/www
git clone https://tt-rss.org/git/tt-rss.git ttrss

Pour des raisons évidentes de sécurité, il est donc recommandé de cloisonner ces utilisateurs et d’avoir un utilisateur dédié à la gestion du dossier ttrss. Cet utilisateur aura des droits aussi restreints que possible à ce répertoire.

Modifier le propriétaire du répertoire /var/www/ttrss et l’attribuer à un nouvel utilisateur dédié ttrss
Nginx est lancé sous l’utilisateur www-data et doit avoir accès en lecture au répertoire /var/www/ttrss pour lire les ressources statiques (HTML, CSS, JS, etc.).
Attribuer le répertoire /var/www/ttrss au groupe www-data.

useradd ttrss                            # création utilisateur dédié ttrss
chown -R ttrss:www-data /var/www/ttrss   # changement de propriétaire par ttrss et groupe par www-data

Retirer toutes les permissions de ce répertoire aux autres utilisateurs.

chmod -R o-rwx /var/www/ttrss

PHP et ses modules

Tiny Tiny RSS nécessite certains modules PHP pour fonctionner :

  • PHP PDO : connecteur pour MariaDB
  • PHP JSON & PHP XML : opérations sur la lecture des flux RSS
  • PHP mbstring : support des caractères multi-octets
  • PHP fileinfo : améliore les performances d’analyse de fichiers
  • PHP CURL : nécessaire pour certains plugins
  • PHP POSIX : nécessaire pour le processus de mise à jour des flux
  • PHP GD : opérations sur les images présentes dans les flux
  • PHP INTL : support de l’internationalisation.

Installer les paquets suivants : php-fileinfo php-posix

sudo apt-get -y install php7.0-cli php7.0-mysql php7.0-json php7.0-xml php7.0-mbstring php7.0-curl php7.0-gd php7.0-intl

version installée sur votre système, tapez la commande suivante :

php -v
PHP 7.0.30-0+deb9u1 (cli) (built: Jun 14 2018 13:50:25) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.30-0+deb9u1, Copyright (c) 1999-2017, by Zend Technologies

PHP-FPM

Le module PHP-FPM permet la communication entre le serveur Nginx et PHP, basée sur le protocole FastCGI. Ce module, écoutant sur le port 9000 par défaut ou sur un socket UNIX, permet notamment l’exécution de scripts PHP dans un processus indépendant de Nginx avec des UID et GID différents. Il sera alors possible, dans le cas de la gestion de plusieurs applications sur un même serveur, de créer et configurer un groupe (appelé aussi pool) par application. Un pool définit notamment le UID/GID des processus PHP et le nombre de processus minimum, maximum ou encore le nombre de processus en attente à lancer.

Création du pool dédié à Tiny Tiny RSS

nano /etc/php/7.0/fpm/pool.d/ttrss.conf
[ttrss]
listen = /run/php/php7.0-fpm-ttrss.sock
 
listen.owner = ttrss
listen.group = www-data
 
user = ttrss
group = www-data
 
pm = ondemand
pm.max_children = 6
pm.process_idle_timeout = 60s
pm.max_requests = 500

Redémarrer le service php-fpm afin d’activer le nouveau pool ttrss :

systemctl restart php7.0-fpm.service

Description

  • [ttrss] : nom du pool. Il est possible de créer plusieurs pools par fichier. Chaque pool doit commencer par cette directive.
  • listen : interface d’écoute des requêtes. Les syntaxes acceptées sont ADRESSE_IP:PORT (exemple : listen = 127.0.0.1:9000) et /path/to/unix/socket (exemple : listen = /var/run/ttrss.sock). Le socket est représenté comme un simple fichier sur le système et permet d’interfacer des processus entre eux sans passer par la couche réseau du système, ce qui est inutile lorsque Nginx et PHP-FPM sont hébergés sur le même serveur. Je vous conseille donc d’utiliser un socket.
  • listen.owner & listen.group : affecte l’utilisateur et le groupe au socket Unix si utilisé. Ces deux paramètres peuvent être associés au paramètre listen.mode qui définit les permissions du socket (660 par défaut). Il est important que Nginx ait les droits de lecture sur le socket Unix.
  • user & group : utilisateur et groupe sous lesquels le pool de processus sera exécuté. Cet utilisateur et ce groupe doivent bien sûr exister sur votre système et surtout accéder aux fichiers PHP de votre tt-rss. Cela veut dire aussi que chaque fichier et répertoire créé dans tt-rss appartiendra à cet utilisateur et à ce groupe. Comme nous l’avons vu dans le chapitre dédié aux droits Unix, chaque fichier devra appartenir à l’utilisateur ttrss et au groupe www-data.
  • pm : directive acceptant les 3 valeurs suivantes : static, dynamic et ondemand.
    • static : les processus, au nombre de pm.max_children, sont continuellement actifs (quelle que soit la charge et l’affluence de votre tt-rss) et sont susceptibles de consommer de la mémoire inutilement. Cette directive est recommandée si tt-rss est l’unique application de votre serveur.
    • dynamic : le nombre de processus fils pourra varier suivant la charge. Cependant, nous gardons le contrôle sur le nombre de processus fils à créer au démarrage du serveur, le nombre de processus maximum, en attente de requêtes, etc. Les directives suivantes deviennent obligatoires : pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers. Cette directive est recommandée si vous avez plusieurs pools avec un fort trafic (plus de 10 000 requêtes/jour). * ondemand : aucun processus fils n’est lancé au démarrage du serveur, les processus s’activent à la demande et auront une durée de vie définie par la directive pm.process_idle_timeout. L’intérêt de cette directive est de libérer de la mémoire en cas de faible charge mais celle-ci peut légèrement augmenter le temps de réponse de votre tt-rss. Cette directive est recommandée si vous avez plusieurs pools avec potentiellement une faible affluence.

Sachant que l’utilisation de tt-rss est personnelle et souvent limitée à quelques utilisateurs, nous choisirons et détaillerons ici la directive ondemand.

  • pm.process_idle_timeout : durée en secondes avant qu’un processus fils inactif soit détruit.
  • pm.max_requests : nombre de requêtes que chaque processus fils devra exécuter avant d’être détruit. Cette valeur ne doit pas être trop élevée afin de contourner d’éventuelles fuites mémoires, ni trop faible pour ne pas solliciter régulièrement le CPU à chaque création de processus fils. 500 reste une valeur recommandée.
  • pm.max_children : nombre maximum de processus fils. La valeur du paramètre pm.max_children varie d’un système à l’autre.

Procédure pour déterminer la valeur du paramètre pm.max_children :

Arrêtez le service php-fpm :

    sudo systemctl stop php7.0-fpm.service

Affichez la mémoire disponible (colonne available) sur votre système :

    free -m
                  total        used        free      shared  buff/cache   available
    Mem:           3913          58        2532          39        1322        3539
    Swap:          1048           0        1048

Sur cet exemple, le système dispose de 3539Mo de RAM disponible. La quantité de RAM que vous souhaitez allouer au maximum à tt-rss dépend de vous et des autres services actifs que vous disposez sur ce même système. Dans notre exemple, nous partirons du principe que nous souhaitons allouer au maximum 256Mo de RAM à tt-rss.
Affichez la mémoire utilisée par un processus fils php-fpm :

    sudo systemctl start php7.2-fpm.service && ps --no-headers -o "rss,cmd" -C php-fpm7.2 | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'
    18M

Déterminez le nombre de pm.max_children en appliquant la méthode de calcul suivante :
pm.max_children = mémoire allouée (en Mo) / mémoire utilisée par un processus fils
Dans notre exemple : 256 / 18 = 14

OPcache

OPcache (qui signifie Optimizer Plus Cache) est introduit depuis la version 5.5.0 de PHP. Il sert à cacher l’opcode de PHP, c’est-à-dire les instructions de bas niveau générées par la machine virtuelle PHP lors de l’exécution d’un script. Autrement dit, le code pré-compilé est stocké en mémoire. Cela évite ainsi l’étape de compilation à chaque requête PHP.

Vérifier et/ou activer option opcache

nano /etc/php/7.0/fpm/php.ini
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1

Redémarrer le service php-fpm pour la prise en charge

systemctl restart php7.0-fpm.service

Création de la base de données sous MariaDB

Connexion mariadb et accès au prompt MariaDB [(none)]>

mysql -uroot -p

Créer la base de données ttrss :

CREATE DATABASE ttrss;

Tout comme pour la gestion du répertoire ttrss et pour plus de sécurité, vous allez tout d’abord créer un utilisateur MySQL ttrss dédié à la base de données ttrss, renseigner un mot de passe et ensuite lui donner les droits sur cette base de données :

CREATE USER "ttrss"@"localhost";
SET password FOR "ttrss"@"localhost" = password('mon_password');
GRANT ALL PRIVILEGES ON ttrss.* TO "ttrss"@"localhost" IDENTIFIED BY "mon_password";
FLUSH PRIVILEGES;
EXIT

Virtualhost ttrss.cinay.pw

On utilise une configuration existante pour le HTTP2 et les certificats

IMPORTANT : Les certificats SSL Let’s Encrypt sont valables pour tous les sous-domaines de cinay.pw

Créer le virtualhost nginx (port 443 , HTTP2 et certificats SSL)

nano /etc/nginx/conf.d/ttrss.cinay.pw.conf
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ttrss.cinay.pw;

    include ssl_params_ttrss;
#    include header_params;
    add_header Strict-Transport-Security "max-age=31536000;";

    include dh_param;

    root /var/www/ttrss/ ;
    index index.php;
        location ~ \.php$ {
           fastcgi_split_path_info ^(.+\.php)(/.+)$;
           fastcgi_pass unix:/run/php/php7.0-fpm-ttrss.sock;
           fastcgi_index index.php;
           include fastcgi_params;
	   fastcgi_param SCRIPT_FILENAME $request_filename;
        }


    access_log /var/log/nginx/ttrss.cinay.pw-access.log;
    error_log /var/log/nginx/ttrss.cinay.pw-error.log;
}

On utilise des paramètres spécifiques pour les entêtes : add_header Strict-Transport-Security "max-age=31536000;";
et le SSL , fichier /etc/nginx/ssl_params_ttrss

cat /etc/nginx/ssl_params_ttrss 
    ssl_certificate /etc/ssl/private/cinay.pw-fullchain.pem;
    ssl_certificate_key /etc/ssl/private/cinay.pw-key.pem;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;

    ssl_prefer_server_ciphers on;

    # Ciphers with intermediate compatibility
    # https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.6.2&openssl=1.0.1t&hsts=yes&profile=intermediate
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

Vérification

nginx -t

La nouvelle configuration sera prise en compte après redémarrage du service Nginx :

systemctl restart nginx.service

Configuration ttrss

On accède au serveur ttrss par le lien https://ttrss.cinay.pw , remplir les champs

tiny

Vérification configuration Test configuration

tiny

Initialisation de la base Initialize database

tiny

Sauvegarder la configuration Save configuration

tiny

La configuration est désormais terminée !
Première connexion, login admin et mot de passe password.
Changer ces valeurs par défaut du compte administrateur dans Actions… → Configuration… → Utilisateurs.
Créer un utilisateur yannick

Pour mettre à jour vos flux, il vous suffit de double-cliquer sur les catégories, Tiny Tiny RSS ne se met pas à jour automatiquement.

Mise à jour automatique des flux

Processus en arrière plan, créer un service qui mettra automatiquement à jour les flux.
Créer le service /etc/systemd/system/ttrss-backend.service :

nano /etc/systemd/system/ttrss-backend.service
[Unit]
Description=TTRSS Backend update
Documentation=https://git.tt-rss.org/fox/tt-rss/wiki/UpdatingFeeds
Requires=network.target mysql.service
After=network.target mysql.service
 
[Service]
User=ttrss
Group=www-data
ExecStart=/var/www/ttrss/update_daemon2.php
 
[Install]
WantedBy=multi-user.target

Activer et lancer le service ttrss-backend

systemctl daemon-reload
systemctl enable ttrss-backend
systemctl start ttrss-backend

Thème tiny RSS

Les thèmes sur le site officiel
Télécharger le fichier ZIP

wget https://github.com/levito/tt-rss-feedly-theme/archive/master.zip

Décompresser le fichier ZIP

unzip master.zip

Se rendre dans le dossier

cd tt-rss-feedly-theme-master

Copier les fichiers et dossiers dans le répertoire des thèmes

cp feedly.css feedly-night.css /var/www/ttrss/themes
cp -r feedly/ /var/www/ttrss//themes

Se connecter et sélectionner le thème feedly dans les préférences