Apache et symfony: optimisation

Je vais vous présentez dans ce billet, les méthodes que j’utilise pour optimiser les réponses d’apache et par la même occasion le rewrite de symfony.

Pour pouvoir effectuer tous les réglages, voici les modules que je charge dans la configuration d’apache

LoadModule deflate_module modules/mod_deflate.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule rewrite_module modules/mod_rewrite.so

Je vais commencer par épurer le log apache. Pour cela, je vais ajouter à la fin de mon fichier de configuration httpd.conf ou apache2.conf (selon les install), les lignes suivantes:

SetEnvIf Request_URI "\.(css|gif|ico|jpg|js|png|txt|xml)$" dontlog
SetEnvIf Request_Method HEAD dontlog

Je vais tout simplement ignorer les fichiers qui contiennent les extensions listées ci-dessus. Ensuite, il suffit d’attribuer cette variable d’environnement à notre paramètre « CustomLog » de notre virtualhost comme ceci:

CustomLog logs/mywebsite.com-access_log combined env=!dontlog

Dès maintenant, Apache prendra moins de temps à écrire ces logs car il ne tiendra plus compte de ces fichiers.

Passons maintenant à la compression des fichiers entre le serveur et le client. Pour cela, j’ai utilisé le code suivant dans la configuration du virtualhost:

<Location />
# ------------- DEFLATE -------------
# http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
<IfModule mod_deflate.c>
  SetOutputFilter DEFLATE
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
  SetEnvIfNoCase Request_URI \
  \.(?:gif|jpe?g|png)$ no-gzip dont-vary
  Header append Vary User-Agent env=!dont-vary
</IfModule>
# ------------- END DEFLATE -------------
</Location>

Cela vous permettra d’économiser un peu de bande passante 😉

Nous allons maintenant nous occuper du cache Apache:

# ------------- EXPIRES RULE -------------
# http://httpd.apache.org/docs/2.0/mod/mod_expires.html
<IfModule mod_expires.c>
  ExpiresActive On

  ExpiresByType text/css "access plus 7 days"
  ExpiresByType application/javascript "access plus 7 days"
  ExpiresByType image/gif "access plus 7 days"
  ExpiresByType image/jpeg "access plus 7 days"
  ExpiresByType image/png "access plus 7 days"
</IfModule>
# ------------- END EXPIRES RULE -------------

Comme vous pouvez le constater ci-dessous, vous avez la possibilité avec la directive « ExpiresByType » de mettre différentes validités selon le type de fichier. Attention quand même lorsque vous utilisez ce genre de cache car il se peut que le serveur ne rende pas toujours le résultat actualisé. Il faut effectuer des tests avant son passage en production.

Passons maintenant à la partie symfony. Par défaut, la configuration du mod_rewrite est située dans le fichier .htaccess à la racine de votre site (dossier web). Apache va lire ce fichier à chaque requête, ce qui prend du temps. Nous allons donc tranférer cela dans notre configuration virtualhost pour l’avoir en mémoire et désactiver la lecture physique:

<Location />
# ------------- REWRITE -------------
<IfModule mod_rewrite.c>
  RewriteEngine On
  
  # Level 0 to 9 [0 = no logging, 9 = all actions] (Default: 0)
  RewriteLogLevel 0
  
  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]

  # no, so we redirect to our front web controller
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
# ------------- END REWRITE -------------
</Location>

Dans la directive « <Directory …> », nous allons passer le paramètre « AllowOverride » à none. Vous pouvez ensuite supprimer le fichier .htaccess de votre dossier web.

Pour finir, je vous donne la représentation complète de mon fichier virtualhost:

<VirtualHost *:80>
  ServerName mywebsite.com
  DocumentRoot /www/virtualhosts/mywebsite.com/web
  ErrorLog logs/mywebsite.com-error_log
  CustomLog logs/mywebsite.com-access_log combined env=!dontlog
  RewriteLog logs/mywebsite.com-rewrite.log
  
  Alias /sf /www/virtualhosts/mywebsite.com/lib/vendor/symfony/data/web/sf
  
  <Directory "/www/virtualhosts/mywebsite.com/web">
    Options Indexes FollowSymLinks SymLinksifOwnerMatch
    AllowOverride none
    Allow from All
  </Directory>
  
  <Directory "/www/virtualhosts/mywebsite.com/lib/vendor/symfony/data/web/sf">
    Options Indexes FollowSymLinks SymLinksifOwnerMatch
    AllowOverride none
    Allow from All
  </Directory>

  <Directory "/path/to/my/sfProject/web/uploads">
    php_flag engine off
  </Directory>

  <Location />
    # ------------- REWRITE -------------
    <IfModule mod_rewrite.c>
      RewriteEngine On
      
      # Level 0 to 9 [0 = no logging, 9 = all actions] (Default: 0)
      RewriteLogLevel 0
      
      # we check if the .html version is here (caching)
      RewriteRule ^$ index.html [QSA]
      RewriteRule ^([^.]+)$ $1.html [QSA]

      # no, so we redirect to our front web controller
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^(.*)$ index.php [QSA,L]
    </IfModule>
    # ------------- END REWRITE -------------
    
    # ------------- DEFLATE -------------
    # http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
    <IfModule mod_deflate.c>
      SetOutputFilter DEFLATE
      BrowserMatch ^Mozilla/4 gzip-only-text/html
      BrowserMatch ^Mozilla/4\.0[678] no-gzip
      BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
      SetEnvIfNoCase Request_URI \
      \.(?:gif|jpe?g|png)$ no-gzip dont-vary
      Header append Vary User-Agent env=!dont-vary
    </IfModule>
    # ------------- END DEFLATE -------------
  </Location>

  # ------------- EXPIRES RULE -------------
  # http://httpd.apache.org/docs/2.0/mod/mod_expires.html
  <IfModule mod_expires.c>
    ExpiresActive On

    ExpiresByType text/css "access plus 7 days"
    ExpiresByType application/javascript "access plus 7 days"
    ExpiresByType image/gif "access plus 7 days"
    ExpiresByType image/jpeg "access plus 7 days"
    ExpiresByType image/png "access plus 7 days"
  </IfModule>
  # ------------- END REWRITE RULE -------------
  
</VirtualHost>

J’espère que ces petites optimisations pourront vous servir un jour. N’hésitez pas à me faire des remarques et éventuellement me communiquer d’autres astuces Apache/symfony.

Share

InstantClient 10 compatible snow leopard 10.6

Bonne nouvelle pour les utilisateurs d’Oracle. Le projet MacPorts a rendu la version InstantClient 10 compatible 64 bits pour l’installation sur snow leopard. Voici donc la marche à suivre pour son installation.

Pour être sur d’avoir les dernières sources, nous allons au préalable faire une mise à jour de l’arbre de MacPorts:

sudo port selfupdate

Première chose, nous allons télécharger la version d’InstantClient 10 directement sur le site d’Oracle en cliquant ici.
Récupérer les paquets suivants:

instantclient-basic-10.2.0.4.0-macosx-x64.zip
instantclient-sdk-10.2.0.4.0-macosx-x64.zip

La démarche suivante consiste à copier ces 2 paquets dans le projet MacPorts à l’emplacement suivant:

 /opt/local/var/macports/distfiles/oracle-instantclient

Dès que vous aurez déplacé ces paquets au bon endroit, il ne vous reste plus qu’à les installer

port install oracle-instantclient

Nous allons insérer la ligne suivante dans le profile (/etc/profile).

export DYLD_LIBRARY_PATH=/opt/local/lib/oracle

Nous allons également insérer ce path dans la configuration apache en ajoutant la ligne ci-dessous dans le fichier envvars se trouvant dans /opt/local/apache2/bin:

...
export DYLD_LIBRARY_PATH="/opt/local/lib/oracle"

Pour finir, nous allons installer l’interface pour php

port install php5-oracle

Il ne reste plus qu’à relancer apache pour que le tout soit pris en compte

sudo /opt/local/apache2/bin/apachectl stop
sudo /opt/local/apache2/bin/apachectl start

J’utilise le stop/start pour vraiment vider les choses en mémoire.

Bonne découverte.

Share

Installation de mon environnement de développement web avec MacPorts

Ayant reçu mon nouveau portable Macintosh, je me suis posé la question suivante: « Faut-il tout recompiler mes éléments ou les installer avec macports ? ». J’ai décidé de choisir la seconde solution pour me faciliter les choses. Je vais vous détailler ci-dessous l’installation des éléments suivants:

  • MacPorts
  • Apache
  • Subversion et dav_svn
  • MySql
  • php

1. MacPorts
Vous trouvez l’installeur directement sur le site web macports. Vous avez plusieurs possibilités offertes. Il vous suffit de lire la page install du site.

2. Installation du serveur Apache

sudo port install apache2

Démarrage du serveur:

sudo /opt/local/apache2/bin/apachectl start

Pour lancer automatiquement le serveur au démarrage, il suffit de lancer la commande suivante:

sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist

Il ne reste plus qu’à changer votre configuration en éditant le fichier httpd.conf.
Dans mon cas, j’ai décidé de mettre mon dossier root à la racine de mon disque (/www).
Nous en avons fini avec l’installation d’apache 😉

3. Installation de Subversion et dav_svn
J’ai décidé d’installer un serveur subversion directement sur ma machine pour pouvoir stocker le suivi des changement dans mes projets. Si vous ne voulez pas le faire, il suffit de supprimer l’option « +mod_dav_svn ».

sudo port install subversion +mod_dav_svn

Après l’installation des éléments, il nous suffit de charger le module dav avec la commande apxs:

cd /opt/local/apache2/modules
sudo /opt/local/apache2/bin/apxs -a -e -n "dav_svn" mod_dav_svn.so

L’installation est toujours aussi simple.

4. Installation de MySql

sudo port install mysql5-server

Installation des bases nécessaires à MySql:

sudo -u mysql mysql_install_db5

Démarrage du serveur:

sudo /opt/local/lib/mysql5/bin/mysqld_safe &

Configuration de mysql:

sudo /opt/local/lib/mysql5/bin/mysql_secure_installation

Pour lancer automatiquement le serveur au démarrage, il suffit de lancer la commande suivante:

sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql5.plist

Je vais maintenant personnaliser un peu mon installation pour fixer les paramètres par défaut. Pour cela , je vais créer un fichier my.cnf dans le dossier /etc avec le contenu suivant:

[client]
port=3306
default-character-set=utf8

[mysqld]
port=3306
default-character-set=utf8
collation-server=utf8_unicode_ci
default-collation=utf8_unicode_ci
default-storage_engine = InnoDB
default_table_type = InnoDB

Toujours aucun problème lors de l’installation de MySql.

5. Installation de PHP
Tous les options ci-dessous ne sont pas nécessaires. Vous pouvez choisir uniquement les paquets dont vous avez besoin.

sudo port install php5
sudo port install php5-curl php5-gd php5-iconv php5-imap php5-mbstring php5-mcrypt php5-mysql php5-sockets php5-solr php5-sqlite php5-tidy php5-zip

Nous allons choisir notre fichier php.ini. Comme je suis sur une machine de dev, je vais choisir le php.ini-dist

sudo cp /opt/local/etc/php5/php.ini-development /opt/local/etc/php5/php.ini

J’ai également changé quelques paramètres dans mon fichier php.ini:

short_open_tag = Off
post_max_size = 50M
magic_quotes_gpc = Off
upload_max_filesize = 50M
;extension_dir = "./" (ligne commentée)
pdo_mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
date.timezone = Europe/Zurich

Il ne reste plus qu’à charger le module php dans apache:

cd /opt/local/apache2/modules
sudo /opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so

Si vous désirez de la couleur en ligne de commande php, vous devez ajouter un module additionnel:

sudo port install php5-posix

Dès à présent, vous retrouverez des commandes sexy 😉

6. Configuration Apache
Pour qu’Apache prenne en compte les extensions .php et .phps, nous allons inclure la ligne suivante dans le fichier httpd.conf

Pour charger la configuration des virtualhosts, il faut activer la ligne suivante:

Include conf/extra/httpd-vhosts.conf

Pour charger la configuration php, il faut ajouter la ligne suivante:

Include conf/extra/mod_php.conf

Dans le fichier httpd-vhosts.conf, j’ai laissé uniquement les choses suivantes:

NameVirtualHost *:80
Include conf/vhosts/*.conf

Nous pouvons maintenant créer le dossier vhosts dans le dossier conf d’apache pour y mettre nos fichiers domaines

cd /opt/local/apache2/conf
sudo mkdir vhosts
cd vhosts

Dans mon cas, j’ai choisi de mettre tous les fichiers des divers virtualhosts dans le dossier /www/vitualhosts/ à la racine de mon disque:

cd /
sudo mkdir -p /www/virtualhosts
chmod -R 777 /www

J’ai ensuite réaliser le virtualhost « default »:

cd /www/virtualhosts
mkdir default
chmod 777 default
cd /opt/local/apache2/conf/vhosts
touch default.conf

Voici le contenu de mon virtualhost « default »

<VirtualHost *:80>
  ServerName macbookpro.local
  DocumentRoot /www/virtualhosts/default
  DirectoryIndex index.php
  
  <Directory "/www/virtualhosts/default">
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>

Remarque: macbookpro.local est le nom défini dans les préférences réseau

J’utilise ce domaine « default » par exemple, pour y mettre mon phpmyadmin.

Vous êtes maintenant prêt pour réaliser vos propres virtualhosts. Tous vos configurations localisées dans le dossier vhosts seront chargées au prochain redémarrage d’apache.

7. Optionnel
Modules additionnels pour php:

sudo port install php5-apc
sudo port install php5-xdebug

Dans mon domaine d’activités professionnelles, j’utilise également un client yaz qui est lui aussi interfaçable avec php:

sudo port install php5-yaz

Voilà. Mon installation est terminée. N’hésitez pas à me poser des questions avec le formulaire ci-dessous.

Share