vendredi 1 janvier 2010
Comme promis, j'ai dit que j'allais expliquer aujourd'hui comment créer une connexion vers PostgreSQL alors que celui-ci roule sur une machine virtuelle VMware Linux.
Petit récapitulatif :
- Mon poste de travail est Windows XP et je simule un environnement de développement avec EasyPHP (Apache/PHP)
- J'ai désinstallé PostgreSQL de Windows et j'ai transféré le tout sur la VM Ubuntu
- Je veux pouvoir faire une connexion au serveur SQL virtualisé à partir de Windows
J'assumerai que les drivers pour PDO et Postgres sont installés. Vous pourrez vous référer à deux autres billets que j'ai écrit précédemment pour mieux comprendre le contexte et le but de ce changement :
- Utiliser une machine virtuelle comme serveur web
- Transférer une base de données PostgreSQL sur un autre serveur
try{L'adresse IP est celle de la machine virtuelle sur mon réseau local. Je l'ai récupérée en exécutant ifconfig dans un terminal sur la machine virtuelle (voir eth0 / inet addr).
# syntaxe : driver/host/port/dbname, username, password
$dbh = new PDO("pgsql:host=192.168.136.134;port=5432;dbname=code18", "infinite", "loop");
echo "Connexion = OK";
}
catch(PDOException $e){
echo $e;
}
Sans n'avoir rien configuré, j'exécute une première fois le script sur mon poste Windows. Il tente de créer une connexion vers la machine virtuelle (évidemment, elle est démarrée). Un premier message d'erreur apparaît :
PDOException' with message 'SQLSTATE[08006] [7] could not connect to server: Connection refused (0x0000274D/10061) Is the server running on host "192.168.136.134" and accepting TCP/IP connections on port 5432?'
J'ai lancé la commande netstat pour voir quels ports étaient sur écoute et le port 5432 l'était (j'ai installé Postgres de façon standard sur la VM, en utilisant apt-get).
netstat -an | greo "LISTEN "
Pour régler ce problème, il faut se rendre dans les fichiers de configuration de Postgres qui se trouvent dans /etc/postgresql/8.3/main/ sous Ubuntu.
Il faut modifier le fichier postgresql.conf.
sudo nano postgresql.conf
Sous l'entête CONNECTIONS AND AUTHENTICATION, trouvez la ligne suivante :
# listen_addresses = 'localhost'
Retirez le dièse (#) et remplacez 'localhost' par '*' :
listen_addresses = '*'
Redémarrer PostgreSQL pour que le changement prenne effet :
sudo /etc/init.d/postgresql-8.3 restart
En réessayant le script à nouveau, un autre message apparaît :
FATAL: no pg_hba.conf entry for host "192.168.136.1", user "infiniteloop", database "code18"
Ah ? Pourquoi l'adresse IP est 192.168.136.1 ? En fait, c'est parce que cette adresse correspond à l'adresse IP du VMware Network Adapter, la connexion réseau créée automatiquement par VMware lorsque la machine virtuelle a été initialisée la première fois. Trouvez la à partir du menu Start / Settings / Network Connections, choisissez le VMware Network Adapter correspondant. L'adresse IP se trouve sous l'onglet Support.
Il faut autoriser cette adresse IP pour que Postgres accepte la connexion. Ceci se fait par le fichier pg_hba.conf qui se trouve dans le même répertoire que postgresql.conf. Pour des raisons de sécurité, il faut indiquer explicitement quel utilisateur peut accéder à quelle base de données, par quelle adresse IP.
sudo nano pg_hba.conf
À la fin du fichier, ajoutez la ligne ci-dessous, suivant votre configuration (vous devriez voir des exemples de configuration du même type ainsi que la configuration par défaut) :
# Dans l'ordre : Type, Database, User, Cidr-Address, Method
# Séparés par des espaces ou une tabulation
host code18 infinite 192.168.136.1 255.255.255.0 md5
Vous devriez normalement remplacer code18 par le nom de votre base de données et l'adresse IP par la vôtre. Il faut aussi inclure le subnet mask (255.255.255.0) après l'adresse IP.
Redémarrez le serveur Postgres (tel que décrit plus haut).
En testant le script à nouveau, on voit que la connection SQL entre la machine physique et la machine virtuelle se fait correctement.
P.s. je viens de me rendre compte que la date et l'heure de publication de ce billet est binaire ! 10-01-01 11:01. Quand je l'ai vu, ça m'a fait sourire :-)