배포 문서 한 줄이 AI 기능 전체를 막을 뻔한 이유

새 기능의 코드와 테스트가 모두 준비되어도 데이터베이스 테이블이 운영에 만들어지지 않으면 서비스는 시작할 수 없습니다. 문서 RAG 기능을 배포하는 과정에서 실제 배포 스크립트는 마이그레이션 파일을 적용하고 있었지만, 개발 지침에는 마이그레이션 파일을 만들지 말라고 적혀 있는 불일치를 발견했습니다.

문서의 지시대로 작업했다면 애플리케이션 코드는 배포되어도 RAG 색인 테이블이 존재하지 않아 관련 API 전체가 실패할 수 있었습니다.

이 글은 특정 도구의 사용법보다 문서, 스키마와 배포 명령을 하나의 계약으로 관리해야 하는 이유를 다룹니다.

문서와 실행 파일 중 무엇이 진실일까요?

개발자는 보통 저장소의 안내 문서를 읽고 작업 방식을 결정합니다. 운영 서버는 문서를 읽지 않고 배포 스크립트에 적힌 명령을 실행합니다.

개발 지침: 스키마만 수정하고 마이그레이션 파일은 만들지 않습니다.
배포 스크립트: 저장소에 포함된 마이그레이션 파일만 적용합니다.

두 문장은 각각 자연스럽지만 함께 존재할 수 없습니다. 스키마를 바꿔도 마이그레이션 파일이 생성되지 않고, 배포는 존재하는 파일만 적용하므로 운영 DB에는 아무 변화가 생기지 않습니다.

실행되는 자동화와 문서가 충돌할 때 현재 동작을 보여주는 것은 자동화입니다. 그렇다고 문서를 무시하면 다음 작업자가 같은 실수를 반복합니다. 실제 배포 방식을 확인한 뒤 문서와 절차를 함께 고쳐야 합니다.

개발 DB에서 잘 된다는 사실이 함정입니다

개발 환경에서는 스키마 동기화 명령으로 테이블이 바로 만들어질 수 있습니다. 이 상태에서 애플리케이션을 실행하면 기능도 테스트도 모두 통과합니다.

운영 배포가 마이그레이션 적용 방식이라면 결과는 다릅니다.

단계 | 개발 환경 | 운영 환경
스키마 파일 수정 | 반영 | 아직 반영되지 않음
직접 스키마 동기화 | 테이블 생성 | 실행하지 않음
마이그레이션 파일 | 없어도 동작 | 없으면 변경 사항 없음
애플리케이션 시작 | 정상 | 테이블 조회에서 실패

개발 DB의 현재 상태가 저장소만으로 재현 가능한지 확인해야 하는 이유입니다.

마이그레이션 드리프트란 무엇인가요?

마이그레이션 드리프트는 데이터베이스의 실제 구조와 저장소가 설명하는 변경 이력이 달라진 상태입니다.

예를 들어 개발 DB에는 컬럼이 있지만 해당 컬럼을 만든 마이그레이션 파일이 저장소 어디에도 없다면 다음 문제가 생깁니다.

새 개발 환경을 만들었을 때 같은 구조를 재현할 수 없습니다.

스키마 도구가 정상 컬럼을 불필요한 것으로 판단해 삭제를 제안할 수 있습니다.

운영 DB와 개발 DB에서 서로 다른 오류가 발생합니다.

장애 원인을 코드와 데이터 중 어디서 찾아야 할지 모호해집니다.

드리프트는 당장 서비스를 멈추지 않더라도 다음 변경의 위험을 키우는 기술 부채입니다.

배포 전에 세 가지를 맞춰야 합니다

데이터베이스 변경은 다음 세 가지가 일치해야 완료됩니다.

선언된 스키마: 애플리케이션이 기대하는 테이블과 컬럼입니다.

변경 이력: 빈 데이터베이스에서 현재 구조까지 도달하는 마이그레이션입니다.

배포 명령: 운영에서 변경 이력을 실제로 적용하는 자동화입니다.

스키마 선언 ──생성──> 마이그레이션 파일
↑ │
└──── 검증 <── 배포 명령 ┘

셋 중 하나만 달라도 로컬에서 성공한 변경이 운영에서 실패할 수 있습니다.

안전한 변경 절차

1. 실제 배포 명령을 먼저 확인합니다

README의 설명만 보지 말고 배포 워크플로와 스크립트가 어떤 DB 명령을 실행하는지 확인합니다. 마이그레이션 적용 방식인지, 직접 동기화 방식인지에 따라 필요한 산출물이 달라집니다.

2. 개발 환경에서 마이그레이션을 생성합니다

스키마 변경과 함께 재현 가능한 변경 파일을 만듭니다. 파일에는 테이블 생성, 인덱스와 제약 조건이 의도대로 포함되었는지 확인합니다.

3. 빈 데이터베이스에서 재현합니다

기존 개발 DB는 수동 변경이 섞여 있을 수 있습니다. 새 데이터베이스에 전체 마이그레이션을 적용해 현재 스키마를 만들 수 있는지 확인합니다.

4. 애플리케이션보다 DB 변경을 먼저 적용합니다

새 코드가 새 테이블을 즉시 조회한다면 DB가 준비되기 전에 애플리케이션이 시작되지 않도록 순서를 보장해야 합니다. 하위 호환이 필요한 무중단 배포에서는 확장과 정리 단계를 나누는 전략이 필요합니다.

5. 배포 후 구조와 기능을 확인합니다

마이그레이션 명령의 종료 코드만 보지 말고 필요한 테이블과 인덱스가 존재하는지, 실제 API가 정상 동작하는지 확인합니다.

위험한 복구 방식

운영 장애가 발생했을 때 즉석에서 테이블을 수동 생성하면 빠르게 복구할 수는 있습니다. 하지만 그 변경을 마이그레이션 이력으로 되돌려 놓지 않으면 드리프트가 더 커집니다.

수동 조치가 필요했다면 다음을 기록해야 합니다.

실행한 변경 내용

적용한 환경과 시각

저장소의 어떤 마이그레이션으로 정식 반영했는지

다른 환경에도 같은 조치가 필요한지

복구 명령 자체보다 저장소가 다시 유일한 재현 경로가 되도록 만드는 작업이 중요합니다.

배포 체크리스트

저장소 문서와 실제 배포 스크립트가 같은 방식을 설명하나요?

스키마 변경에 대응하는 마이그레이션 파일이 있나요?

빈 데이터베이스에서 전체 이력을 재현할 수 있나요?

개발 DB에만 존재하는 테이블이나 컬럼이 없나요?

애플리케이션 시작 전에 필요한 DB 변경이 완료되나요?

배포 후 테이블 존재와 핵심 API를 확인하나요?

수동 복구 내역이 정식 마이그레이션으로 반영됐나요?

듀오랩스가 보는 관점

배포 문서는 참고 자료가 아니라 자동화와 사람이 공유하는 운영 계약입니다. 문서가 실제 명령과 다르면 숙련된 개발자도 잘못된 결과를 만들 수 있습니다.

새로운 AI 기능을 안전하게 운영하려면 모델과 프롬프트뿐 아니라 그 기능이 의존하는 데이터 구조가 모든 환경에서 재현되어야 합니다. 코드가 준비된 시점이 아니라 스키마, 변경 이력과 배포 검증이 맞물린 시점에 기능이 완성됩니다.

문서 RAG 구축기 시리즈

27B보다 2.4B가 더 나았던 문서 RAG 모델 선택기

문서 RAG를 관리자와 공개 서비스에 함께 붙인 구조

RAG 검색 임계값을 감으로 정하면 안 되는 이유

로컬에서는 정상인데 운영에서만 깨진 AI 스트리밍

내부 문서를 공개 AI에 연결할 때 필요한 안전장치

데스크톱 AI 화면을 모바일에서 과감히 제거한 이유

배포 문서 한 줄이 AI 기능 전체를 막을 뻔한 이유