Accueil / Articles / Next.js, Tailwind et Prisma avec Docker Postgres

Next.js, Tailwind et Prisma avec Docker Postgres

Étapes par étapes : créer une application Next.js TypeScript, exécuter Postgres dans Docker, configurer Prisma migrate et seed, puis interroger les utilisateurs depuis un composant serveur.

1108 mots

Prérequis

Installez ces outils avant de suivre les étapes :

  • Docker (pour un conteneur Postgres local)
  • Node.js (v16+ recommandé)
  • npm (fourni avec Node)

1) Créer un projet Next.js

Utilisez l’initialisateur officiel et répondez aux questions. Préférez App Router et TypeScript pour cette démarche.

npx create-next-app@latest notes-taking
# choose your options in the interactive prompt (App Router, TypeScript recommended)
cd note-taking

Pour forcer l’utilisation de TypeScript dès la première commande :

npx create-next-app@latest note-taking — ts

2) Ajouter Tailwind CSS (déjà inclus dans Next.js)

Les templates récents de create-next-app intègrent déjà Tailwind lorsque vous l’activez dans les options interactives, il n’est donc pas nécessaire d’installer séparément Tailwind pour un projet neuf qui l’a choisi.

3) Lancer Postgres avec Docker (localement)

Démarrez Postgres dans un conteneur :

docker run — name notes-postgres -e POSTGRES_PASSWORD=password -e POSTGRES_DB=notes_app -p 5432:5432 -d postgres:latest

Sens des flags :

  • docker run — créer et lancer un conteneur
  • --name notes-postgres — nom stable pour les commandes ultérieures
  • -e POSTGRES_PASSWORD=... / -e POSTGRES_DB=... — identifiants de démarrage et base de données
  • -p 5432:5432 — exposer le port sur l’hôte
  • -d postgres:latest — fonctionner en arrière-plan et utiliser l’image Postgres

Vérifier qu’il est en cours d’exécution :

docker ps

Filtrer par image :

docker ps — filter “ancestor=postgres”

Lister tous les conteneurs, y compris ceux arrêtés :

docker ps -a

Filtrer par nom de conteneur :

docker ps — filter “name=notes-postgres”

4) Installer Prisma et les packages associés

Dans la racine du projet Next.js :

npm install prisma tsx — save-dev
npm install @prisma/extension-accelerate @prisma/client

Initialiser Prisma et générer le client dans le dossier app afin que les imports d’App Router restent locaux :

npx prisma init — db — output ../app/generated/prisma

Cela crée un répertoire prisma/ contenant schema.prisma, un fichier .env avec la valeur DATABASE_URL, et (avec l’option --output) un client généré dans app/generated/prisma.

Préférez-vous l’emplacement par défaut du client ? Initialisez sans spécifier d’emplacement personnalisé :

npx prisma init — db and remove — output.

5) Configurer .env (DATABASE_URL)

Pointez DATABASE_URL vers l’instance Docker Postgres :

DATABASE_URL=”postgresql://postgres:password@localhost:5432/notes_app?schema=public”

Modifiez le mot de passe et le nom de la base de données si vous avez choisi d’autres valeurs.

6) Modifier prisma/schema.prisma

Utilisez une paire de modèles User/Post qui correspondra au script de génération ultérieur :

generator client {
provider = "prisma-client-js"
output = "../app/generated/prisma"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id Int @id @default(autoincrement())
name String
email String @unique
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}

Enregistrez le fichier une fois que les modèles sont corrects.

7) Exécuter la migration (créer des tables)

Apliquez la première migration pour créer les tables :

npx prisma migrate dev — name init

Prisma génère du SQL dans le répertoire prisma/migrations pour effectuer ce changement.

8) Semer la base de données

La semaille insère des lignes d’échantillon afin que Prisma Studio et l’application disposent immédiatement de données.

Créez le fichier prisma/seed.ts (ajustez l’import si le chemin de sortie de votre client est différent) :

// prisma/seed.ts
import { PrismaClient, Prisma } from "../app/generated/prisma";

const prisma = new PrismaClient();

const userData: Prisma.UserCreateInput[] = [
  {
    name: "Alice",
    email: "alice@prisma.io",
    posts: {
      create: [
        {
          title: "Join the Prisma Discord",
          content: "https://pris.ly/discord",
          published: true,
        },
        {
          title: "Prisma on YouTube",
          content: "https://pris.ly/youtube",
        },
      ],
    },
  },
  {
    name: "Bob",
    email: "bob@prisma.io",
    posts: {
      create: [
        {
          title: "Follow Prisma on Twitter",
          content: "https://www.twitter.com/prisma",
          published: true,
        },
      ],
    },
  },
];

export async function main() {
  for (const u of userData) {
    await prisma.user.create({ data: u });
  }
}

main();ty

Enregistrez le script de semaille dans package.json :

"prisma": {
"seed": "tsx prisma/seed.ts"
}

Exécutez-le :

npx prisma db seed

Cela insère Alice et Bob ainsi que leurs publications.

9) Ouvrez Prisma Studio

Inspectez et modifiez visuellement les lignes :

npx prisma studio

L’interface du navigateur affiche les modèles et les enregistrements.

10) Créez un enveloppe pour le client Prisma (lib/prisma.ts)

Évitez de créer de nombreuses instances de PrismaClient en phase de développement en utilisant un singleton global ainsi que l’extension accelerate. Créez le fichier lib/prisma.ts :

// lib/prisma.ts
import { PrismaClient } from "../app/generated/prisma"; // adjust path if needed
import { withAccelerate } from "@prisma/extension-accelerate";

declare global {
// allow global prisma across module reloads in dev
// eslint-disable-next-line no-var
var prisma: PrismaClient | undefined;
}

const prisma =
global.prisma ?? new PrismaClient().$extends(withAccelerate());
if (process.env.NODE_ENV !== "production") global.prisma = prisma;

export default prisma;

Pointez l’import vers le chemin du client que vous avez généré, ou utilisez @prisma/client si vous avez omis l’option --output.

11) Tester la connexion à la base de données depuis Next.js (composant serveur)

Exemple de app/page.tsx qui charge les utilisateurs sur le serveur :

import prisma from '@/lib/db'

export default async function Home() {
  const users = await prisma.user.findMany();
  return (
    <div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center -mt-16">
      <h1 className="text-4xl font-bold mb-8 font-[family-name:var(--font-geist-sans)] text-[#333333]">
        Superblog
      </h1>
      <ol className="list-decimal list-inside font-[family-name:var(--font-geist-sans)]">
        {users.map((user) => (
          <li key={user.id} className="mb-2">
            {user.name}
          </li>
        ))}
      </ol>
    </div>
  );
}

Démarrez le serveur de développement de Next.js :

npm run dev

Ouvrez http://localhost:3000 et vérifiez que les utilisateurs préinitialisés s’affichent.

Liste complète des commandes

Créer un projet

npx create-next-app@latest my-app
cd my-app

Docker PostgreSQL

docker run — name notes-postgres -e POSTGRES_PASSWORD=password -e POSTGRES_DB=notes_app -p 5432:5432 -d postgres:latest

docker ps

docker exec -it notes-postgres psql -U postgres

Prisma

npm install prisma tsx — save-dev
npm install @prisma/extension-accelerate @prisma/client
npx prisma init — db — output ../app/generated/prisma

Modifier prisma/schema.prisma

npx prisma migrate dev — name init

Créer prisma/seed.ts

Ajouter l’entrée prisma.seed dans package.json

npx prisma db seed
npx prisma studio
npm run dev

Résolution de problèmes et conseils

  • Impossible de se connecter à Postgres : confirmez le conteneur avec docker ps, puis vérifiez l’hôte et le port de DATABASE_URL. Essayez psql depuis l’hôte ou un autre client en utilisant la même URL.
  • Échecs de migration : consultez les scripts SQL générés par Prisma dans prisma/migrations et assurez-vous que le nom de la base de données correspond à celui indiqué dans .env.
  • Import du client incorrect : régénérez les fichiers après avoir modifié output, ou passez à l’import via @prisma/client si vous utilisez la localisation par défaut.
  • Interface utilisateur vide : relancez l’opération de population des données et assurez-vous que Prisma Studio affiche Alice/Bob avant de déboguer le composant de la page.