Configurer une base de données pour votre application

Ce tutoriel vous guidera à travers les étapes pour configurer une base de données PostgreSQL pour votre application sur la plateforme Atlas.

Prérequis

Vue d'ensemble

Atlas propose deux types d'implémentations pour les bases de données PostgreSQL :

  1. CNPG (CloudNativePG) : Déploiement dans le cluster Kubernetes, adapté pour les environnements de développement et de test.
  2. Managed (OVH) : Cluster de base de données managé, recommandé pour les environnements de production.

Étapes pour configurer une base de données

1. Cloner le dépôt GitOps de votre workspace

1
2
git clone <URL du dépôt de votre workspace>
cd <nom du dépôt>

2. Créer un fichier de définition pour le DatabaseCluster

Créez un nouveau fichier YAML dans le dossier resources du dépôt. Nommez-le de manière significative, par exemple ma-db-dev.yaml.

1
2
mkdir -p resources
touch resources/ma-db-dev.yaml

3. Définir la configuration du DatabaseCluster

Ouvrez le fichier ma-db-dev.yaml dans votre éditeur préféré et ajoutez la configuration appropriée selon le type d'implémentation que vous souhaitez utiliser.

Option 1 : Configuration CNPG (pour développement/test)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: workspace.fabrique.social.gouv.fr/v1alpha1
kind: DatabaseCluster
metadata:
  name: ma-db-dev
spec:
  parameters:
    name: "ma-db-dev"
    implementation: "cnpg"
    version: "15"
    diskSize: 10
    replicas: 1
    cnpg:
      resources:
        limits:
          cpu: "500m"
          memory: "512Mi"
        requests:
          cpu: "100m"
          memory: "256Mi"
    zoneRef:
      name: "dev"
    secretDeliveryTargets:
      - kind: "DeploymentTarget"
        name: "mon-app-dev"

Option 2 : Configuration Managed (pour production)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: workspace.fabrique.social.gouv.fr/v1alpha1
kind: DatabaseCluster
metadata:
  name: ma-db-prod
spec:
  parameters:
    name: "ma-db-prod"
    implementation: "managed"
    version: "15"
    diskSize: 80
    replicas: 3
    ovh:
      plan: "essential"
      flavor: "db1-4"
      authorized_ips: []
    zoneRef:
      name: "prod"
    secretDeliveryTargets:
      - kind: "DeploymentTarget"
        name: "mon-app-prod"

Assurez-vous de remplacer : - ma-db-dev ou ma-db-prod par un nom significatif pour votre base de données - mon-app-dev ou mon-app-prod par le nom de votre DeploymentTarget - dev ou prod par le nom de la zone appropriée

4. Pousser les changements vers le dépôt

1
2
3
git add resources/ma-db-dev.yaml
git commit -m "Ajout du DatabaseCluster pour mon application"
git push

5. Vérifier la création du DatabaseCluster

Une fois les changements poussés, ArgoCD détectera automatiquement les modifications et créera le DatabaseCluster. Vous pouvez vérifier l'état de la création dans ArgoCD.

  1. Accédez à ArgoCD via l'interface Atlas
  2. Recherchez l'application correspondant à votre workspace
  3. Vérifiez que le DatabaseCluster a été créé avec succès

6. Format et accès aux informations de connexion

Les informations de connexion à la base de données sont automatiquement livrées au DeploymentTarget spécifié dans secretDeliveryTargets. Le secret est livré dans le format JSON suivant :

1
2
3
4
5
6
7
8
9
{
  "url": "postgresql://username:password@host:port/database",
  "server": "host:port",
  "host": "host",
  "port": "port",
  "username": "username",
  "password": "password",
  "database": "database"
}

Vous pouvez accéder à ces informations de deux façons :

Via Vault

  1. Accédez à Vault via l'interface Atlas
  2. Naviguez vers le chemin correspondant à votre DeploymentTarget
  3. Vous y trouverez les informations de connexion à la base de données

Via les secrets Kubernetes

Les informations de connexion sont également disponibles sous forme de secrets Kubernetes dans le namespace de votre DeploymentTarget. Vous pouvez y accéder dans votre application en montant le secret ou en utilisant les variables d'environnement.

Exemple d'utilisation dans un déploiement Kubernetes :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mon-application
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - name: mon-application
        image: mon-image:latest
        env:
        # Utilisation de l'URL complète
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: ma-db-dev
              key: url
        # Ou utilisation des paramètres individuels
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: ma-db-dev
              key: host
        - name: DB_PORT
          valueFrom:
            secretKeyRef:
              name: ma-db-dev
              key: port
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: ma-db-dev
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: ma-db-dev
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: ma-db-dev
              key: database

7. Utilisation de la base de données dans votre application

Voici quelques exemples d'utilisation de la base de données avec TypeScript :

TypeScript avec pg

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Pool, PoolClient, QueryResult } from 'pg';

// Utilisation directe de l'URL de connexion
const pool1 = new Pool({
  connectionString: process.env.DATABASE_URL
});

// Ou utilisation des paramètres individuels
const pool2 = new Pool({
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT || '5432', 10),
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME
});

// Exemple de requête
interface TimeResult {
  now: Date;
}

async function query(): Promise<void> {
  let client: PoolClient | null = null;
  try {
    client = await pool1.connect();
    const result: QueryResult<TimeResult> = await client.query('SELECT NOW() as now');
    console.log(result.rows[0].now);
  } finally {
    if (client) client.release();
  }
}

TypeScript avec TypeORM

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { createConnection, Connection, Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

// Définition d'une entité
@Entity()
class User {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  name!: string;

  @Column({ unique: true })
  email!: string;

  @Column({ default: () => 'CURRENT_TIMESTAMP' })
  createdAt!: Date;
}

// Connexion à la base de données
async function connectToDatabase(): Promise<Connection> {
  // Utilisation directe de l'URL de connexion
  return createConnection({
    type: 'postgres',
    url: process.env.DATABASE_URL,
    entities: [User],
    synchronize: true, // Ne pas utiliser en production
  });
}

// Ou connexion avec des paramètres individuels
async function connectWithParams(): Promise<Connection> {
  return createConnection({
    type: 'postgres',
    host: process.env.DB_HOST,
    port: parseInt(process.env.DB_PORT || '5432', 10),
    username: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    entities: [User],
    synchronize: true, // Ne pas utiliser en production
  });
}

// Exemple d'utilisation
async function createUser(name: string, email: string): Promise<User> {
  const connection = await connectToDatabase();
  const userRepository = connection.getRepository(User);

  const user = new User();
  user.name = name;
  user.email = email;

  return userRepository.save(user);
}

Bonnes pratiques

  • Utilisez l'implémentation cnpg pour les environnements de développement et de test, et managed pour la production.
  • Pour la haute disponibilité en production, définissez replicas à une valeur supérieure à 1.
  • Ajustez les ressources (CPU, mémoire) et la taille du disque en fonction des besoins de votre application.
  • Limitez l'accès à votre base de données en utilisant le champ authorized_ips pour les bases de données managées.

Que faire ensuite ?

Maintenant que vous avez configuré une base de données, vous pouvez :

  • Utiliser un bucket S3 pour stocker des fichiers
  • Configurer des sauvegardes pour votre base de données
  • Optimiser les performances de votre base de données

Résolution des problèmes courants

Le DatabaseCluster n'est pas créé

  • Vérifiez que vous avez bien poussé les changements vers le dépôt
  • Vérifiez que le fichier YAML est correctement formaté
  • Vérifiez que vous avez les droits nécessaires

Erreur de connexion à la base de données

  • Vérifiez que le DatabaseCluster a été créé avec succès
  • Vérifiez que les secrets ont été correctement livrés au DeploymentTarget
  • Vérifiez que votre application utilise les bonnes informations de connexion
  • Pour les bases de données managées, vérifiez que l'adresse IP de votre application est autorisée

Paramètres d’affichage

Choisissez un thème pour personnaliser l’apparence du site.