← 전체 글로 돌아가기

웹 개발

연결 문자열(Connection String) 오류를 배포 전에 잡기

데이터베이스 연결 문자열은 환경마다 다르고, 타이핑 실수가 쉽다. 배포 전에 한 번이라도 테스트해야 한다.

"데이터베이스에 연결할 수 없습니다"는 에러는 보통 연결 문자열 때문이다. 배포 후에 이 에러를 만나면 빠르게 대응하기 어렵다. 배포 전에 확인하는 방법을 정리했다.

연결 문자열의 구성 요소 확인

연결 문자열은 다양한 형식이 있다.

# PostgreSQL
postgres://username:password@host:port/database

# MySQL
mysql://username:password@host:port/database

# MongoDB
mongodb://username:password@host:port/database?authSource=admin

각 부분이 올바른가?

  • username과 password: 특수문자는 URL 인코딩됐는가?
  • host: 로컬 개발에서는 localhost, 배포에서는 실제 서버 주소
  • port: 기본 포트를 썼거나 정말 그 포트가 열려 있는가?
  • database: 데이터베이스 이름이 정확한가?

환경변수 확인

npm run build

빌드할 때 DATABASE_URL 같은 환경변수가 제대로 주입되는가? .env.production에 정의돼 있는가?

로컬에서 먼저 테스트

배포 전에 로컬 개발 환경에서 연결을 테스트한다.

# 로컬 .env.local에 연결 문자열 설정
echo "DATABASE_URL=postgres://user:pass@localhost:5432/testdb" > .env.local

npm run build
npm start

앱이 정상적으로 데이터베이스에 연결되는가?

수동으로 연결 테스트

DB 클라이언트 도구로 직접 연결해본다.

# PostgreSQL
psql "postgresql://user:pass@localhost:5432/testdb"

# MySQL
mysql -h localhost -u user -p password testdb

# MongoDB
mongosh "mongodb://user:pass@localhost:27017/testdb"

연결이 성공하는가? 권한 에러가 나는가?

특수문자 처리

연결 문자열에 특수문자가 있다면, URL 인코딩해야 한다.

# 원래 비밀번호: my@pass#word
# URL 인코딩: my%40pass%23word
postgres://user:my%40pass%23word@localhost:5432/db

Prisma나 다른 ORM은 자동으로 처리하기도 하지만, 명시적으로 하는 게 안전하다.

배포 환경 설정 점검

CI/CD 파이프라인 (GitHub Actions, GitLab CI 등)의 환경변수 설정을 본다.

  • DATABASE_URL 변수가 존재하는가?
  • 값이 실제 데이터베이스 주소와 일치하는가?
  • 비밀번호 같은 민감한 값은 secret으로 관리되는가?

배포 직후 헬스 체크

배포 직후, 앱이 DB에 연결됐는지 확인하는 엔드포인트를 만든다.

app.get('/health/db', async (req, res) => {
  try {
    await db.query('SELECT 1');
    res.json({ status: 'ok', db: 'connected' });
  } catch (err) {
    res.status(500).json({ status: 'error', db: 'disconnected', error: err.message });
  }
});

배포 후 curl https://example.com/health/db로 확인한다.

타임아웃 설정 확인

대용량 데이터베이스나 느린 네트워크에서는 연결 타임아웃이 발생할 수 있다.

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  connectionTimeoutMillis: 5000,  // 5초
  idleTimeoutMillis: 30000,        // 30초
  max: 20,                         // 최대 연결 수
});

필요에 따라 타임아웃을 조정한다.