Главная / Статьи / Next.js, Tailwind и Prisma с Docker Postgres

Next.js, Tailwind и Prisma с Docker Postgres

Пошагово: создайте приложение Next.js на TypeScript, запустите Postgres в Docker, настройте Prisma migrate и seed, а также выполните запросы к пользователям из компонента сервера.

1108 слов

Предварительные требования

Установите эти инструменты перед тем, как приступить к шагам:

  • 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, прежде чем начинать отладку компонента страницы.