이재홍의 언제나 최신 Docker - Unit 10.4 Docker Compose로 Next.js와 PostgreSQL 컨테이너 생성하기

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

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

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

Docker Compose로 Next.js와 PostgreSQL 컨테이너 생성하기

docker-compose.yml 파일을 작성하기 전에 Next.js와 PostgreSQL 컨테이너의 docker run 명령을 살펴보겠습니다.

먼저 PostgreSQL 데이터베이스 컨테이너입니다.

~/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 앱 컨테이너입니다.

~/exampleapp$ sudo docker run -d --name app -p 3000:3000 \
    --network nextjs-network \
    -e DATABASE_URL="postgresql://postgres:examplepassword@db:5432/postgres?schema=public" \
    nextjs

이제 이 명령들을 docker-compose.yml로 옮겨보겠습니다. 다음 내용을 ~/exampleapp/docker-compose.yml로 저장합니다.

~/exampleapp/docker-compose.yml
version: '3.8'

services:
  db:
    image: postgres:14-alpine
    ports:
      - 5432:5432
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: examplepassword
      PGDATA: /var/lib/postgresql/data/pgdata
    networks:
      - nextjs-network

  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    command: sh -c "npx prisma db push && npm run start"
    ports:
      - 3000:3000
    environment:
      DATABASE_URL: 'postgresql://postgres:examplepassword@db:5432/postgres?schema=public'
    depends_on:
      - db
    networks:
      - nextjs-network

networks:
  nextjs-network:

volumes:
  postgres-data:
  • networks: Next.js 컨테이너에서 데이터베이스 컨테이너에 연결할 수 있도록 네트워크를 생성합니다. docker network create 명령과 같으며 이름은 nextjs-network로 지정합니다.
  • volumes: 데이터베이스 컨테이너에서 사용할 볼륨을 생성합니다. docker volume create 명령과 같으며 이름은 postgres-data로 지정합니다.
  • servicesdbapp로 나누어서 설정값을 넣습니다.
  • db: 데이터베이스 컨테이너이며 이름은 db로 지정했습니다.
    • image: PostgreSQL의 공식 이미지 postgres:14-alpine를 사용합니다.
    • ports: PostgreSQL의 포트 번호입니다. 5432:5432로 설정합니다.
    • volumes: 최상위 volumes에서 만든 볼륨 postgres-data을 컨테이너의 /var/lib/postgresql/data에 연결해줍니다.
    • environment: PostgreSQL를 실행할 때 사용할 환경 변수를 설정합니다. POSTGRES_PASSWORDPGDATAdocker run과 동일하게 넣어줍니다.
    • networks: 컨테이너가 사용할 네트워크를 지정합니다. 최상위 networks에서 만든 네트워크 nextjs-network를 연결해줍니다.
  • app: Next.js 앱 컨테이너이며 이름은 app으로 지정했습니다.
    • build: Docker Compose로 컨테이너를 생성하면서 이미지를 빌드할 때 사용합니다.
      • context: 빌드할 컨텍스트 디렉터리입니다. 현재 디렉터리 .을 지정합니다.
      • dockerfile: 빌드할 Dockerfile 경로입니다. ./Dockerfile를 지정합니다.
    • command: 컨테이너를 생성할 때 실행할 명령입니다. Prisma로 데이터베이스의 테이블을 생성하기 위해 npx prisma db push를 먼저 실행하고 npm run start로 Next.js 앱을 실행합니다.
    • ports: Next.js의 포트 번호입니다. 3000:3000으로 설정합니다.
    • environment: Next.js 앱을 실행할 때 사용할 환경 변수를 설정합니다. .env 파일에 넣었던 DATABASE_URL를 이곳에 넣어줍니다. 특히 localhost였던 부분을 데이터베이스 컨테이너의 호스트이름인 db로 바꿔줍니다.
    • depends_on: Next.js에서 ORM으로 데이터베이스 테이블을 생성해야 하는데, app 컨테이너가 먼저 생성되면 안 됩니다. 따라서 depends_ondb를 설정하여 db 컨테이너가 생성된 뒤에 app 컨테이너가 생성되도록 합니다.
    • networks: 데이터베이스 컨테이너에 연결할 수 있도록, 최상위 networks에서 만든 네트워크 nextjs-network를 연결해줍니다.

다음 명령을 실행하여 docker-compose.yml에 정의된 컨테이너들을 생성합니다.

$ sudo docker compose up -d
[+] Running 4/4
 ⠿ Network exampleapp_nextjs-network  Created                         1.0s
 ⠿ Volume "exampleapp_postgres-data"  Created                         0.2s
 ⠿ Container exampleapp-db-1          Started                         7.1s
 ⠿ Container exampleapp-app-1         Started                         8.8s

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

다음과 같은 데이터가 표시되면 Next.js 앱 컨테이너와 PostgreSQL 데이터베이스 컨테이너가 정상적으로 생성된 것입니다(새로 고침하면 데이터가 계속 누적되서 표시될 것입니다).

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

이전 Docker Compose 이미지 삭제하기
다른 예제에서 Docker Compose로 생성한 이미지가 있었다면, 이번 예제에서 이전 이미지가 컨테이너로 생성될 수 있습니다. 이때는 이미지를 삭제하거나 이미지를 새로 빌드해줍니다.

다음과 같이 이미지를 삭제합니다.

$ sudo docker rmi exampleapp-app

또는, 다음과 같이 docker compose build 명령으로 이미지를 새로 빌드합니다.

$ sudo docker compose build

컨테이너들을 삭제하려면 docker compose down 명령을 사용하면 됩니다.

$ sudo docker compose down
[+] Running 3/3
 ⠿ Container exampleapp-app-1         Removed                         2.3s
 ⠿ Container exampleapp-db-1          Removed                         2.5s
 ⠿ Network exampleapp_nextjs-network  Removed                         0.8s

만약 데이터베이스 볼륨도 삭제하고 싶다면 docker volume rm 명령을 사용합니다.

$ sudo docker volume ls
DRIVER    VOLUME NAME
local     exampleapp_postgres-data
$ sudo docker volume rm exampleapp_postgres-data

저작권 안내

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

Published

2022-10-03