Next.js, Tailwind i Prisma z Dockerem i Postgresem
Krok po kroku: utwórz aplikację Next.js z TypeScript, uruchom Postgres w Dockerze, skonfiguruj Prisma migrate i seed, a następnie wyślij zapytania do użytkowników z komponentu serwerowego.
Wymagania wstępne
Zainstaluj te narzędzia przed przystąpieniem do kroków:
- Docker (do lokalnego kontenera Postgres)
- Node.js (zalecana wersja v16+)
- npm (dołączony do Node)
1) Stwórz projekt Next.js
Użyj oficjalnego narzędzia inicjalizacyjnego i odpowiedz na pytania. W tym przewodniku zaleca się użycie App Router i TypeScript.
npx create-next-app@latest notes-taking
# choose your options in the interactive prompt (App Router, TypeScript recommended)
cd note-taking
Aby od razu użyć TypeScript w pierwszym poleceniu:
npx create-next-app@latest note-taking — ts
2) Dodaj Tailwind CSS (już jest włączony w NextJs)
Nowsze szablony create-next-app automatycznie integrują Tailwind, gdy jest on włączony w opcjach interaktywnych, więc nie ma potrzeby osobistej instalacji Tailwind dla nowego projektu, który go wybrał.
3) Uruchom Postgres za pomocą Dockera (lokalnie)
Zapocznij działanie Postgres w kontenerze:
docker run — name notes-postgres -e POSTGRES_PASSWORD=password -e POSTGRES_DB=notes_app -p 5432:5432 -d postgres:latest
Znaczenie flag:
- docker run — tworzy i uruchamia kontener
- --name notes-postgres — stała nazwa dla późniejszych poleceń
- -e POSTGRES_PASSWORD=... / -e POSTGRES_DB=... — dane logowania i baza danych
- -p 5432:5432 — udostępnianie portu na hostzie
- -d postgres:latest — uruchomienie w tle z użyciem obrazu Postgres
Potwierdzenie działania:
docker ps
Filtrowanie według obrazu:
docker ps — filter “ancestor=postgres”
Wyświetlanie wszystkich kontenerów, włączając te zatrzymane:
docker ps -a
Filtrowanie według nazwy kontenera:
docker ps — filter “name=notes-postgres”
4) Instalacja Prisma i powiązanych pakietów
Z katalogu głównego projektu Next.js:
npm install prisma tsx — save-dev
npm install @prisma/extension-accelerate @prisma/client
Inicjalizacja Prisma oraz umieszczenie klienta w folderze app, aby importy App Router pozostały lokalne:
npx prisma init — db — output ../app/generated/prisma
To tworzy katalog prisma/ zawierający plik schema.prisma, plik .env z wartością DATABASE_URL, a także (przy użyciu opcji --output) wygenerowany klient w katalogu app/generated/prisma.
Czy wolisz domyślną lokalizację klienta? Zainicjuj projekt bez określania własnego miejsca zapisu:
npx prisma init — db and remove — output.
5) Konfiguracja pliku .env (DATABASE_URL)
Ustaw wartość DATABASE_URL na adres instancji Docker Postgres:
DATABASE_URL=”postgresql://postgres:password@localhost:5432/notes_app?schema=public”
Zmień hasło oraz nazwę bazy danych, jeśli wybrałeś inne wartości.
6) Edytowanie pliku prisma/schema.prisma
Użyj pary modeli User/Post, która będzie pasować do późniejszego skryptu siewnego:
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])
}
Zapisz plik, gdy modele będą poprawne.
7) Uruchomienie migracji (tworzenie tabel)
Zastosuj pierwszą migrację w celu utworzenia tabel:
npx prisma migrate dev — name init
Prisma zapisuje SQL w katalogu prisma/migrations dla tej zmiany.
8) Wypełnij bazę danych przykładowymi danymi
Dzięki temu kroku dodawane są przykładowe wiersze, dzięki czemu Prisma Studio oraz aplikacja od razu mają dostęp do danych.
Stwórz plik prisma/seed.ts (zmień import, jeśli ścieżka wyjściowa klienta jest inna):
// 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
Zarejestruj skrypt wypełniania bazy w pliku package.json:
"prisma": {
"seed": "tsx prisma/seed.ts"
}
Zapuść go:
npx prisma db seed
Dzięki temu zostaną dodane Alice i Bob wraz z ich wpisami.
9) Otwórz Prisma Studio
Można wizualnie przeglądać i edytować wiersze:
npx prisma studio
Interfejs przeglądarki pokazuje modele oraz zapisy.
10) Stwórz otoczkę dla klienta Prisma (lib/prisma.ts)
Aby uniknąć tworzenia wielu instancji PrismaClient podczas rozwoju, użyj globalnego singletona oraz rozszerzenia accelerate. Stwórz plik 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;
Wskazz import na utworzoną ścieżkę klienta lub użyj @prisma/client, jeśli pominąłeś parametr --output.
11) Testowanie połączenia z bazą danych w Next.js (komponent serwerowy)
Przykład pliku app/page.tsx, który ładuje użytkowników na serwerze:
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>
);
}
Zainicjuj serwer rozwojowy Next.js:
npm run dev
Otwórz http://localhost:3000 i upewnij się, że wyświetlają się założone użytkownicy.
Pełna lista poleceń
utworzenie projektu
npx create-next-app@latest my-app
cd my-app
postgres docker
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
edycja pliku prisma/schema.prisma
npx prisma migrate dev — name init
utworzenie pliku prisma/seed.ts
dodanie wpisu prisma.seed do package.json
npx prisma db seed
npx prisma studio
npm run dev
Rozwiązywanie problemów i wskazówki
- Nie można połączyć się z Postgres: sprawdź kontener za pomocą
docker ps, a następnie zweryfikuj host i port wDATABASE_URL. Spróbuj użyćpsqlz hosta lub innego klienta pod tym samym adresem URL. - Błędy migracji: przeczytaj SQL wygenerowany przez Prismę w katalogu
prisma/migrationsi upewnij się, że nazwa bazy danych jest zgodna z wartością w pliku.env. - Niewłaściwy import klienta: zregeneruj pliki po zmianie ustawienia
output, albo przełącz się na import z@prisma/client, jeśli używasz domyślnego miejsca przechowywania. - Pusta interfejs użytkownika: uruchom ponownie procedurę seedowania i upewnij się, że w Prisma Studio widnieją postacie Alice/Bob, zanim rozpoczniesz debugowanie komponentu strony.
Literatura pokrewna
- Next.js Server Actions z Prismą i PostgreSQL — Połącz Server Actions bezpośrednio z wspólnym klientem Prisma oraz PostgreSQL, dzięki czemu operacje CRUD nie wymagają tras API ani żądań od klienta.
- Konfiguracja Prismy 7 z Accelerate URLs — Przeanalizuj plik prisma.config.ts, argumenty konstruktora, protokoły accelerateURL oraz dwukrotne ustawienie DATABASE_URL w Prismie 7.
- Wersjonowanie Prismy na v7 w aplikacji Next.js z adaptatorami drivera — ESM, aktualizacje schematu/generatora, plik dotenv, moduły konfiguracyjne oraz tworzenie instancji klienta za pomocą adaptatorów drivera.