안녕하세요, 13년 차 하드웨어/소프트웨어 엔지니어이자 기술 블로거입니다. 오늘은 개발자라면 누구나 한 번쯤 겪어봤을 ‘내 컴퓨터에서는 되는데 네 컴퓨터에서는 안돼!’ 문제를 해결해 줄 강력한 도구, Docker Compose를 활용하여 Node.js 애플리케이션과 PostgreSQL 데이터베이스로 구성된 로컬 개발 환경을 구축하는 방법을 공유하고자 합니다. 이 가이드를 통해 개발 환경 설정에 드는 시간을 줄이고, 핵심 개발에 집중할 수 있게 될 것입니다.
1. 왜 Docker Compose로 로컬 개발 환경을 구축해야 할까요? #
전통적인 개발 환경 설정은 많은 시간과 노력을 필요로 합니다. Node.js 런타임 설치, PostgreSQL 데이터베이스 설치, 의존성 관리 등 각 컴포넌트마다 다른 설치 과정을 거쳐야 하며, 버전 충돌이나 운영체제(OS)별 차이로 인해 예측치 못한 문제가 발생하기도 합니다. 특히 팀 프로젝트에서는 각 개발자의 환경이 달라 디버깅에 어려움을 겪는 경우가 빈번합니다.
Docker Compose는 이러한 문제를 해결해 줍니다. 애플리케이션과 그 의존성(데이터베이스, 캐시 등)을 컨테이너화하고, YAML 파일을 통해 이 컨테이너들을 한 번에 정의하고 실행할 수 있도록 합니다. 이는 다음과 같은 이점을 제공합니다.
- 환경 일관성: 모든 팀원이 동일한 개발 환경을 공유하여 “내 컴퓨터에서는 되는데…” 문제를 방지합니다.
- 빠른 설정: 새로운 개발자가 프로젝트에 합류했을 때,
docker-compose up명령 하나로 모든 환경을 구축할 수 있습니다. - 격리성: 각 서비스가 독립된 컨테이너에서 실행되므로, 한 서비스의 변경이 다른 서비스에 영향을 주지 않습니다.
- 쉬운 버전 관리:
docker-compose.yml파일만으로 각 서비스의 버전을 명확히 관리할 수 있습니다.
필자의 경험상, 초기 프로젝트 설정 단계에서 Docker Compose를 도입하면 장기적으로 개발 생산성을 크게 향상시킬 수 있었습니다.
2. Node.js & PostgreSQL 개발 환경 구축을 위한 Docker Compose 설정 #
이제 본격적으로 Docker Compose 파일을 작성하고 Node.js 애플리케이션 및 PostgreSQL 데이터베이스 컨테이너를 정의해 보겠습니다.
2.1 프로젝트 구조 설정 #
먼저 다음과 같은 프로젝트 디렉토리 구조를 만듭니다.
|
|
docker-compose.yml: Docker Compose 설정을 정의하는 파일입니다.node-app/: Node.js 애플리케이션 코드를 포함하는 디렉토리입니다..env: 환경 변수를 관리하는 파일입니다.
2.2 .env 파일 설정
#
데이터베이스 연결 정보와 같은 민감한 정보는 .env 파일에 저장하여 관리하는 것이 좋습니다.
|
|
2.3 node-app/Dockerfile 작성
#
Node.js 애플리케이션을 위한 Docker 이미지를 빌드하는 Dockerfile입니다.
|
|
FROM node:18-alpine: Node.js 18 버전의 Alpine Linux 기반 이미지를 사용합니다. 경량화된 이미지로 컨테이너 크기를 줄일 수 있습니다.WORKDIR /app: 컨테이너 내부의 작업 디렉토리를/app으로 설정합니다.COPY package*.json ./:package.json과package-lock.json파일을 작업 디렉토리로 복사합니다.RUN npm install: Node.js 의존성 패키지를 설치합니다. 이 단계를COPY . .앞에 두면, 소스 코드가 변경되어도node_modules가 재빌드되지 않아 빌드 속도를 높일 수 있습니다.COPY . .: 현재 디렉토리의 모든 파일(Node.js 소스 코드)을/app으로 복사합니다.EXPOSE 3000: Node.js 애플리케이션이 3000번 포트에서 실행됨을 외부에 알립니다.CMD ["node", "server.js"]: 컨테이너가 시작될 때server.js파일을 실행합니다.
2.4 node-app/server.js 작성 (간단한 Node.js 애플리케이션)
#
PostgreSQL에 연결하여 데이터를 저장하고 조회하는 간단한 Node.js 애플리케이션입니다. pg 라이브러리를 사용합니다.
|
|
node-app/package.json 파일도 생성해야 합니다.
|
|
2.5 docker-compose.yml 작성
#
이제 Node.js 애플리케이션과 PostgreSQL 데이터베이스를 함께 실행하기 위한 docker-compose.yml 파일을 작성합니다.
|
|
version: '3.8': Docker Compose 파일 형식 버전을 지정합니다.services: 실행할 서비스들을 정의합니다.app서비스 (Node.js 애플리케이션):build: ./node-app:node-app디렉토리의Dockerfile을 사용하여 이미지를 빌드합니다.ports: - "${NODE_PORT}:${NODE_PORT}": 호스트의NODE_PORT(예: 3000)와 컨테이너의 3000번 포트를 연결합니다..env파일의 변수를 사용합니다.environment: 컨테이너 내부에 전달될 환경 변수들을 정의합니다..env파일의 변수를 참조합니다.depends_on: - db:app서비스는db서비스가 시작된 후에 시작되어야 함을 명시합니다. (이것은 시작 순서만 보장하며,db서비스가 완전히 준비되었음을 보장하지는 않습니다. 실제 프로덕션 환경에서는 헬스 체크를 추가하는 것이 좋습니다.)volumes:- ./node-app:/app: 호스트의node-app디렉토리를 컨테이너의/app디렉토리에 마운트(바인드 마운트)합니다. 이를 통해 호스트에서 코드를 수정하면 컨테이너에 즉시 반영되어 개발 시 편리합니다.- /app/node_modules:node_modules디렉토리는 호스트에 마운트하지 않도록 명시적으로 제외합니다. 컨테이너 내부의node_modules를 사용해야 합니다. 그렇지 않으면 호스트의 OS와 컨테이너의 OS가 달라 의존성 문제가 발생할 수 있습니다.
env_file: - ./.env:.env파일에서 환경 변수를 로드합니다.
db서비스 (PostgreSQL 데이터베이스):image: postgres:15-alpine: PostgreSQL 15 버전의 Alpine Linux 기반 이미지를 사용합니다.ports: - "${PG_PORT}:${PG_PORT}": 호스트의PG_PORT(예: 5432)와 컨테이너의 5432번 포트를 연결합니다.environment: PostgreSQL 컨테이너에 필요한 환경 변수들을 정의합니다.POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB는 데이터베이스 초기 설정에 사용됩니다.volumes: - db_data:/var/lib/postgresql/data:db_data라는 이름의 Docker 볼륨을 생성하고, 이를 PostgreSQL 데이터가 저장되는 컨테이너 내부 경로에 마운트합니다. 이 볼륨을 사용하면 컨테이너가 삭제되어도 데이터는 유지됩니다.env_file: - ./.env:.env파일에서 환경 변수를 로드합니다.
volumes: Docker 볼륨을 정의합니다.db_data는 PostgreSQL 데이터 영속성을 위해 사용됩니다.
2.6 Docker Compose 실행 #
모든 파일 작성을 마쳤다면, 프로젝트 루트 디렉토리에서 다음 명령어를 실행하여 서비스를 시작합니다.
|
|
up:docker-compose.yml파일에 정의된 서비스들을 시작합니다.--build: 이미지가 아직 빌드되지 않았거나Dockerfile이 변경되었을 경우, 다시 빌드하도록 합니다.
백그라운드에서 실행하려면 -d 옵션을 추가합니다.
|
|
컨테이너의 로그를 확인하려면:
|
|
서비스가 정상적으로 실행되면, 웹 브라우저에서 http://localhost:3000에 접속하여 Node.js 애플리케이션을 확인할 수 있습니다.
테스트 절차:
- 브라우저 또는
curl로http://localhost:3000/init에 접속하여 데이터베이스를 초기화하고messages테이블을 생성합니다.1curl http://localhost:3000/init - 새로운 메시지를 저장합니다.
1curl -X POST -H "Content-Type: application/json" -d '{"text": "Hello Docker Compose!"}' http://localhost:3000/messages - 저장된 메시지들을 조회합니다.
1curl http://localhost:3000/messages
2.7 Docker Compose 서비스 중지 및 삭제 #
개발이 완료되거나 서비스를 중지하고 싶을 때는 다음 명령어를 사용합니다.
|
|
down:docker-compose.yml파일에 정의된 서비스들을 중지하고 컨테이너를 제거합니다.
데이터 볼륨까지 완전히 삭제하려면 -v 옵션을 추가합니다.
|
|
이 명령은 db_data 볼륨도 함께 삭제하므로, 데이터가 영구적으로 지워진다는 점에 유의해야 합니다.
3. 결론 및 요약 #
Docker Compose는 Node.js와 PostgreSQL을 포함한 복잡한 로컬 개발 환경을 쉽고 빠르게 구축할 수 있도록 돕는 강력한 도구입니다. 이 글에서 제시된 .env, Dockerfile, docker-compose.yml 파일을 통해 환경 일관성을 확보하고, 개발 생산성을 크게 향상시킬 수 있습니다.
- Docker Compose는 개발 환경의 일관성을 보장하고, 초기 설정 시간을 대폭 단축시킵니다.
- Node.js 애플리케이션과 PostgreSQL 데이터베이스를 컨테이너화하여 독립적으로 관리하고 연동할 수 있습니다.
docker-compose up --build명령 하나로 전체 개발 스택을 간편하게 시작하고 관리할 수 있습니다.
필자의 경험상, 한 번 Docker Compose의 편리함에 익숙해지면 다시는 수동 환경 설정으로 돌아가고 싶지 않을 것입니다. 지금 바로 여러분의 프로젝트에 적용해 보시길 강력히 추천합니다!
