Next.js, Tailwind и Prisma с Docker Postgres
Пошагово: создайте приложение Next.js на TypeScript, запустите Postgres в Docker, настройте Prisma migrate и seed, а также выполните запросы к пользователям из компонента сервера.
Предварительные требования
Установите эти инструменты перед тем, как приступить к шагам:
- Docker (для локального контейнера Postgres)
- Node.js (рекомендуется версия v16+)
- npm (предустановлен в Node)
1) Создание проекта Next.js
Используйте официальный инициализатор и отвечайте на вопросы. Для этого руководства рекомендуется использовать App Router и TypeScript.
npx create-next-app@latest notes-taking
# choose your options in the interactive prompt (App Router, TypeScript recommended)
cd note-taking
Чтобы обязательно использовать TypeScript с первой команды:
npx create-next-app@latest note-taking — ts
2) Добавление Tailwind CSS (уже входит в NextJs)
В новейших шаблонах create-next-app Tailwind автоматически подключается, если вы включите его в интерактивных настройках, поэтому для нового проекта с его выбором не требуется отдельная установка Tailwind.
3) Запуск Postgres с помощью Docker (локально)
Запустите Postgres в контейнере:
docker run — name notes-postgres -e POSTGRES_PASSWORD=password -e POSTGRES_DB=notes_app -p 5432:5432 -d postgres:latest
Значения флагов:
- docker run — создание и запуск контейнера
- --name notes-postgres — стабильное имя для последующих команд
- -e POSTGRES_PASSWORD=... / -e POSTGRES_DB=... — установка учетных данных и базы данных
- -p 5432:5432 — обнародование порта на хосте
- -d postgres:latest — работа в фоновом режиме с использованием образа Postgres
Проверьте, что он запущен:
docker ps
Фильтрация по образу:
docker ps — filter “ancestor=postgres”
Список всех контейнеров, включая остановленные:
docker ps -a
Фильтрация по имени контейнера:
docker ps — filter “name=notes-postgres”
4) Установка Prisma и связанных пакетов
Из корневой директории проекта Next.js:
npm install prisma tsx — save-dev
npm install @prisma/extension-accelerate @prisma/client
Инициализация Prisma и создание клиента в папке app, чтобы импорты App Router оставались локальными:
npx prisma init — db — output ../app/generated/prisma
Это создает каталог prisma/ с файлом schema.prisma, файлом .env, содержащим значение DATABASE_URL, а также (при использовании параметра --output) генерированный клиент в каталоге app/generated/prisma.
Хотите использовать стандартное местоположение клиента? Инициализируйте проект без указания пользовательского пути вывода:
npx prisma init — db and remove — output.
5) Настройка файла .env (DATABASE_URL)
Укажите в поле DATABASE_URL адрес экземпляра PostgreSQL в Docker:
DATABASE_URL=”postgresql://postgres:password@localhost:5432/notes_app?schema=public”
Измените пароль и имя базы данных, если вы выбрали другие значения.
6) Редактирование файла prisma/schema.prisma
Используйте пару моделей User/Post, соответствующую скрипту семенования:
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])
}
Сохраните файл, когда структура моделей будет соответствовать требуемой.
7) Запуск миграций (создание таблиц)
Примените первую миграцию для создания таблиц:
npx prisma migrate dev — name init
Prisma генерирует SQL-код в папке prisma/migrations для таких изменений.
8) Заполнение базы данных примерными данными
Этот процесс вставляет примерные строки, чтобы Prisma Studio и приложение сразу имели данные.
Создайте файл prisma/seed.ts (при необходимости скорректируйте импорты в зависимости от пути вывода клиента):
// 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
Зарегистрируйте скрипт заполнения в файле package.json:
"prisma": {
"seed": "tsx prisma/seed.ts"
}
Запустите его:
npx prisma db seed
В результате будут вставлены данные об Алисе и Бобе, а также их записи.
9) Открытие Prisma Studio
Визуально просматривайте и редактируйте строки данных:
npx prisma studio
Интерфейс браузера отображает модели и записи.
10) Создание обертки для клиента Prisma (lib/prisma.ts)
Чтобы избежать создания множества экземпляров PrismaClient во время разработки, используйте глобальный синглтон и расширение accelerate. Создайте файл 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;
Укажите путь к импорту на путь клиента, сгенерированный вами, или используйте @prisma/client, если вы пропустили параметр --output.
11) Проверка подключения к БД из Next.js (серверный компонент)
Пример файла app/page.tsx, который загружает пользователей на сервере:
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>
);
}
Запустите разработческий сервер Next.js:
npm run dev
Откройте http://localhost:3000 и убедитесь, что загружены пользователи из базы данных.
Полный список команд
Создание проекта
npx create-next-app@latest my-app
cd my-app
PostgreSQL в 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
Редактирование файла prisma/schema.prisma
npx prisma migrate dev — name init
Создание файла prisma/seed.ts
Добавление записи prisma.seed в package.json
npx prisma db seed
npx prisma studio
npm run dev
Устранение неполадок и советы
- Невозможно подключиться к Postgres: убедитесь, что контейнер существует с помощью команды
docker ps, затем проверьте хост и порт, указанные вDATABASE_URL. Попробуйте использовать командуpsqlс хоста или другого клиента по тому же URL. - Сбои миграции: прочитайте SQL-код, сгенерированный Prisma в папке
prisma/migrations, и убедитесь, что имя базы данных совпадает с значением в файле.env. - Неправильный импорт клиента: перегенерируйте код после изменения параметра
output, или переключитесь на импорт из библиотеки@prisma/client, если используется стандартное расположение файлов. - Пустой интерфейс: снова запустите процедуру загрузки данных и убедитесь, что в Prisma Studio отображаются данные Alice/Bob, прежде чем начинать отладку компонента страницы.