- 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
- 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.
Docker로 Next.js 애플리케이션 구축하기
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로 저장합니다.
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로 지정합니다.services
에db
와app
로 나누어서 설정값을 넣습니다.db
: 데이터베이스 컨테이너이며 이름은db
로 지정했습니다.image
: PostgreSQL의 공식 이미지 postgres:14-alpine를 사용합니다.ports
: PostgreSQL의 포트 번호입니다. 5432:5432로 설정합니다.volumes
: 최상위volumes
에서 만든 볼륨 postgres-data을 컨테이너의 /var/lib/postgresql/data에 연결해줍니다.environment
: PostgreSQL를 실행할 때 사용할 환경 변수를 설정합니다. POSTGRES_PASSWORD와 PGDATA를docker 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_on
에db
를 설정하여 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 공유는 허용합니다.