Lancer NodeJS comme un service avec Upstart

Il est facile de lancer un serveur web, par exemple, avec NodeJS et une de ces commandes :

  1. La première lance le script web.js en console. Dès que la console est coupée, le script l’est aussi. Ballot.
  2. La seconde permet de garder le script  web.js en arrière-plan, mais si le script cherche à écrire quelque chose sur stdout et que la console est coupée, le script va crasher. Et oui stdout n’existe plus.
  3. La dernière solution est la meilleure des 3 mais en cas de crash ou de redémarrage du serveur, on est obligé de relancer le script à la main.

Mais alors, comment je fais ? Je reste au cul du serveur, à guetter sur htop si mon script disparait pour pouvoir garder un service continu ?

Et non, il y a Upstart !

Upstart est un outil basé sur les évènements et permet de lancer des tâches ou des services pendant un boot, les arrêter quand le serveur s’arrête et pouvoir superviser le service à tout moment.

Comment installer Upstart ?

Si vous êtes sur Ubuntu, il n’y a rien à faire. C’est installé d’origine.
Sinon un classique fera l’affaire :

Configuration de Upstart

Cet outil fonctionne avec des fichiers de configuration qu’il faut placer dans /etc/init/. Voici mon fichier web.conf pour mon serveur web NodeJS:

Voilà rien de bien compliqué. Je vais pas détailler plus, c’est assez simple à comprendre.

Utilisation de Upstart

Maintenant pour lancer son script comme un service c’est super simple. Il suffit d’exécuter:
Pour lancer le service:

Pour arreter le service:

Pour vérifier le statut du service:

Astuce

Si vous voyez celà pendant que vous lancez le service

C’est qu’il y a une erreur dans le fichier de configuration.
Ou que le fichier n’est pas dans /etc/init, ou que le fichier n’est pas web.conf. Mais là c’est que vous n’auriez pas bien suivi le tuto ;).

Side menu avec un storyboard sur IOS 7

Une fonction super à la mode sur les applications mobiles c’est le side menu, comme avec celle de Facebook (seulement sur la droite maintenant), ou Foursquare par exemple.

side_menu

Il existe plusieurs librairies pour faire ça, je ne vais pas m’amuser à recréer la roue. Mais comme j’apprends depuis très peu de temps à développer sur IOS, autant utiliser des outils simples avec lesquels j’ai appris. Et ici je parle surtout de Storyboard, qui diminue assez le temps de développement (surtout quand on apprend).

Du coup la librairie que j’utilise ici c’est ECSlidingViewController , puisqu’elle est compatible avec les storyboards.

Préparation de l’environnement

Version IOS: 7.1
Version Xcode 5.1

Je commence par créer un nouveau projet de type « Single View Application » que je nomme SideMenu.

Ensuite il faut télécharger la librairie directement sur Github et glisser le répertoire ECSlidingViewController directement dans Xcode.

Storyboard

Création de la première vue

Pour commencer nous allons changer le nom du ViewController de base en « FirstViewController » afin que les choses soient plus claires. N’oubliez de changer le nom du fichier .h, .m, les interfaces et les #import et enfin dans le storyboard (partie Identity Inspector, la custom class du ViewController).

Le FirstViewController correspondra à votre première vue comme son nom l’indique.

Afin d’avoir un meilleur environnement j’ajoute un Navigation Controller à mon ViewController. Pour faire ça dans Xcode: Editor > Embed In > Navigation Controller.

Dans l’Identity Inspector du Navigation Controller, remplissez le Storyboard ID avec « FirstViewController ».

Maintenant j’ajoute un UIbutton dans la Navigation Bar de ma FirstViewController que je nomme Menu, comme ceci:

side-menu1

Création du menu

Maintenant nous allons créer le ViewController du menu. Pour cela on ajoute directement un TableViewController (ou autre si vous préférez) dans le storyboard. On ajoute une nouvelle classe héritant de UITableViewController nommé MenuViewController. On lie cette nouvelle classe avec le TableViewController précédemment créée dans la partie Identity Inspector.

Toujours dans l’Identity Inspector remplissez le Storyboard ID avec « MenuViewController ».

A partir de ce moment là je vous laisse personnaliser votre menu (TableView). Pour garder un exemple de fonctionnement simple, j’utilise des cellules statiques que je nomme Page 1, Page 2.

Ajout de la Sliding View

La sliding view c’est la vue qui va créer l’effet de menu glissant contrôlé par la librairie ECSlidingViewController. Visuellement elle n’a rien de particulier.

Pour cela on va ajouter un ViewController dans le storyboard et ajouter les informations importantes dans l’Identity Inspector:

Custom Class: ECSlidingViewController

Et on ajoute des clés/valeurs dans User Defined Runtime Attributes:

underLeftViewControllerStoryboardId    String    MenuViewController
topViewControllerStoryboardId    String     FirstViewController

La librairie utilise une appellation pour définir le menu de gauche (underLeftView) et la vue en cours (topView).

Faites maintenant glisser la flèche correspondant au point d’entrée de votre application vers la SlidingView. C’est elle qui est chargée en première afin de pouvoir contrôler le menu avec le reste des vues.

A ce point nous avons presque fini de mettre en place le menu et toujours pas une ligne de code ;).

Lier le bouton menu au menu

Maintenant pour rendre le bouton menu de notre FirstViewController actif, nous allons utiliser la partie Exit du MenuViewController avec un unwing segue.

Pour cela il est nécessaire de préparer le menu à recevoir un unwing segue. Le début du code, mais ne vous inquiétez pas il n’y a pas grand chose 🙂

Dans l’interface de MenuViewController.h ajoutez:

Et dans MenuViewController.m ajoutez:

Maintenant nous pouvons ajouter la unwind segue dans le storyboard (Ctrl + click sur le bouton menu, glissé vers le exit de MenuViewController).

Votre storyboard devrait maintenant ressembler à ça:

side-menu2

A partir de maintenant vous pouvez déjà tester en compilant votre application. La seule possibilité pour le moment c’est d’ouvrir le menu.

Plus loin avec le menu

Fermer le menu

Maintenant nous allons rajouter une ligne de code pour fermer le menu lorsque l’on tape sur la top view, ou que l’on fait glisser le menu.

Dans un premier temps il nécessaire d’importer la classe UIViewController+ECSlidingViewController.h

Dans le fichier MenuViewController.m ajoutez:

Puis

Voila c’est tout. Le menu se ferme et s’ouvre à volonté.

Lier les cellules du menu

Maintenant il est nécessaire de lier les cellules du menu avec leur NavigationController. Pour cela nous allons retourner sur le storyboard, et créer une transition classique (segue) entre la cellule et le NavigationController correspondant. La segue doit être de type custom.

Dans la partie Attributes Inspector de la segue, ajoutez la segue class ECSlidingSegue. Et voila, rien de bien compliqué.

Vous pouvez maintenant ajouter d’autres vues comme expliqué en première partie, et les linker avec le menu.

Vous pouvez retrouver tout le code sur Github

 

C’est mon premier article sur IOS et ce n’est pas facile d’expliquer les choses avec le Storyboard (cliquer la, remplir ça, glisser ça). J’espère que le tutoriel est suffisamment clair. N’hésitez à faire des commentaires, à expliquer votre façon de faire si vous faîtes différemment.

Contrôle d’accès simple avec CodeIgniter

Une des choses redondantes dans un projet, c’est le contrôle d’accès. Savoir jusqu’où un utilisateur non connecté peut aller, ou même limiter les droits de certains utilisateurs.
Le truc basique c’est de checker soit dans le constructeur du contrôleur, soit dans chaque fonction du contrôleur si l’utilisateur a les droits suffisants pour continuer. Or lorsque le projet atteint une certaine ampleur, il devient vite contraignant et lourd de rajouter ce contrôle à chaque fonction.

Étendre la classe controller

Au début, je pensais créer un hook pre-controller mais toutes les fonctionnalités dont j’avais besoin n’étaient pas chargées. Du coup j’étends la classe controller afin que chaque contrôleur commence par checker l’accès avant d’aller plus loin.

Pour étendre la classe controller il faut créer un fichier /application/core/MY_Controller.php

Préparer les liens accessibles sans connexion

Ici je définis tous les liens ( controleur/fonction ) qui peuvent être accessibles sans connexion. Pour moi c’est plus simple dans ce sens, il est possible de faire l’inverse s’il y a plus d’endroits accessibles sans connexion qu’avec connexion.

Je créé donc un tableau avec les fonctions qui n’ont pas besoin de contrôle d’accès. C’est utile de mettre les fonctions car on peut très bien imaginer une fonction profil dans le contrôleur user, qui aurait besoin d’un contrôle d’accès.

Mise en place du contrôle d’accès

Voila tout est fait.

Explications:

A chaque chargement du contrôleur, on construit l’URI pour n’avoir que le contrôleur et sa fonction. On vérifie à partir de la session si la personne est connectée et si l’url qu’elle demande lui est autorisée. Avec cet exemple simple, un utilisateur non connecté peut accéder qu’aux liens présents dans le tableau. Pour tous les autres il doit être connecté. Lorsque l’utilisateur n’est pas accepté, il est redirigé directement vers l’accueil.

Maintenant c’est bien beau, mais il va falloir modifier chaque contrôleur afin de les étendre à partir de notre nouveau contrôleur de base.

Conseil d’utilisation de ce système:

Si vous n’avez pas du tout besoin du contrôle d’accès dans votre contrôleur, vous créez votre contrôleur normalement ( extends CI_Controller ).

Si au moins une fonction de votre contrôleur a besoin du contrôle d’accès alors vous créez à partir de votre contrôleur étendu ( extends MY_Controller ).

Sauvegarder les mots de passe dans Postgresql avec bcrypt

On voit de plus en plus souvent dans les news, que des bases de données se sont faites hackées, et des gros dumps de mots de passe circulent ainsi dans la nature.

La sauvegarde old school

La manière classique de sauvegarder les mots de passe utilisateur est de les garder en clair de les hasher (md5, sha1, …) avec un salt.

Exemple:

Voila, on récupère ainsi une chaine de caractère illisible. Le problème c’est qu’elle est crackable très très rapidement, puisque les algorithmes de hash rapides, tels que md5 et ceux de la famille SHA, ne sont plus vraiment fiables: voir cet article.

Et oui décrypter un hash en quelques secondes avec les technologies d’aujourd’hui est clairement possible.

La nouvelle façon

Maintenant il existe une approche plus moderne pour faire tout ça avec Postgresql: bcrypt qui fait partie du module pgcrypto.

Attention, si vous avez déjà une application avec des utilisateurs, ils seront obligés de mettre à jour leur mot de passe pour cette nouvelle solution.

Avantages de bcrypt

  • On utilise un algorithme de hash lent (Blowfish)
  • Plusieurs cycles de hash sont exécutés afin de renforcer la sécurité
  • Un salt aléatoire est généré pour chaque mot de passe. Inutile de garder un salt dans son code/BDD et la sécurité est plus accrue.

Mise en place

Modification du type du champ mot de passe (facultatif):

Ajout du module à votre base:

Mise à jour d’un mot de passe pour un utilisateur donné:

Dans la génération du salt, bf correspond à l’algorithme (blowfish) et le chiffre 8 correspond au nombre de passage. Plus le nombre de passage est élevé, plus c’est long et plus c’est sécurisé. Sur la doc de pgcrypto il est conseillé d’avoir une vitesse d’exécution entre 4 et 100 mots de passe par seconde. La vitesse change évidemment suivant la puissance du processeur. Un tableau est aussi disponible, toujours sur la doc afin de comparer les temps d’exécution suivant les différents types d’algorithme avec un même processeur.

Comparer le mot de passe entré par l’utilisateur à celui en base:

Ici le mot de passe en base est utilisé comme salt du mot de passe entré.

Et voila, il n’y a rien de bien compliqué, c’est facile à mettre en place, donc sautez sur l’occasion pour améliorer la sécurité de votre application.

Recherche avec auto-complétion multi-mots et Postgresql

L’auto-complétion multi-mots ? Kézako ? Bon c’est un terme que j’ai un peu inventé (oui je me la raconte ;)), mais je vais vous expliquer la théorie rapidement.

Avec une auto-complétion normale, sur une base importante, on utilise en général like ‘blabla%’. Avec un index sur le champ concerné, les performances sont très correctes, et ce genre de méthode est fréquemment utilisée.

Mon problème: j’aimerai effectuer une recherche auto-complétée à partir de n’importe quel mot d’un titre.

Exemple: Trouver « Tour Eiffel » en tapant « eif ».

Exemple 2: Trouver « Tour Eiffel » en tapant « eiffel to ».

Ceci est impossible avec l’auto-complétion basique. Il faudrait taper « tou » pour trouver ce que l’on veut. De plus, un problème de casse apparait (sauf si l’on utilise ilike).

L’idée alors est de découper tous les titres par mot, et de les rassembler dans une seule et même table. Ceci fonctionne bien mais que pour l’exemple 1.

Pour l’exemple 2, j’utilise en plus le Full Text Search.

Dans la suite de cette article, j’utilise une table film avec pour champs id et titre.

Postgresql 9.1 est utilisé sur une Ubuntu 12.04 LTS.

Formatage des textes

Dans un premier temps j’ai créé une fonction qui me permet de formater tous mes titres sans majuscule, ni accent. Un avantage, l’utilisateur ne sera pas obligé de mettre toutes les majuscules et/ou accents afin de trouver ce qu’il veut.

Création de la fonction dans postgresql:

Si unaccent n’est pas disponible sur votre serveur, il faut installer postgresql-contrib, qui contient plusieurs fonctions d’aide comme unaccent.

Mise en place du Full Text Search

Dans un premier je créé une nouvelle colonne dans ma table film:

Ensuite je remplis la colonne à partir des titres de mes films:

Et pour finir la mise en place de l’index:

On peut d’ores et déjà tester le Full Text Search.

Le Full Text Search est un outil très puissant pour la recherche de mots dans un document. Le problème ici c’est que l’utilisateur est obligé de taper le mot entier pour avoir une réponse. Pas très pratique.

Mise en place de la table de mots

Cette table de mots permet d’avoir une auto-complétion avec n’importe quels mots des titres des films.

On commence donc par créer une nouvelle table:

Puis remplir la table:

Ici la fonction un peu magique c’est regex_split_to_table, qui permet de spliter une chaine de caractères suivant un modèle; ici l’espace et ensuite de créer plusieurs entrées à partir d’une seule.

On rajoutes les index pour que ce soit un minimum efficace:

Et voila le système est mis en place.

On peut tester les 2 systèmes en même temps:

Voila on voit que la requête est exécutée très rapidement. Si je compare cet exemple à l’utilisation de like ‘%mechant%’, la vitesse de résultat n’est pas du tout la même et ne pas être utilisé dans un cas d’auto-complétion.

Maintenant il ne reste plus qu’à intégrer tout ça avec Jquery et PHP.

Intégration

Jquery

J’utilise Jquery UI avec le widget Autocomplete, c’est simple et rapide à mettre en place:

PHP

Et les fonctions pour la recherche en PHP avec Codeigniter comme d’habitude 🙂

Maintenant vous avez tout à votre disposition pour mettre vous aussi en place une auto-complétion multi-mots.

Avantage:

  • Extrêmement performant (testé sur une table de 600 000 titres et un peu plus de 1 100 000 de mots)

Inconvénients:

  • Base de données plus lourde
  • Impossible de trouver « Tour eiffel » si la personne tape « ffel » comme peut le faire like ‘%bla%’

Archivage continu Postgresql avec WAL-E

La sauvegarde de sa base de données est une chose essentielle pour la pérennité de son site. Actuellement je fonctionne sur le principe très basique du dump (pg_dump) de toute ma base de données. Mais cette pratique est loin d’être optimum, et il faut effectuer des dumps assez régulièrement s’il l’on ne veut pas perdre trop de données en cas de crash.

Pour la sauvegarde, il existe un autre moyen avec Postgresql, qui consiste dans un premier temps à enregistrer une sauvegarde complète de la base, et ensuite de ne sauvegarder que les changements apportés à la base sous forme de fichiers WAL. Ainsi « terminé » les gros backups entiers de la base de données, et nous pouvons garder une trace de chaque action effectuée sur la base de données et les rejouer à n’importe quel moment (Point-In-Time Recovery).

Faire des sauvegardes c’est bien, mais faut aussi les sauvegarder quelque part ailleurs que sur le serveur. Sinon en cas de problème avec le disque dur, bye bye la BDD et bye bye les sauvegardes. Et pour cela il existe un très bon outil: Amazon S3. Je ne vais pas détailler ici comment utiliser S3, mais c’est vraiment simple.

Du coup, maintenant nous avons un outil pour effectuer un archivage continu de la base de données, et un outil pour le stockage.

Et il n’existerais pas un outil pour simplifier l’utilisation de ces choses ? Et bien si: WAL-E, à ne pas confondre avec Wall-E 😉

Toute la suite de l’installation se fait sur une Ubuntu 12.04.2 LTS avec Postgresql 9.1.

Installation de WAL-E

On commence avec l’installation des dépendances:

Téléchargement de WAL-E. Pour moi c’est la version 0.6:

Et installation:

Installation de Daemontools

Afin d’exécuter WAL-E dans un environnement sécurisé, nous avons besoin de envdir présent dans la suite Deamontools de D.J. Bernstein.

Préparation:

Téléchargement:

Décompression:

Attention, il est nécessaire de modifier un fichier de configuration afin de pouvoir compiler les daemontools sur Ubuntu.

Modifiez le fichier /package/admin/daemontools/src/conf-cc et ajouter « -include /usr/include/errno.h » à la fin de la première ligne (commande gcc):

Nous pouvons maintenant compiler:

Configuration de WAL-E

Dans un premier temps, nous allons préparer les variables d’environnement nécessaires à l’utilisation de WAL-E. Ces variables sont les informations de connexion à votre S3.

Pour retrouver access-key et secret-key-content, allez ici et connectez-vous.

Nous allons maintenant modifier le fichier /etc/postgresql/9.1/main/postgresql.conf avec les informations suivantes:

J’utilise le chemin entier pour appeler wal-e car sinon la commande ne fonctionne pas.

Il faut maintenant recharger Postgresql afin que la nouvelle configuration soit prise en compte:

Et voila la configuration est terminée !

Sauvegarde complète de la base

Maintenant il est nécessaire de faire un premier backup de votre base de données vers S3, et donc d’exécuter votre première commande WAL-E à partir de l’environnement sécurisé grâce à envdir.

Cela peut prendre quelques secondes à quelques dizaines de minutes en fonction de la taille de votre base de données et de la vitesse d’upload entre votre serveur et Amazon.

A la fin de cette commande, vous devriez trouver 2 nouveaux dossiers dans votre bucket S3. Un dossier pour les backups de base et un dossier pour tous les fichiers WAL.

De nouveaux fichiers WAL sont envoyés très régulièrement vers votre s3.

Restauration des données

Pour récupérer sa base après un crash, il suffit de créer un fichier recovery.conf, qui sera lu au démarrage de Postgresql. Se fichier se place dans /var/lib/postgresql/9.1/main/.

Il est possible de définir dans ce fichier une heure de restauration. Ainsi nous pouvons récupérer l’état de la base à moment bien précis. Si cette variable n’est pas définie, WAL-E essaie de restaurer l’état de la base au plus proche du dernier état.

Vérifier que le fichier recovery.conf appartient bien à postgresql. Sinon:

Maintenant il suffit de démarrer Postgresql

Vous pouvez suivre l’évolution du démarrage à partir des logs:

Une fois la restauration terminée, le fichier recovery.conf devient recovery.done afin d’éviter tout problème en cas de redémarrage du serveur.

Et voilà, votre base a été restaurée.

Créer une nouvelle base de données à partir des sauvegardes

Par exemple pour une machine de développement, il peut être nécessaire de recréer une machine avec une base de données.

Dans un premier temps, il faut bêtement installer Postgresql.

Ensuite supprimer toutes les données présentes dans cette base:

On récupère la dernière version de base avec WAL-E:

Une fois cela terminé, il suffit de reprendre toute la partie Restauration des données, juste au dessus, afin de récupérer la dernière version de la base.

Sauvegarde de base quotidienne

Il est peut être bien d’effectuer une sauvegarde totale de la base tous les jours, afin d’accélérer les remises en production en cas de crash. Ajoutez cette ligne à cron:

Sources:

http://jamesreubenknowles.com/centos5-daemontools-143
https://github.com/wal-e/wal-e
https://gist.github.com/ruckus/2293434

Simple upload en drag and drop avec HTML5 / Jquery / PHP

Il existe actuellement plusieurs plugins qui gèrent les uploads en drag and drop avec HTML5, et avec une pléthore d’options. Mais c’est bien là le problème. Encore un plugin lourd pour effectuer une action simple. Le but ici est de mettre en place un système permettant de télécharger une image sur un serveur, en glissant une image simplement dans une « dropbox » présente sur une page web ; rien de plus.

Posons les bases

Je commence juste par créer la dropbox de base :

Avec son petit code css :

 

Jquery

Je commence par initialiser tous les évènements liés au drag et au drop, afin d’éviter la propagation des évènements.

 

 

Un peu de CSS est rajouté afin d’avoir une petite animation suivant les différents évènements.

Maintenant je m’occupe de l’événement drop, qui va lancer toutes les actions à faire au moment où on va lâcher notre image dans la dropbox.

 

 

La fonction principale pour l’upload de mon image, commence par effectuer un contrôle sur le type de fichier, puis nous utilisons FileReader, un objet d’une API disponible avec HTML5 : File. Cet objet va permettre de lire directement le fichier depuis le navigateur.

La chose importante à comprendre avec la lecture de fichier depuis le navigateur, c’est que le traitement est asynchrone. C’est normal, le temps que la lecture de l’image se fasse, le script continu de tourner.

Je vais donc ordonner l’exécution d’une nouvelle fonction (handleReaderLoad), lorsque l’image sera chargée (reader.onload).

 

 

La fonction handleReaderLoad va s’occuper d’uploader l’image sur le serveur dès que l’image est chargée dans le navigateur.

Rien de bien compliqué ici, c’est juste une requête Ajax avec l’image encodée en Base64.

 

 

Coté PHP

Pour PHP, comme souvent sur ce blog, j’utilise CodeIgniter. Donc voici le contrôleur qui gère le décodage de l’image et qui l’enregistre dans un dossier.

 

 

Voilà avec ce simple code, il est maintenant possible d’envoyer rapidement une image en drag and drop de votre site vers votre serveur, pour une photo de profil par exemple 😉

Afficher les fichiers cachés sous MacOSX

De base tous les fichiers ne sont pas visibles sous Mac-OSX. Afin d’afficher tous les fichiers cachés, il suffit d’ouvrir un terminal de rentrer cet commande:

defaults write com.apple.finder AppleShowAllFiles 1

Et de relancer Finder pour que la commande soit prise en compte:

Menu Pomme –> Forcer à quitter –> Finder –> Relancer

Si vous souhaitez cacher à nouveau les fichiers cachés, entrez cette commande:

defaults write com.apple.finder AppleShowAllFiles 0

et relancer le Finder.

Source

Migration MySQL vers Postgresql

J’ai été amené à effectuer un changement de base de données, et après des journées de recherche/modifications/tests, je suis enfin arrivé à mes fins.

Pourquoi changer de base de données?

C’est vrai que je n’avais aucun problème avec MySQL, mais j’ai découvert PostGIS, un plugin qui transforme Postgresql en base de données spatiale. Et ce plugin très puissant va s’avérer très utile dans mon projet. C’est donc la principale raison qui m’a poussée à migrer.

De plus, le projet n’étant pas encore en production, le changement devait se faire maintenant. Mais des données importantes étaient quand même présentes, et il n’était pas question de juste faire une adaptation de schéma.

Préparation du terrain

Afin d’effectuer le transfert proprement, j’ai utilisé deux machines.

La machine avec MySQL 5.1 qui tourne sous Debian 6.0

La nouvelle machine avec Postgresql 9.1 qui tourne sous Ubuntu 12.04 (Afin d’avoir des paquets plus récents qu’avec une Debian)

Installation basique de la nouvelle machine

Création de la base de données

Posgresql utilise un utilisateur nommé postgres afin d’effectuer toutes les taches d’administration. C’est le superutilisateur.

Afin de protéger cet utilisateur, il est nécessaire de rajouter un mot de passe à celui-ci.

Ensuite nous pouvons nous connecter avec cet utilisateur à l’aide de la commande suivante:

Et accéder à la base de données:

Vous voilà connecté à Postgresql en tant que superutilisateur (un # est présent dans la ligne de commande).

Pour commencer, nous allons créer un utilisateur:

Lui ajouter un mot de passe:

Et lui donner les droits de création de base de données:

Maintenant qu’un utilisateur existe, vous pouvez créer votre première base de données:

Afin de pouvoir vous connecter à la base avec votre nouvel utilisateur, il faut modifier le fichier /etc/postgresql/9.1/main/pg_hba.conf qui gère toutes les connexions à Postgresql.

Dans l’état actuel du fichier, vous êtes obligé d’avoir un utilisateur système du même nom que celui que vous venez de créer pour pouvoir vous connecter. Personnellement je préfère bien scinder les choses.

Il faut donc remplacer la valeur peer par md5 au niveau de la ligne local all all :

La première ligne local all postgres peer doit rester intacte, afin de garder une certaine sécurité. Cette ligne veut dire: « Je peux me connecter à Postgresql avec l’utilisateur postgres que si je suis connecté au système avec le compte postgres ».

Maintenant pour se connecter avec votre utilisateur il suffit de faire:

Maintenant que Postgresql est prêt, nous allons pouvoir commencer la migration.

Création d’un dump propre pour Postgresql

Quand je dis création d’un dump, je ferais mieux de dire créations de plusieurs dumps. Car c’est le plus simple pour éviter les erreurs.

Afin de créer ces dumps, j’ai utilisé un outil qui m’a BEAUCOUP aidé: py-mysql2pgsql

Installation de py-mysql2pgsql

Normalement toutes les dépendances s’installent avec easy_install, si vous rencontrez des problèmes, essayez de les installer manuellement.

Dans un premier temps, il faut générer un fichier de configuration avec la commande:

Le fichier mysql2pgsql.yml est maintenant présent dans le répertoire courant.

Ce fichier est extrêmement simple à comprendre. Il y a une partie pour se connecter à MySQL, une autre pour l’export (soit vers un fichier, soit directement vers Postgresql) et une partie de configuration avancée.

Afin de tout contrôler, je n’utiliserai que l’export vers un fichier durant toute la migration.

Migration du schéma

Certainement la partie la plus délicate de la migration, et c’est ici que py-mysql2pgsql est d’une très grande aide, puisqu’il va convertir tous les types de données qui diffèrent entre MySQL et Postgresql.

Je configure le fichier mysql2pgsql.yml afin de ne récupérer que le schéma:

A vous de remplacer les informations propre à votre connexion à MySQL.

Un fichier schema.sql a maintenant été généré, et il est nécessaire de tout vérifier afin d’éviter les incohérences. Personnellement j’ai dû modifier des types integer qui étaient devenus des bigint.

Une fois le schéma validé, vous pouvez l’ajouter à votre base:

Voila une bonne chose de faite, la structure est en place. Maintenant nous pouvons ajouter les données.

Migration des données

Pour cette partie il faut y aller étape par étape, et ça peut être long.

Je vais ici vous expliquer la méthodologie utilisée plutôt que de faire un tuto puisque chaque cas est différent.

Dans un premier temps j’ai exporté les tables « mères » une par une, de la plus importante à la moins importante. Ce que j’appelle ici table « mère », c’est une table dont vont dépendre d’autres tables via des clés étrangères.

Exemple: Une table personne et une table voiture. Une clé étrangère est présente dans la table voiture afin de savoir à qui appartient cette voiture. La table personne est donc une table mère par rapport à la table voiture. Je dois donc ajouter les données de la table personne avant d’ajouter celles de la table voiture afin d’éviter des erreurs de contrainte. (J’espère être clair sur cette partie, je n’ai peut-être pas le bon vocabulaire).

Pour cela, il faut modifier le fichier mysql2pgsql.yml pour chaque table:

Ensuite, vous pouvez ajouter les données de la table directement dans Postgresql:

Si des erreurs apparaissent, vérifiez les données dans votre base MySQL. Il peut exister des incohérences qui troublent l’import. Cela a été le cas pour moi, une dizaine de lignes sur plus d’un million de lignes. Dans ce cas il faut corriger l’erreur et recommencer l’export avec py-mysql2pgsql jusqu’à temps qu’il n’y ait plus d’erreur.

Une fois que toutes les tables « mères » sont importés dans Postgresql, vous pouvez ajouter les tables restantes en une fois, en utilisant la condition exclude_tables dans le fichier mysql2pgsql.yml, pour exclure les tables déjà ajoutées.

Une fois que tout cela est terminé, la migration commence à se terminer.

Après les imports

Et oui, ce n’est pas encore terminé ! Un certain nombre de choses sont maintenant à vérifier, comme la création/modification de certains index, l’ajout des triggers, de fonctions, etc…

De plus il faut modifier un certain nombre de choses dans le code votre projet, car MySQL et Postgresql n’utilisent pas les mêmes fonctions.

Modifications pour CodeIgniter

Les modifications sont ici relativement simples, et doivent être adaptables pour d’autres frameworks.

Dans un premier temps il faut installer l’extension Postgresql pour PHP:

Et enfin, modifier le fichier /application/config/database.php:

Rien de plus n’est nécessaire pour connecter votre projet à Postgresql.

Sauvegarde de la nouvelle base

Maintenant que tout est propre au niveau de la base Postgresql, n’oubliez pas de faire un dump:

 

CodeIgniter avec Nginx

Depuis un moment je voulais essayer Nginx, puisqu’il est apparemment, bien plus performant qu’Apache. Donc je me suis décidé à passer le pas, et je vais expliquer ici ma démarche.

D’abord je vous conseille de lire cet article (en anglais) qui explique les différences importantes entre Apache et Nginx. Ca permet de savoir où on met les pieds.

Pour cette installation je travaille sur Ubuntu 12.04.2 LTS.

Installation

Dans un premier, il faut arrêter tous les services qui pourrait écouter sur le port 80 (http). Dans mon cas, j’ai besoin de stopper Apache

Ensuite on installe les paquets nécessaires.

Configuration de PHP-FPM

Une petite modification au fichier /etc/php5/fpm/php.ini est nécessaire afin d’empêcher un potentiel risque de sécurité.

Et redémarrer le service

Configuration de Nginx

Créer un fichier « nom_de_votre_domaine » dans /etc/nginx/sites-available et y ajouter ceci

Modifier les valeurs de server_name (votre nom de domaine) et de root (le répertoire où se situe votre site CodeIgniter) afin qu’ils correspondent à votre configuration.

Ajouter le lien symbolique afin d’activer le nouveau site

Recharger Nginx

Et voila, vous devez avoir accès à votre site via Nginx !

Source