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.
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 deDATABASE_URL. Essayezpsqldepuis 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/migrationset 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/clientsi 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.