PostgreSQL, tout en étant un SGBDR moderne et polyvalent, n'est pas le plus facile à configurer et à démarrer lorsque vous cherchez à développer une application. Lisez la suite pour savoir comment vous pouvez démarrer avec la dernière version de PostgreSQL sur la version LTS de Ubuntu.
Installation
Ubuntu 18.04 est livré avec PostgreSQL 10, mais nous pouvons à la place utiliser le référentiel APT hébergé par l'équipe PostgreSQL pour installer la dernière version, PostgreSQL 11.
Vous pouvez configurer le référentiel à l'aide de ces commandes :
# add the repository
sudo tee /etc/apt/sources.list.d/pgdg.list <<END
deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
END
# get the signing key and import it
wget https://www.postgresql.org/media/keys/ACCC4CF8.asc
sudo apt-key add ACCC4CF8.asc
# fetch the metadata from the new repo
sudo apt-get update
Et puis installez le logiciel lui-même, en utilisant :
sudo apt-get install postgresql-11
L'installation fait quelques choses :
- Il installe le serveur PostgreSQL, les utilitaires et un client en ligne de commande appelé psql .
- Il crée un utilisateur système Linux appelé postgres . Tous les fichiers de données appartiennent à cet utilisateur et tous les processus s'exécutent sous cet utilisateur.
- Il crée une base de données, également appelée postgres .
- Cela crée un utilisateur PostgreSQL (pas l'utilisateur du système Linux), également appelé postgres .
Vous pouvez voir que cela commence à devenir confus !
Clusters de bases de données
Votre serveur PostgreSQL nouvellement installé se compose d'un ensemble de processus qui gèrent ce qu'on appelle un "cluster de base de données". Vous pouvez voir les processus ici :
alice@devbox:~$ ps axfww | grep postgres
4737 ? S 0:00 /usr/lib/postgresql/11/bin/postgres -D /var/lib/postgresql/11/main -c config_file=/etc/postgresql/11/main/postgresql.conf
4749 ? Ss 0:00 \_ postgres: 11/main: checkpointer
4750 ? Ss 0:00 \_ postgres: 11/main: background writer
4751 ? Ss 0:00 \_ postgres: 11/main: walwriter
4752 ? Ss 0:00 \_ postgres: 11/main: autovacuum launcher
4753 ? Ss 0:00 \_ postgres: 11/main: stats collector
4754 ? Ss 0:00 \_ postgres: 11/main: logical replication launcher
Le processus principal (ici avec le PID 4737) est le processus principal qui engendre ensuite les processus enfants - c'est ce qu'on appelle classiquement le processus "postmaster".
L'utilisation du terme "cluster" par PostgreSQL est antérieure au jargon moderne des clusters distribués - ici, cela signifie simplement un ensemble de bases de données gérées sur une seule machine par un seul postmaster. En savoir plus sur les clusters ici.
Un cluster contient entre autres des bases de données (pour l'instant nous n'en avons qu'une, "postgres") et des utilisateurs PostgreSQL (encore une fois, une seule pour l'instant, également appelée "postgres"). Juste pour que vous le sachiez, le cluster est associé à tout un tas de fichiers de données, qui vivent tous sous un seul répertoire - dans ce cas sous /var/lib/postgresql/11/main . Avez-vous remarqué ce chemin dans la ligne de commande postmaster ci-dessus ?
Lorsque votre application, ou psql, se connecte à Postgres, elle doit le faire dans le contexte d'un utilisateur PostgreSQL. Il y a toujours un utilisateur PostgreSQL associé à une connexion. Mais, comme vous l'avez peut-être déjà deviné, un utilisateur PostgreSQL peut correspondre ou non à un utilisateur système.
Utilisateurs système et utilisateurs PostgreSQL
Les utilisateurs PostgreSQL peuvent être créés à l'aide de commandes SQL telles que CREATE ROLE ou d'outils intégrés tels que createdb.
Lorsqu'une application tente de se connecter à Postgres, elle doit fournir un nom d'utilisateur PostgreSQL. Voyons ce qui se passe lorsque vous lancez un client PostgreSQL comme psql :
alice@devbox:~$ psql
psql: FATAL: role "alice" does not exist
Ici, "alice" est votre nom d'utilisateur système Linux. psql prend ce nom et l'utilise comme nom d'utilisateur Postgres. Un rôle (les rôles sont un nom générique pour "utilisateur" ou "groupe", BTW) de ce nom n'existe pas, c'est ce dont se plaint Postgres.
Nous savons qu'il existe un rôle nommé "postgres", alors essayons cela. Nous pouvons utiliser le paramètre "-U" de psql pour spécifier le nom d'utilisateur :
alice@devbox:~$ psql -U postgres
psql: FATAL: Peer authentication failed for user "postgres"
OK, nous nous rapprochons - le rôle/utilisateur "postgres" existe, mais "peerauthentication" a échoué. Qu'est-ce que cette "authentification par les pairs" ?
Authentification par les pairs et par mot de passe
Les clients PostgreSQL comme psql ou votre application peuvent se connecter au serveur PostgreSQL via l'un de ces mécanismes IPC :
- Sockets de domaine Unix
- Prises TCP
Contrairement aux sockets TCP, les sockets de domaine Unix offrent la possibilité de valider l'ID utilisateur système de la connexion client. Le serveur Postgres peut examiner une connexion entrante sur un socket de domaine Unix et déterminer l'ID utilisateur système du client, puis décider de lui accorder ou non l'accès.
Par défaut, votre serveur n'écoute que les connexions sur les sockets de domaine Unix et non sur TCP/IP.
Voyons ce qui se passe si nous essayons de démarrer psql en tant qu'utilisateur système postgres :
alice@devbox:~$ sudo -u postgres psql
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
Type "help" for help.
postgres=#
Ça a marché! (Utilisez "\q", "\quit" ou ^D
pour quitter psql, BTW.)
Dans l'authentification par les pairs, si la connexion client est établie à l'aide d'un socket de domaine Unix et que le processus client a le même nom d'utilisateur système que l'utilisateur PostgreSQL sous lequel il tente de se connecter, l'authentification est considérée comme réussie.
Les utilisateurs de PostgreSQL peuvent également se voir attribuer un mot de passe en option, et vous pouvez demander à PostgreSQL de valider les connexions entrantes à l'aide du mot de passe. Mais comment? C'est la prochaine pièce du puzzle.
pg_hba.conf
Il est maintenant temps d'ouvrir le (très) célèbre fichier de configuration pg_hba.conf, situé dans /etc/postgresql/11/main/pg_hba.conf
:
sudo vim /etc/postgresql/11/main/pg_hba.conf
HBA signifie authentification basée sur l'hôte. Fondamentalement, ce fichier est utilisé pour contrôler la façon dont les utilisateurs de PostgreSQL sont authentifiés. Ce fichier est probablement la partie la plus non intuitive de la courbe d'apprentissage de PostgreSQL. La documentation de référence est ici, vous devriez la lire plus tard.
La première ligne (sans commentaire) ici est :
local all postgres peer
qui indique à Postgres d'accepter les connexions "locales" (domaine Unix) à "toutes" les bases de données, en s'authentifiant en tant qu'utilisateur "postgres" en utilisant l'authentification "peer". C'est pourquoi la connexion en tant qu'utilisateur système "postgres" fonctionne immédiatement.
L'ordre des lignes dans ce fichier est important, la première ligne correspondante l'emporte. Voyons une autre ligne :
host all all 127.0.0.1/32 md5
Cette ligne permet à "tous" les utilisateurs de se connecter en utilisant TCP/IP ("hôte") depuis l'hôte local ("127.0.0.1/32") vers "toutes" les bases de données, s'ils réussissent à s'authentifier par mot de passe en utilisant la méthode "md5".
Il existe plus de méthodes d'authentification par mot de passe (md5, scram-sha-256, gss, ldap, ...) que nous ne pouvons couvrir, alors revenons à des exemples plus simples.
Mais d'abord, nous devons nous assurer que PostgreSQL accepte également les connexions TCP/IP. Pour cela, nous devons modifier le fichier de configuration principal.
postgresql.conf
Le fichier /etc/postgresql/11/main/postgresql.conf est le fichier de configuration principal de votre cluster PostgreSQL. Ce fichier contient un lot des paramètres, et comprendre ce que tout cela signifie n'est pas une tâche facile du tout. Pour l'instant, voyons le tout premier paramètre :
#listen_addresses = 'localhost'
Cette ligne est commentée par défaut, décommentons-la pour la faire lire :
listen_addresses = 'localhost'
Cela permettra à PostgreSQL d'écouter les connexions TCP/IP entrantes sur localhost, port 5432 (par défaut). Enregistrez les modifications (vous devrez être "root" pour le faire), et redémarrez le serveur Postgres pour que les modifications prennent effet :
sudo systemctl restart postgresql
(Notez que pour la plupart des changements de paramètres, il vous suffit de "recharger", pas de "redémarrer", mais cela nécessite un "redémarrage").
Nous pouvons maintenant voir Postgres écouter sur le port 5432, lié à 127.0.0.1 :
alice@devbox:~$ sudo netstat -tnlp | grep 5432
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 8408/postgres
Configurons maintenant un nouvel utilisateur et une nouvelle base de données à utiliser par une application.
Configuration de l'application
Connectons-nous en tant que superutilisateur "postgres" pour effectuer les modifications :
alice@devbox:~$ sudo -u postgres psql
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
Type "help" for help.
postgres=# create user myapp_user password 's3cr3t';
CREATE ROLE
postgres=# create database myapp owner myapp_user;
CREATE DATABASE
postgres=#
Nous avons maintenant créé une base de données appelée myapp
et un utilisateur appelé myapp_user
,avec le mot de passe s3cr3t
. La base de données est vide et appartiendra à l'utilisateur myapp_user
, ce qui signifie qu'en se connectant en tant que myapp_user
le client pourra exécuter la plupart des commandes DDL/DML.
Connectons-nous maintenant à la base de données de l'application en tant qu'utilisateur de l'application :
alice@devbox:~$ psql -h 127.0.0.1 -d myapp -U myapp_user
Password for user myapp_user:
psql (11.0 (Ubuntu 11.0-1.pgdg18.04+2))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
myapp=>
Ça a marché! Vous êtes maintenant connecté à "myapp" (voir l'invite), en utilisant SSL sur une connexion TCP/IP à 127.0.0.1. Notez que nous avons également spécifié le nom de la base de données sur la ligne de commande pour psql. Pour des raisons historiques, si cela est omis, le nom de la base de données est également supposé être le même que le nom d'utilisateur du système ("alice" ici), ce qui n'est pas ce que nous voulons. Le nom d'utilisateur PostgreSQL est également spécifié ("-U myapp_user").
Si vous avez besoin de vous connecter à partir d'autres machines, vous devrez modifier pg_hba.conf
pour ajouter des lignes comme ceci :
# existing entry, allows connections from localhost
host all all 127.0.0.1/32 md5
# new entry to allow connections from 10.1.2.0/24 subnet,
# only to myapp database for myapp_user
host myapp myapp_user 10.1.2.0/24 md5
et rechargez PostgreSQL ("sudo systemctl reload postgresql") pour que les modifications prennent effet.
Une fois cela en place, vous pouvez désormais utiliser des chaînes de connexion à la base de données comme celles-ci dans vos applications :
# URL format
postgresql://myapp_user:[email protected]/myapp
# connection string format
host=127.0.0.1 user=myapp_user dbname=myapp password=s3cr3t
Prêt !
Cela devrait vous permettre de configurer une base de données dédiée et un utilisateur pour votre application. Votre framework de développement d'application (comme Django, Drupal, etc.) doit être capable de créer des objets (comme des tables, des vues) et de gérer les données dans cette base de données.