Debian – Apache2 reload vs restart mais pourquoi ?

Bon un petit billet pour expliquer un cas rencontré qui me semble des plus incohérents. Attention sur une ancienne version d’apache2 (la 2.2.16 autant dire une très vieille version).

Le contexte, je suis sur un serveur Debian en train de modifier des virtualhosts apache2, jusqu’ici rien de bien méchant.

Après ma modification (toute petite et n’ayant aucune conséquence sur la suite de l’histoire) je lance un « reload » d’apache2 => tout est ok.

Comme notre bonne pratique le veut (un peu comme chez les électriciens), c’est le dernier qui intervient qui est responsable donc pour éviter au copain de se prendre un restart qui failed à cause de ma modification (et ce potentiellement des mois après) je lance un « restart » d’apache2 et là bam ça failed. Je commente ma modification et je relance un « restart » et au surprise ça failed encore. J’en tire une première conclusion la bonne pratique n’a pas été respecté sur l’intervention précédente, bon cela arrive ce n’est pas le top mais ce n’est pas dramatique, la seconde conclusion que j’en tire et qui me pose beaucoup de souci, c’est là le souci réel c’est que la commande reload autorise des configurations qui ne sont pas bonnes alors que la commande restart elle ne les autorise pas donc à quoi sert d’utiliser une commande qui peu vous entrainer ce genre de soucis des mois après ?

Bon je me creuse la tête et je me dis tiens maintenant que je sais où est l’erreur je désactive le virtualhost concerné, je lance un « restart » => Ok parfait, je vais plus loin je réactive le virtualhost et je lance un « reload » et là devinez quoi bah OK donc la conclusion c’est quand vous avez une configuration qui ne passe pas en restart, commentez là, faites un restart, décommentez là et faites un reload mais oui bien sûr c’est super trivial.

Si certains comprennent ce genre de chose je suis preneur mais personnellement, je trouve ça incohérent surtout quand on sait qu’il y avait bien une erreur dans ma configuration. Donc le reload ne check pas autant que le restart et on ne peut être sûr d’une config qu’après un restart seulement.

Pas top 😉

Certificat ssl et virtualhost en 443 sur apache2 – debian

Si vous rencontrez une erreur de « restart » d’apache2 (attention le « reload » lui passe, ce que je ne comprendrai jamais c’est l’utilité d’une commande qui passe sur des configurations non valides plus d’explication ici) qui mentionne dans le fichier /var/log/apache2/error.log :

Server should be SSL-aware but has no certificate configured [Hint: SSLCertificateFile] ((null):0)

Il y a plusieurs points à vérifier le premier d’après ce forum est de vérifier que le chemin d’accès aux différents éléments de votre Virtualhost en 443 sont cohérents dans l’exemple suivant il faut vérifier « /etc/ssl/certs/domaine.fr.crt » et « /etc/ssl/private/domaine.fr.key » :

NameVirtualHost *:443

‹VirtualHost *:443›
    ServerName www.domaine.fr
   
    DocumentRoot /var/www/
    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/domaine.fr.crt
    SSLCertificateKeyFile /etc/ssl/private/domaine.fr.key
‹/VirtualHost›

Dans mon cas cela n’a pas suffit, j’ai donc cherché un peu plus loin en relisant l’erreur qui m’indique que le serveur n’aurait pas de certificat de configurer pour quelque chose et je me suis aperçu que j’avais dans mes Virtualhost en 443, un Virtualhost de redirection comme ci-après :

NameVirtualHost *:443

‹VirtualHost *:443›
    ServerName domaine.fr
    RedirectMatch 301 ^/(.*) https://www.domaine.fr/$1
‹/VirtualHost›

Et là c’est le drame, oui on veut faire une redirection mais pour que cette redirection fonctionne il faut indiquer au serveur le certificat correspondant à domaine.fr, j’ai donc transformé mon Virtualhost en :

NameVirtualHost *:443

‹VirtualHost *:443›
    ServerName domaine.fr
    RedirectMatch 301 ^/(.*) https://www.domaine.fr/$1

    SSLEngine On
    SSLCertificateFile /etc/ssl/certs/domaine.fr.crt
    SSLCertificateKeyFile /etc/ssl/private/domaine.fr.key
‹/VirtualHost›

Et un « restart » d’apache2 plus tard tout est rentré dans l’ordre.

Enjoy 😉

Environnement d’exécution différents entre l’utilisateur et le cron de l’utilisateur

Une simple brève pour rappeler qu’un utilisateur que ce soit root ou un autre n’a pas le même environnement d’exécution que le cron de cet utilisateur. En d’autres termes ce n’est pas parce qu’une commande s’exécute correctement lorsque que l’on est connecté en tant que l’utilisateur X que cette même commande s’exécutera correctement dans un cron de l’utilisateur X (test fait sous debian).

L’environnement étant différent l’accès à certaines commandes ne se fait pas toujours de la même façon.
Ceux sont souvent des scripts peu classiques, par exemple un script de renouvellement automatique pour let’s encrypt comme proposé ici, s’exécutera très bien en root en ne tapant pas le chemin complet vers le script mais pas via le cron de root si vous n’indiquez pas le chemin complet vers le script. Il faut donc penser à tester ces crons, de manière quasi systématique pour être certains de la bonne exécution de ceux-ci.

Et voilà 😉

Récupérer les dates de début et de fin d’un certificat ssl en ligne de commande

Si vous avez besoin de récupérer rapidement et simplement les dates de début et de fin de certificat ssl pour par exemple vérifier le temps qu’il vous reste avant l’expiration il y a plusieurs solutions :

La solution simple via le navigateur : Vous vous connectez sur l’url à vérifier et vous inspectez votre certificat à travers le navigateur, action simple et visuelle.

Oui mais pas facile à automatiser cela demande une action humaine.

Si vous souhaitez monitorer les dates de manière automatique vous pouvez passer par une ligne de commande qui vous retourne les dates du certificat, la voici :
echo | openssl s_client -showcerts -servername monUrl.fr -connect monUrl.fr:443 2>/dev/null | openssl x509 -inform pem -noout -text | egrep "Not After :|Not Before:"

Cette ligne de commande vous sort ce résultat :

Not Before: Mar 24 07:28:00 2017 GMT
Not After : Jun 22 07:28:00 2017 GMT

Il est simple par la suite de récupérer les 2 dates (Not before : date d’émission du certificat, Not after : date d’expiration du certificat) et de les stocker comme bon vous semble et de faire les calculs qui vont bien pour vous prévenir quand l’échéance du renouvellement arrive.

Et voilà 😉

Source : http://serverfault.com/questions/661978/displaying-a-remote-ssl-certificate-details-using-cli-tools

Quelles technologies se cachent derrière le format de paquets snaps « by Canonical » ?

Principe de fonctionnement des snaps

Contrairement aux paquets habituels sous Linux, les snaps ne partagent pas leurs dépendances. C’est ce qui explique que les logiciels empaquetés dans des snaps soient indépendants du système. Les paquets sont bien plus lourds et chaque logiciel lancé chargera en RAM l’intégralité de ses dépendances sans les partager.

Un paquet snap est une archive SquashFS montée en lecture seule, exactement comme un Live CD sous Linux. Les paquets sont signés comme les dépôts et mis à jours de manière transactionnelle. Les mises à jours n’ajoutent que les différences entre la nouvelle version et l’actuelle, sans retélécharger intégralement le paquet.

Chaque paquet dispose d’autorisations précises pour accéder à d’autres applications, services ou fonctionnalités du système d’exploitation (via AppArmor). Leurs dossiers « tmp » sont séparés.

Un snap peut difficilement endommager ou déstabiliser le système :

Contrairement aux conteneurs à la mode, type docker et compagnie, les paquets sont montés dans des dossiers isolés par confinement, ils utilisent donc le noyau du système et n’ont pas d’interface réseau individuelle requérant une gestion NAT compliquée.

Le système Ubuntu complet a été découpé et mis dans des snaps dans l’édition Ubuntu Core. Voici à quoi ressemble l’OS actuel :

Et voici Ubunutu Core :

Sur Ubuntu Core, les .deb ne disparaissent pas du système pour autant mais ne sont plus la voie principale pour installer des paquets, puisqu’apt semble placé dans un conteneur (assez peu d’info trouvée à ce sujet). Dans un premier temps en revanche, l’option la plus souple semble d’installer snapd (l’apt des snaps) sur un système non-snappy tel que l’Ubuntu Desktop classique, ce qui vous prive toutefois du déploiement facilité de mises à jour d’Ubuntu Core.

Vous pouvez trouver plus d’informations en écoutant cette conférence de l’Ubuntu Party de Paris.

Que sont les paquets Snaps développés par Canonical pour la portabilité ?

Introduction

Avec son désir d’interface graphique « convergeante », c’est à dire adaptative entre des tailles d’écran très différentes, Canonical doit faire face à des problèmes de portabilité de ses applications.

Le monde mobile a ceci de particulier que les périphériques sont vendus préinstallés, à des utilisateurs néophytes, le plus souvent sur l’architecture ARM réputée plus complexe que le monde standardisé des processeurs x86 de bureau. Mettre le téléphone d’un utilisateur à jour et à distance relève dès lors du défis. L’univers Android le connait bien, puisque les téléphones reçoivent au mieux quelques mises à jour avant d’être abandonnés.

L’entreprise Canonical veut éviter de tomber dans ce piège et pouvoir gérer elle même les mises à jours de tous les périphériques utilisant son OS, mobiles comme ordinateurs de bureau. Cela lui permettra d’une part d’éviter une fragmentation importante des versions de son OS sur le marché mobile, d’autre part d’étendre la prise en charge de ses applications sur ordinateur de bureau vers d’autres distributions Linux.

Des paquets universels

La solution envisagée repose sur la création d’un format de paquet universel, différent de deb ou rpm, capable de s’installer sur tout système d’exploitation Linux ayant installé le logiciel snapd, équivalent d’apt. Snappy est déjà disponible dans Gentoo, Fedora, Arch Linux, Debian etc.

Puisque ces paquets sont portables, il existe un site expliquant comment packager des applications ainsi qu’un store d’applications empaquetées.

Microsoft Azure supporte Ubuntu Snappy depuis fin 2014, une version serveur d’Ubuntu utilisant les snaps, et Ubuntu Desktop les supporte depuis la version 16.04.

L’intérêt pour les développeurs

Tout le casse tête pour un développeur d’applications souhaitant prendre en charge l’univers Linux est de devoir s’intéresser à chaque distribution individuellement, empaqueter son logiciel en .deb, .rpm et continuer avec les nombreux autres formats, tout en s’impliquant dans un processus long et complexe de maintient de ses paquets dans les dépôts officiels des distributions qu’il veut toucher, et recommencer lors de chaque mise à jour desdites distributions, là où un .exe sous Windows peut fonctionner de XP à Windows 10 sans avoir eu à s’en soucier.

Les paquets snaps viennent de résoudre cette problématique.

L’intérêt pour les utilisateurs

En revanche, côté utilisateur, les .deb ont beaucoup d’avantages :

  • On peut les installer via un store applicatif (apt, la logithèque Ubuntu, le centre de logiciels Gnome, celui de KDE etc)
  • L’installation de paquets sur le système requiers les droits « root »
  • Tous les paquets sont vérifiés et signés, donc sûrs, leur présence dans un dépôt officiel garanti qu’ils soient libres et que ce soit bien la version officielle du développeur initial (et non trafiquée par Sourceforge)
  • Les mises à jours de tous les logiciels sont centralisées dans un seul outil, ce dont les utilisateurs de Windows rêvent depuis sa création
  • Les dépendances d’un logiciel sont partagées, rendant son téléchargement initial ultra léger (plus on a de logiciels installés plus on a de change d’avoir déjà toutes les bibliothèques les plus populaires). Autre avantage, la consommation en RAM est réduite à son minimum car une bibliothèque n’est chargée qu’une fois pour plusieurs logiciels (GTK est un bon exemple). Le système est donc rapide pour installer, lancer et mettre à jour ses logiciels.

Et quelques inconvénients :

  • Les versions des logiciels sont figées dans les dépôts, on a rarement la dernière version du développeur, seulement les mises à jour pour la version en cours
  • Ajouter des dépôts externe créé irrémédiablement de l’instabilité, en proposant parfois des mises à jour de dépendances
  • Installer un logiciel hors des dépôts n’est pas une facilité et le mettre à jour est plus compliqué

L’avantage des paquets snaps pour l’utilisateur est la possibilité d’avoir les dernières versions disponibles de chaque logiciel sans avoir à attendre la prochaine montée de version du système. Les paquets snaps pourraient convaincre des développeurs dont le logiciel fonctionne sous Linux de faire l’effort de l’empaqueter pour le distribuer et le maintenir. Certains logiciels comme l’interface Unity représentent actuellement un trop grand défi pour être empaquetés sur d’autres distributions. Enfin, les vieux logiciels abandonnés finissent souvent par ne plus avoir de paquets deb/rpm récents et ne peuvent plus être exécutés sur les distributions récentes à cause de leurs dépendances.

Les paquets snaps arrivent avec un inconvénient, en terme de poids et consommation en RAM. Pour savoir de quoi ils sont faits, lisez la suite !

Nokogiri : installer avec « Building native extensions » sous Mac OSX 10.12 Sierra

Si l’installation de la gem Nokogiri provoque une erreur telle que :

$ gem install nokogiri -v 1.6.7.1
Fetching: nokogiri-1.6.7.1.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
  ERROR: Failed to build gem native extension.

    current directory: /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/ext/nokogiri
/Users/username/.rvm/rubies/ruby-2.3.1/bin/ruby -r ./siteconf20170214-68028-185u3z7.rb extconf.rb
checking if the C compiler accepts ... yes
checking if the C compiler accepts -Wno-error=unused-command-line-argument-hard-error-in-future... no
Building nokogiri using packaged libraries.
Using mini_portile version 2.0.0
checking for iconv.h... yes
checking for gzdopen() in -lz... yes
checking for iconv using --with-opt-* flags... yes
************************************************************************
IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxml2-2.9.2
with the following patches applied:
  - 0001-Revert-Missing-initialization-for-the-catalog-module.patch
  - 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch
  - 0003-Stop-parsing-on-entities-boundaries-errors.patch
  - 0004-Cleanup-conditional-section-error-handling.patch
  - 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch
  - 0006-Another-variation-of-overflow-in-Conditional-section.patch
  - 0007-Fix-an-error-in-previous-Conditional-section-patch.patch
  - 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch
  - 0009-Updated-config.guess.patch
  - 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch
  - 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch
  - 0012-Avoid-processing-entities-after-encoding-conversion-.patch
  - 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch
  - 0014-CVE-2015-5312-Another-entity-expansion-issue.patch
  - 0015-Add-xmlHaltParser-to-stop-the-parser.patch
  - 0016-Detect-incoherency-on-GROW.patch
  - 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch
  - 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install

Note, however, that nokogiri is not fully compatible with arbitrary
versions of libxml2 provided by OS/package vendors.
************************************************************************
Extracting libxml2-2.9.2.tar.gz into tmp/x86_64-apple-darwin15.0.0/ports/libxml2/2.9.2... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0001-Revert-Missing-initialization-for-the-catalog-module.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0003-Stop-parsing-on-entities-boundaries-errors.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0004-Cleanup-conditional-section-error-handling.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0006-Another-variation-of-overflow-in-Conditional-section.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0007-Fix-an-error-in-previous-Conditional-section-patch.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0009-Updated-config.guess.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0012-Avoid-processing-entities-after-encoding-conversion-.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0014-CVE-2015-5312-Another-entity-expansion-issue.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0015-Add-xmlHaltParser-to-stop-the-parser.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0016-Detect-incoherency-on-GROW.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch... OK
Running 'configure' for libxml2 2.9.2... OK
Running 'compile' for libxml2 2.9.2... OK
Running 'install' for libxml2 2.9.2... OK
Activating libxml2 2.9.2 (from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/ports/x86_64-apple-darwin15.0.0/libxml2/2.9.2)...
************************************************************************
IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxslt-1.1.28
with the following patches applied:
  - 0001-Adding-doc-update-related-to-1.1.28.patch
  - 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch
  - 0003-Initialize-pseudo-random-number-generator-with-curre.patch
  - 0004-EXSLT-function-str-replace-is-broken-as-is.patch
  - 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch
  - 0007-Separate-function-for-predicate-matching-in-patterns.patch
  - 0008-Fix-direct-pattern-matching.patch
  - 0009-Fix-certain-patterns-with-predicates.patch
  - 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch
  - 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch
  - 0014-Fix-for-bug-436589.patch
  - 0015-Fix-mkdir-for-mingw.patch
  - 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch
  - 0017-Updated-config.guess.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install
************************************************************************
Extracting libxslt-1.1.28.tar.gz into tmp/x86_64-apple-darwin15.0.0/ports/libxslt/1.1.28... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0008-Fix-direct-pattern-matching.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0014-Fix-for-bug-436589.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0015-Fix-mkdir-for-mingw.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0016-Fix-for-type-confusion-in-preprocessing-attributes.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0017-Updated-config.guess.patch... OK
Running 'configure' for libxslt 1.1.28... OK
Running 'compile' for libxslt 1.1.28... ERROR, review '/Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/ext/nokogiri/tmp/x86_64-apple-darwin15.0.0/ports/libxslt/1.1.28/compile.log' to see what happened. Last lines are:
========================================================================
                      ^
xsltutils.c:1876:24: note: expanded from macro 'XSLT_CLOCK'
#    define XSLT_CLOCK CLOCK_REALTIME
                       ^
xsltutils.c:1886:23: error: use of undeclared identifier 'CLOCK_REALTIME'
        clock_gettime(XSLT_CLOCK, &startup);
                      ^
xsltutils.c:1876:24: note: expanded from macro 'XSLT_CLOCK'
#    define XSLT_CLOCK CLOCK_REALTIME
                       ^
xsltutils.c:1890:19: error: use of undeclared identifier 'CLOCK_REALTIME'
    clock_gettime(XSLT_CLOCK, &cur);
                  ^
xsltutils.c:1876:24: note: expanded from macro 'XSLT_CLOCK'
#    define XSLT_CLOCK CLOCK_REALTIME
                       ^
1 warning and 3 errors generated.
make[2]: *** [xsltutils.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
========================================================================
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
  --with-opt-dir
  --with-opt-include
  --without-opt-include=${opt-dir}/include
  --with-opt-lib
  --without-opt-lib=${opt-dir}/lib
  --with-make-prog
  --without-make-prog
  --srcdir=.
  --curdir
  --ruby=/Users/username/.rvm/rubies/ruby-2.3.1/bin/$(RUBY_BASE_NAME)
  --help
  --clean
  --use-system-libraries
  --enable-static
  --disable-static
  --with-zlib-dir
  --without-zlib-dir
  --with-zlib-include
  --without-zlib-include=${zlib-dir}/include
  --with-zlib-lib
  --without-zlib-lib=${zlib-dir}/lib
  --enable-cross-build
  --disable-cross-build
/Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:366:in `block in execute': Failed to complete compile task (RuntimeError)
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:337:in `chdir'
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:337:in `execute'
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:111:in `compile'
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:150:in `cook'
  from extconf.rb:289:in `block (2 levels) in process_recipe'
  from extconf.rb:182:in `block in chdir_for_build'
  from extconf.rb:181:in `chdir'
  from extconf.rb:181:in `chdir_for_build'
  from extconf.rb:288:in `block in process_recipe'
  from extconf.rb:187:in `tap'
  from extconf.rb:187:in `process_recipe'
  from extconf.rb:490:in `
' To see why this extension failed to compile, please check the mkmf.log which can be found here: /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/extensions/x86_64-darwin-15/2.3.0/nokogiri-1.6.7.1/mkmf.log extconf failed, exit code 1 Gem files will remain installed in /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1 for inspection. Results logged to /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/extensions/x86_64-darwin-15/2.3.0/nokogiri-1.6.7.1/gem_make.out

Vous pouvez essayer les solutions suivantes, en adaptant le numéro de version à celui voulu :
gem install nokogiri -v 1.6.8.1 -- --use-system-libraries
gem install nokogiri -v 1.6.8.1 -- --use-system-libraries=true --with-xml2-include=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml2
brew uninstall libxml2 (fourni par Xcode) puis relancer gem install nokogiri -v 1.6.8.1 -- --use-system-libraries
brew reinstall xz --universal puis relancer gem install nokogiri -v 1.6.8.1 -- --use-system-libraries

Passenger, gestion des ressources avec plus de 6 applications

Erreur type rencontrée : This website is under heavy load, too many requests

Too many requests ?

Passenger contient dans sa configuration un paramètre PassengerMaxRequestQueueSize définissant le nombre de requêtes en attente à 100 par défaut.
Contrairement à ce que l’on pourrait penser, rallonger cette file d’attente n’est pas une bonne idée. Le serveur a une capacité à traiter un volume de requêtes simultanées donné. Lorsqu’il ne peut plus en traiter, les clients doivent alors patienter dans la file d’attente : lorsque le serveur a placé 100 requêtes en attente, toutes les prochaines recevront l’erreur « 503 Service Unavailable ».
Cette file d’attente est une sorte de tampon lors de montée en charge momentanée et non une solution durable. On peut en effet s’attendre à voir le temps d’attente devenir de plus en plus long à mesure que la file s’allonge, et des clients seront alors tentés de quitter ou de rafraichir leur page, augmentant le nombre de requêtes à traiter sans même en attendre la réponse.

Si le serveur ne peut plus faire face, il faut alors en changer ou augmenter ses ressources. Mais ce n’est pas la seule raison de l’apparition de notre erreur initiale.

Beaucoup d’appli, pool trop petit

Lorsque l’erreur « This website is under heavy load » apparait, vous pouvez soupçonner une autre cause qu’un nombre trop élevé de requêtes. C’est le cas si vous venez de lancer des actions gourmandes sur plusieurs applications, comme dans notre cas.

Ce qu’explique cet article c’est la manière dont Passenger gère des applications. Par nature, une application Rails ne peut gérer qu’une requête à la fois. Pour paralléliser le traitement des requêtes, Passenger créé des processus pour chaque nouvelle requête, dans lesquels l’application est lancée à nouveau.
passenger-request_load_balancing
Un processus ne peut donc traiter qu’une requête à la fois, mais Passenger n’attribue pas de limite de création de processus et il s’assure qu’au moins un processus reste toujours actif par application. Les processus inactifs depuis plus de 5 minutes sont éteints.

En revanche, Passenger définit une limite globale du nombre de processus actifs, par défaut de 6 processus, qui fait autorité sur tout autre paramètre de configuration. Cela signifie qu’avec 7 applications, Passenger passera son temps à jongler entre les processus actifs pour n’en garder que 6, éteignant un processus pour en démarrer un autre.

Par défaut, si une action telle qu’un import de données est lancée simultanément sur 6 applications, les 6 processus actifs ne peuvent plus être « tués » car ils sont en cours de traitement long et la queue va se remplir très rapidement. Le paramètre « passengermaxpoolsize » est donc à configurer en fonction du nombre d’applications que Passenger gère, selon vos besoins et la capacité du serveur.

Pour ne pas manquer de mémoire vive, la documentation conseille de garder 25% de la RAM totale pour l’OS. On divise les 75% de RAM restants par la consommation en RAM totale de toutes les applications (attention aux unités), ce qui indique combien de processus le serveur est en théorie capable d’exécuter.

Il est possible de surveiller la consommation en ressources de chaque application via la commande passenger-status. On y trouve la longueur courante de la queue, bien qu’il ne soit pas possible de la visualiser. Il est cependant possible d’afficher les requêtes en cours de traitement avec passenger-status --show=requests.