---
title: "Créer une BDD psql"
description: "Création d'une base de données PostgreSQL pour une nouvelle application"
date: 2025-02-25
dateCreated: 2022-12-22
weight: 12
extra:
  parent: 'operations/deployer.md'
---

## Le besoin

On déploie une application sur l'infra Deuxfleurs, et cette application a besoin de stocker des données dans une base PostgreSQL.

On utilise pour cela le service PostgreSQL existant de Deuxfleurs, déployé en cluster avec [Stolon](@/operations/stolon.md).

Pour mettre en place l'accès nécessaire à cette nouvelle application, nous avons besoin de :

- créer un utisateur pour que l'application puisse se connecter à PostgreSQL
- générer un mot de passe associé
- créer une ou plusieurs bases de données dans PostgreSQL

Ces trois éléments seront ensuite utilisés dans la configuration de l'application.

## Comment ça marche

- **utilisateur et mot de passe :** PostgreSQL est configuré pour
  authentifier les connexions via le LDAP de Deuxfleurs, géré par Bottin.
  Il faut donc créer un nouvel "utilisateur de service" dans le LDAP
  Deuxfleurs (avec un mot de passe associé).

- **base de données :** On crée une base de données pour chaque
  application, et seul l'utilisateur associé a le droit d'accéder à cette
  base.  Cela sépare bien les différentes applications.

- **nom de la base de données :** Cas simple où l'application a besoin
  d'une seule base de données : on lui donne le nom de l'application.  Cas
  complexe avec plusieurs bases : on préfixe par le nom de l'application.
  
- **configuration de l'application :** On veut passer quatre éléments à
  l'application : l'adresse/port du service PostgreSQL, le nom
  d'utilisateur, le mot de passe, et le nom de la base de données.  Les
  applications se configurent généralement soit via des variables
  d'environnement, soit via un fichier de configuration.  Chez Deuxfleurs,
  on stocke les secrets dans Consul, et on utilise des templates pour
  injecter ces secrets dans la configuration de l'application.  Voir dépôt
  nixcfg pour des exemples, ou ici un exemple simple :
  
```
DATABASE_URL=postgres://monapplication:{{ key "secrets/monapplication/postgres_pwd" | trimSpace }}@{{ env "meta.site" }}.psql-proxy.service.prod.consul:5432/monapplication
```

## Etapes de création de l'utilisateur et base de données

### 1. Création de l'utilisateur dans LDAP (méthode automatisée à privilégier)

Voir la page de [secretmgr](@/operations/secretmgr.md)

Gros avantage : le script va également copier les secrets dans Consul, ce qui facilitera la configuration de l'application.

### 1.bis Création de l'utilisateur dans LDAP (méthode manuelle au cas où)

Si la méthode automatique ne convient pas, commencer par générer un mot de passe (sur votre laptop, ou depuis une machine Deuxfleurs, peu importe) :

  1. Générer un mot de passe aléatoire avec la commande `openssl rand -base64 32`
  2. Hasher ce mot de passe avec la commande `slappasswd`

Puis aller sur https://guichet.deuxfleurs.fr :

  1. Il est nécessaire d'être admin Guichet
  2. Trouver l'arbre LDAP des utilisateurs de service `ou=services,ou=users,dc=deuxfleurs,dc=fr`
  3. Créer un nouvel utilisateur dans cet arbre, par exemple `monapplication` (nom de l'application)
  4. Ajouter un champ `userpassword` avec le hash du mot de passe obtenu précédemment

### 2. Se connecter en admin au PostgreSQL de production

Installer le client postgresql (paquet `postgresql-client` sous Debian).

Se connecter en SSH sur une machine de prod en faisant un tunnel vers
`psql-proxy.service.prod.consul:5432` (c'est automatique avec [la
configuration SSH recommandée]
(https://git.deuxfleurs.fr/Deuxfleurs/nixcfg/src/branch/main/doc/onboarding.md))

On peut alors se connecter au serveur PostgreSQL de production :

```bash
psql -h localhost -U postgres -W postgres
```

TODO : demande un mot de passe, où est-il stocké ?


### 3. Créer l'utilisateur et la base de données dans PostgreSQL

Dans le client `psql`, lancer les commandes SQL suivantes.  Il faut adapter le nom de l'application et le nom de la base de données.

```sql
CREATE USER monapplication;
CREATE DATABASE monapplication WITH OWNER monapplication ENCODING 'utf8' LC_COLLATE = 'C' LC_CTYPE = 'C' TEMPLATE template0;
```
