로컬 개발 환경에서 Docker를 활용해 PostgreSQL을 설치하고 관리하는 방법을 단계별로 정리합니다.
백엔드 개발을 시작할 때 가장 먼저 마주하는 관문 중 하나가 데이터베이스 환경 구축입니다.
PostgreSQL을 로컬에 직접 설치하는 방법도 있지만, Docker를 활용하면 훨씬 깔끔하고 효율적으로 관리할 수 있습니다.
이번 포스팅에서는 Docker를 사용해 PostgreSQL 환경을 구축하는 두 가지 방법을 다룹니다:
데이터베이스를 로컬 시스템에 직접 설치하면 다음과 같은 문제가 발생합니다:
| 문제점 | 설명 |
|---|---|
| 환경 오염 | 시스템에 불필요한 의존성과 설정 파일이 쌓임 |
| 버전 충돌 | 프로젝트마다 다른 DB 버전이 필요할 때 관리가 어려움 |
| 재현성 부족 | "내 컴퓨터에서는 되는데..." 문제 발생 |
| 정리의 어려움 | 완전한 삭제가 까다롭고 잔여 파일이 남음 |
| 팀 협업 | 팀원마다 환경 설정이 달라 디버깅 시간 증가 |
Docker는 컨테이너 기반 격리 환경을 제공하여 위 문제들을 해결합니다:
┌─────────────────────────────────────────────────────┐
│ Host Machine │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Docker Container │ │
│ │ ┌───────────────────────────────────────┐ │ │
│ │ │ PostgreSQL 15 │ │ │
│ │ │ │ │ │
│ │ │ - User: postgres │ │ │
│ │ │ - Database: postgres │ │ │
│ │ │ - Port: 5432 │ │ │
│ │ └───────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
│ ↕ │
│ Port Mapping │
│ localhost:5432 ← → 5432 │
│ ↕ │
│ Volume Mount │
│ ./postgres-data ← → /var/lib/postgresql/data │
│ (영구 데이터 저장) │
└─────────────────────────────────────────────────────┘
터미널에서 Docker가 설치되어 있는지 확인합니다:
# Docker 버전 확인
docker --version
# 예상 출력: Docker version 24.0.x, build xxxxxxx
# Docker Compose 버전 확인
docker-compose --version
# 예상 출력: Docker Compose version v2.x.x
Docker가 설치되어 있지 않다면 Docker 공식 사이트에서 Docker Desktop을 설치하세요.
Docker Desktop이 실행 중인지 확인합니다:
docker info
에러가 발생하면 Docker Desktop 앱을 실행해주세요.
단일 데이터베이스 컨테이너만 필요한 경우, Docker CLI로 충분합니다.
별도의 설정 파일 없이 명령어 한 줄로 PostgreSQL을 실행할 수 있습니다.
docker run -d \
--name crud-api \
-v $(pwd)/postgres-data:/var/lib/postgresql/data \
-p 5432:5432 \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=postgres \
postgres:15
| 옵션 | 값 | 설명 |
|---|---|---|
-d | - | Detached 모드. 백그라운드에서 실행 |
--name | crud-api | 컨테이너 이름 지정. 이후 관리 시 사용 |
-v | $(pwd)/postgres-data:... | 볼륨 마운트. 데이터 영구 저장 |
-p | 5432:5432 | 포트 매핑 (호스트:컨테이너) |
-e | POSTGRES_USER=... | 환경 변수. DB 초기 설정 |
명령어 실행 후 컨테이너가 정상적으로 실행되었는지 확인합니다:
# 실행 중인 컨테이너 목록
docker ps
# 예상 출력:
# CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
# a1b2c3d4e5f6 postgres:15 "docker-entrypoint.s…" Up 10 seconds 0.0.0.0:5432->5432/tcp crud-api
# 컨테이너 중지
docker stop crud-api
# 컨테이너 시작 (중지된 컨테이너)
docker start crud-api
# 컨테이너 재시작
docker restart crud-api
# 컨테이너 로그 확인
docker logs crud-api
# 실시간 로그 확인 (tail -f 처럼)
docker logs -f crud-api
# 컨테이너 삭제 (중지 후)
docker stop crud-api && docker rm crud-api
# 컨테이너 내부 접속
docker exec -it crud-api bash
여러 서비스를 함께 관리하거나, 설정을 코드로 버전 관리하고 싶다면 Docker Compose가 적합합니다.
프로젝트 루트에 docker-compose.yaml 파일을 생성합니다:
version: '3.8'
services:
postgres:
image: postgres:15
container_name: crud-api-db
restart: always
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
| 항목 | 설명 |
|---|---|
version | Docker Compose 파일 형식 버전 |
services | 실행할 서비스(컨테이너) 정의 |
image | 사용할 Docker 이미지 |
container_name | 컨테이너 이름 (선택) |
restart | 재시작 정책. always는 Docker 시작 시 자동 실행 |
volumes | 볼륨 마운트 설정 |
ports | 포트 매핑 |
environment | 환경 변수 |
healthcheck | 컨테이너 상태 체크 설정 |
# 컨테이너 시작 (포그라운드)
docker-compose up
# 컨테이너 시작 (백그라운드, 권장)
docker-compose up -d
# 컨테이너 중지
docker-compose down
# 컨테이너 중지 + 볼륨 삭제 (데이터 초기화)
docker-compose down -v
# 로그 확인
docker-compose logs postgres
# 실시간 로그 확인
docker-compose logs -f postgres
# 컨테이너 상태 확인
docker-compose ps
# 설정 변경 후 재생성
docker-compose up -d --force-recreate
PostgreSQL이 정상적으로 실행되었는지 확인하는 방법들입니다.
pgAdmin에서 새 서버를 추가하고 다음 정보로 연결합니다:
| 항목 | 값 |
|---|---|
| Host | localhost |
| Port | 5432 |
| Username | postgres |
| Password | postgres |
| Database | postgres |
연결 성공 후 좌측 트리에서 데이터베이스와 테이블을 확인할 수 있습니다.
# 컨테이너 내부의 psql로 접속
docker exec -it crud-api psql -U postgres -d postgres
# psql 프롬프트에서 사용할 수 있는 명령어:
# 데이터베이스 목록 확인
\l
# 현재 데이터베이스의 테이블 목록
\dt
# 테이블 구조 확인
\d table_name
# SQL 쿼리 실행
SELECT * FROM your_table;
# psql 종료
\q
psql -h localhost -p 5432 -U postgres -d postgres
어떤 방법을 선택해야 할지 고민된다면 아래 표를 참고하세요:
| 비교 항목 | Docker CLI | Docker Compose |
|---|---|---|
| 적합한 상황 | 단일 컨테이너, 빠른 테스트 | 다중 컨테이너, 팀 협업, 프로덕션 |
| 설정 관리 | 명령어에 직접 포함 | YAML 파일로 분리 |
| 재사용성 | 쉘 스크립트로 저장 필요 | 파일 공유로 즉시 재현 |
| 버전 관리 | 어려움 | Git으로 쉽게 관리 |
| 확장성 | 제한적 | 서비스 추가 용이 |
| 학습 곡선 | 낮음 | 약간 높음 |
볼륨 마운트를 사용하면 컨테이너를 삭제해도 데이터가 유지됩니다.
volumes:
- ./postgres-data:/var/lib/postgresql/data
주의: 볼륨까지 삭제하면 데이터도 사라집니다.
# 볼륨 포함 삭제 (데이터 초기화)
docker-compose down -v
데이터 폴더는 Git에서 반드시 제외합니다:
# Database
postgres-data/
# Environment
.env
민감한 정보는 .env 파일로 분리하여 관리합니다:
docker-compose.yaml
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
.env
DB_USER=postgres
DB_PASSWORD=your_secure_password_here
DB_NAME=myapp_development
이미 5432 포트가 사용 중이라면 다른 포트로 매핑합니다:
ports:
- "5433:5432" # 호스트 5433 → 컨테이너 5432
연결 시 포트를 5433으로 변경해야 합니다.
개발/테스트 환경을 분리하려면 별도의 compose 파일을 사용합니다:
# 개발 환경
docker-compose -f docker-compose.dev.yaml up -d
# 테스트 환경
docker-compose -f docker-compose.test.yaml up -d
Docker를 사용하면 데이터베이스 환경을 코드로 관리할 수 있어,
팀원 누구나 docker-compose up -d 한 줄로 동일한 환경을 즉시 구축할 수 있습니다.
| 상황 | 추천 방법 |
|---|---|
| 빠른 테스트, 혼자 작업 | Docker CLI |
| 팀 협업, 설정 버전 관리 | Docker Compose |
| 여러 서비스 연동 (DB + Redis + ...) | Docker Compose |
이렇게 구축한 PostgreSQL 환경에 실제 애플리케이션을 연결해보세요:
config/development.yaml에서 DB 연결 정보 설정application.yml에서 datasource 설정이 글이 도움이 되셨다면 좋아요와 댓글 부탁드립니다!
궁금한 점이나 오류가 있다면 댓글로 알려주세요.