이재홍의 언제나 최신 Docker - Unit 10.3 PostgreSQL 데이터베이스 설정하기

저작권 안내
  • 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
  • 책 또는 웹사이트의 내용을 발췌, 요약하여 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.

Docker로 Next.js 애플리케이션 구축하기

이재홍 http://www.pyrasis.com

PostgreSQL 데이터베이스 설정하기

PostgreSQL 데이터베이스 Dockerfile은 따로 작성하지 않고, 공식 이미지인 postgres/14-alpine을 사용하도록 하겠습니다.

다음과 명령으로 네트워크와 볼륨, PostgreSQL 데이터베이스 컨테이너를 생성합니다.

$ cd exampleapp
~/exampleapp$ sudo docker network create nextjs-network
~/exampleapp$ sudo docker volume create postgres-data
~/exampleapp$ sudo docker run -d --name db \
    -p 5432:5432 \
    --network nextjs-network \
    -e POSTGRES_PASSWORD=examplepassword \
    -e PGDATA=/var/lib/postgresql/data/pgdata \
    -v postgres-data:/var/lib/postgresql/data \
    postgres:14-alpine

이번 예제에서는 앞에서 생성한 Next.js 앱의 ORM(Object Relational Mapping)인 Prisma를 사용해서 테이블을 생성해보겠습니다.

다음 명령을 실행하여 exampleapp 디렉터리에서 Prisma 패키지를 설치합니다.

~/exampleapp$ npm install prisma --save-dev

그다음에 npx prisma init을 실행하여 schema 파일을 생성합니다.

~/exampleapp$ npx prisma init

✔ Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.

warn Prisma would have added DATABASE_URL but it already exists in .env
warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.

Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb.
3. Run prisma db pull to turn your database schema into a Prisma schema.
4. Run prisma generate to generate the Prisma Client. You can then start querying your database.

More information in our documentation:
https://pris.ly/d/getting-started

prisma/schema.prisma 파일이 생성되었습니다. 이 파일을 열고 다음과 같이 수정합니다.

~/exampleapp/prisma/schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

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

model User {
  id    Int     @id @default(autoincrement())
  email String?
  name  String?
}

그리고 .env 파일도 함께 생성되는데, 이 파일에는 데이터베이스 접속 정보가 들어있습니다. 이 파일을 열고 다음과 같이 수정합니다.

~/exampleapp/.env
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="postgresql://postgres:examplepassword@localhost:5432/postgres?schema=public"
  • postgresql://<계정>:<암호>@<DB 도메인 또는 IP 주소>:5432/<데이터베이스>?schema=<스키마> 형식입니다.
    • 계정은 기본 계정인 postgres, 암호는 컨테이너를 생성할 떄 설정한 examplepassword를 지정합니다.
    • DB 도메인 또는 IP 주소는 localhost로 지정해서 앞에서 만든 컨테이너에 연결될 수 있도록 합니다.
    • 데이터베이스는 기본값인 postgres, 스키마도 기본값인 public을 지정합니다.

npx prisma db push 명령을 실행하여 schema.prisma 파일의 내용대로 데이터베이스에 테이블을 생성합니다.

~/exampleapp$ npx prisma db push
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "localhost:5432"

🚀  Your database is now in sync with your Prisma schema. Done in 436ms

✔ Generated Prisma Client (4.4.0 | library) to ./node_modules/@prisma/client in 330ms

테이블이 생성되었습니다. 이제 테스트용 데이터를 쓴 뒤 다시 읽어보겠습니다. pages/api/hello.ts 파일을 열고 다음과 같이 수정합니다.

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

type Data = {
  name: string
}

export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
  await prisma.user.create({
    data: {
      name: 'Alice',
      email: 'alice@prisma.io'
    }
  })

  const allUsers = await prisma.user.findMany()

  res.status(200).json(allUsers as any)
}

await가 실행될 수 있도록 function handler 앞에 async를 붙였는지 반드시 확인합니다.

다음 명령으로 Next.js 앱을 실행합니다.

~/exampleapp$ npm run dev

> exampleapp@0.1.0 dev
> next dev

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Loaded env from /home/pyrasis/exampleapp/.env
event - compiled client and server successfully in 1353 ms (173 modules)
wait  - compiling /api/hello (client and server)...
event - compiled successfully in 165 ms (34 modules)

웹 브라우저에서 http://<컨테이너 IP 주소 또는 도메인>:3000/api/hello으로 접속해봅니다(Docker Desktop에서 실행했다면 http://127.0.0.1:3000/api/hello입니다).

다음과 같은 데이터가 표시되면 PostgreSQL 데이터베이스에 정상적으로 데이터를 쓰고 읽어온 것입니다(새로 고침하면 데이터가 계속 누적되서 표시될 것입니다).

[{"id":1,"email":"alice@prisma.io","name":"Alice"}]

확인이 끝났으면 Ctrl+C를 눌러 Next.js 앱을 종료합니다.

그리고 데이터베이스 컨테이너도 삭제합니다.

$ sudo docker rm -f db

저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

2022-10-03