이 글에는 제휴 링크(affiliate link)가 포함되어 있습니다. Vultr·DigitalOcean 가입 링크로 가입하시면 추가 비용 없이 크레딧 혜택을 받으실 수 있으며, 블로그 운영에 도움이 됩니다.
프로덕션 데이터베이스를 직접 운영해야 하는 이유
개발할 때는 데이터베이스가 로컬에 있으면 충분했습니다. 하지만 서비스를 실제로 올리면 사용자가 쓴 데이터, 결제 기록, 게시글 전부 서버에 쌓입니다. 서버 디스크가 고장 나거나 누군가 실수로 데이터베이스를 날려버리면 백업이 없으면 복구할 방법이 없습니다. 그래서 프로덕션에서는 데이터베이스를 직접 설치하고 관리해야 합니다.

이 튜토리얼에서는 VPS에 PostgreSQL을 배포하고 보안 설정부터 매일 자동 백업까지 구축하는 전체 과정을 다룹니다. 데이터를 지키는 1인 운영의 핵심입니다.
1. 왜 PostgreSQL인가?
MySQL도 훌륭한 데이터베이스지만 최근 트렌드는 PostgreSQL입니다. SQL 표준을 비교적 충실히 따라 다른 데이터베이스로 옮기기 좋은 편이고, JSON 데이터 타입을 기본 지원해서 REST API 응답을 그대로 저장할 수도 있습니다. 유사 문자열 검색 확장인 pg_trgm은 contrib 패키지(postgresql-contrib)로 제공되어 CREATE EXTENSION pg_trgm으로 켜면 검색 기능을 쉽게 붙일 수 있습니다. 복잡한 쿼리에서 성능이 안정적이고 동시 처리에 강하며, 커뮤니티가 활발해 문제 해결책을 찾기 쉽습니다. 다음 글에서 다루는 Docker Compose에서도 PostgreSQL이 기본 데이터베이스로 쓰입니다.
2. 설치 + 초기 보안
Ubuntu 기준입니다.
sudo apt update
sudo apt install -y postgresql postgresql-contrib
sudo systemctl enable postgresql
sudo systemctl status postgresql
패키지를 설치하면 postgres라는 기본 사용자와 서비스가 자동으로 만들어지고, 재부팅해도 자동으로 시작됩니다. 설치 직후 먼저 살펴볼 것은 기본 postgres 계정입니다. 기본 설치에서는 postgres 계정이 비밀번호 없이 로컬 peer 인증(운영체제 사용자 postgres)으로만 접속되고 외부 접속은 막혀 있지만, 원격·비밀번호 접속을 쓸 계획이라면 먼저 강한 비밀번호를 지정해야 합니다.
sudo -u postgres psql
-- psql 안에서:
ALTER USER postgres WITH PASSWORD '강력한비밀번호';
\q

3. pg_hba.conf 접근 제어
PostgreSQL의 접근 제어는 pg_hba.conf 파일로 관리합니다. 위치는 /etc/postgresql/{버전}/main/ 안입니다. 로컬 소켓 접속(local 항목)은 기본적으로 peer 인증(운영체제 계정 이름으로 접속)을 쓰고, TCP 접속(host 항목)은 비밀번호 인증을 쓰도록 둡니다. 비밀번호 방식은 md5 대신 scram-sha-256을 권장합니다(PostgreSQL 공식 문서는 md5 방식이 더 이상 권장되지 않는다고 안내합니다).
# /etc/postgresql/16/main/pg_hba.conf
# TCP 접속(host 항목)은 scram-sha-256 비밀번호 인증으로
host all all 127.0.0.1/32 scram-sha-256
host all all 10.0.0.0/24 scram-sha-256 # VPN 대역만 허용
sudo systemctl restart postgresql
4. listen_addresses + 방화벽
listen_addresses 기본값은 localhost만 듣는 것입니다. 외부에서 접속하려면 특정 IP나 인터페이스로 바꿔야 하지만 0.0.0.0으로 열면 모든 IP에서 접속 가능해지므로 위험합니다. 신뢰할 수 있는 IP만 지정하거나, 가장 안전한 방법인 WireGuard VPN 터널을 통해서만 접속하게 합니다.
# /etc/postgresql/16/main/postgresql.conf
listen_addresses = 'localhost,10.0.0.1' # VPN IP만
sudo ufw allow from 10.0.0.0/24 to any port 5432
sudo systemctl restart postgresql
앞서 만든 WireGuard 터널 안으로 접속하면 pg_hba.conf에서 VPN IP 대역만 허용해 외부에서는 접속 자체가 차단됩니다. 원격 접속 테스트:
psql -h 서버VPN_IP -U postgres
5. pg_dump 백업 스크립트
백업이 없으면 데이터베이스를 직접 운영하는 의미가 없습니다. pg_dump가 PostgreSQL의 기본 백업 도구입니다. 전체 데이터베이스를 하나의 파일로 덤프합니다.
#!/bin/bash
# /usr/local/bin/pg-backup.sh
set -euo pipefail
DB_NAME="myapp"
BACKUP_DIR="/mnt/backup/postgres"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/pg-backup.log"
mkdir -p "$BACKUP_DIR"
if pg_dump -Fc "$DB_NAME" -f "$BACKUP_DIR/backup_${TIMESTAMP}.dump"; then
echo "[$(date)] 백업 성공: backup_${TIMESTAMP}.dump" >> "$LOG_FILE"
else
echo "[$(date)] 백업 실패" >> "$LOG_FILE"
fi
# 7일 이상 된 백업 자동 삭제
find "$BACKUP_DIR" -name "backup_*.dump" -mtime +7 -delete
-Fc 옵션은 압축까지 포함하는 커스텀 포맷으로 덤프하고(그래서 gzip을 따로 쓰지 않습니다), 타임스탬프를 파일명에 붙여 겹치지 않게 합니다. 셸 스크립팅 가이드의 패턴(에러 핸들링 + 로그)을 그대로 적용했습니다.

6. cron 자동 백업 + 보관 정책
# /etc/cron.d/pg-backup
# 매일 새벽 3시에 실행
0 3 * * * postgres /usr/local/bin/pg-backup.sh
백업 디렉터리와 로그 파일은 postgres 사용자가 쓸 수 있어야 합니다(예: chown postgres /mnt/backup/postgres). 백업 파일이 계속 쌓이면 디스크를 꽉 채우므로 find -mtime +7로 7일이 지난 파일은 자동 삭제합니다(로테이션). 이렇게 하면 매일 백업이 자동으로 돌고 오래된 건 스스로 정리됩니다.
7. 복원 실습 + pgAdmin
백업이 있으면 복원도 간단합니다. pg_restore로 덤프 파일에서 데이터를 되돌립니다.
createdb -U postgres restore_test
pg_restore -U postgres -d restore_test backup_20260101_030000.dump
큰 데이터베이스면 복원에 시간이 걸리고, 복원 중인 DB는 사용할 수 없으니 유지보수 시간에 하세요. 복원 전에 현재 데이터를 다시 백업해 두는 것도 안전합니다.
pgAdmin은 PostgreSQL의 대표적인 웹 관리 도구입니다. Nginx 리버스 프록시 뒤에 두면 admin.example.com 같은 도메인으로 접근할 수 있고, SQL 쿼리를 웹에서 실행하며 테이블 구조도 시각적으로 볼 수 있습니다. 단, 웹에서 접근 가능하니 반드시 인증과 방화벽을 철저히 해야 합니다.
마무리: 데이터를 지키는 1인 운영
오늘 배운 것을 정리하면: PostgreSQL을 VPS에 설치하고, 기본 보안을 설정하고, pg_dump로 매일 백업이 자동으로 돌게 했으며, 오래된 백업은 자동으로 정리됩니다. 이제 데이터가 사라져도 어제로 되돌릴 수 있습니다. 다음 글에서는 Docker Compose로 웹·DB·캐시 프로덕션 스택을 한 번에 구축합니다.
추천 VPS: 이 튜토리얼은 Vultr(서울 리전, 신규 고객 첫 입금 최대 100달러 매칭), DigitalOcean, Hetzner 어디서나 동일하게 적용됩니다.
자주 묻는 질문 (FAQ)
Q1. MySQL이 아니라 PostgreSQL을 쓰는 이유가 있나요?
SQL 표준을 엄격히 지켜 다른 DB로 옮기기 쉽고, JSON 타입을 기본 지원해 REST API 응답을 그대로 저장할 수 있습니다. 전문 검색 확장 pg_trgm이 내장되어 있고 복잡한 쿼리와 동시 처리에서 성능이 안정적입니다.
Q2. 설치 직후 가장 먼저 해야 할 보안 설정은?
원격 접속을 쓸 계획이라면 postgres 계정에 강한 비밀번호를 지정하는 것입니다. 기본 설치는 비밀번호 없이 로컬 peer 인증으로만 접속되고 외부 접속은 막혀 있습니다. sudo -u postgres psql로 들어가 ALTER USER postgres WITH PASSWORD로 바꾸세요.
Q3. 외부에서 DB에 접속하려면 어떻게 해야 하나요?
listen_addresses를 0.0.0.0으로 열면 모든 IP에서 접속할 수 있어 위험합니다. 신뢰할 수 있는 IP만 지정하거나, WireGuard VPN 터널을 만들고 pg_hba.conf에서 VPN 대역만 비밀번호(scram-sha-256) 인증으로 허용하는 방식이 안전합니다.
Q4. 백업 파일이 계속 쌓이면 디스크가 꽉 차지 않나요?
백업 스크립트 안에서 find “$BACKUP_DIR” -name “backup_*.dump” -mtime +7 -delete로 7일이 지난 파일을 자동 삭제합니다. cron에 매일 새벽 3시로 걸어 두면 백업과 정리가 함께 돌아갑니다.
관련 글
- Docker Compose로 프로덕션 스택 구축 완벽 가이드: 웹+DB+캐시 한 번에 (2026)
- VPS 백업 자동화 완벽 가이드 2026: restic + cron으로 증분 백업 구축
- Ansible Playbook으로 VPS 서버 구성 자동화 완벽 가이드: 10대도 한 번에 (2026)



















