RSS듀오랩스
데이터베이스

Supabase 풀러 계정 이름: 운영이 두 번 죽은 이유

작성자
듀오랩스 대표·5분 읽기

환경변수의 정본을 볼트로 옮기는 작업이었습니다. 값을 한곳에 모으고, 거기서 배포처로 밀고, 어긋나면 대조로 잡는 구조입니다. 마지막 단계가 운영이었습니다.

밀어넣고 재배포했더니 운영이 500 을 냈습니다. 로그는 이랬습니다.

Error [DriverAdapterError]: (ENOIDENTIFIER) no tenant identifier provided
  (external_id or sni_hostname required)

계정 이름으로 프로젝트를 가르는 풀러

Supabase 의 커넥션 풀러는 여러 프로젝트를 한 엔드포인트로 받습니다. 그래서 접속이 들어오면 "이게 어느 프로젝트냐" 를 먼저 정해야 하는데, 그 판단을 사용자 이름으로 합니다. postgres 가 아니라 postgres.<프로젝트 ref> 형태여야 합니다.

제가 넣은 값은 계정이 그냥 postgres 였습니다. 그래서 풀러가 인증까지 가기도 전에 거절했습니다. 뒤에 나온 다른 로그가 같은 이야기를 더 분명하게 했습니다.

Authentication failed against the database server,
the provided database credentials for `postgres` are not valid

옛 값은 왜 멀쩡했나

여기서 처음에 헷갈렸습니다. 이 서비스는 17일 동안 postgres 라는 계정으로 잘 돌고 있었습니다. 계정 이름이 틀렸다면 그동안에도 죽었어야 합니다.

옛 값이 직결 이었기 때문입니다. db.<ref>.supabase.co 로 데이터베이스에 바로 붙으면 호스트 자체가 프로젝트별이라 계정에 접미사가 필요 없습니다. postgres 가 맞는 값입니다.

바뀐 것은 계정이 아니라 경로 였습니다. 서버리스에서 연결 폭증을 막으려고 런타임을 풀러로 옮겼는데, 풀러는 호스트를 공유하므로 프로젝트를 계정 이름에서 읽습니다. 같은 비밀번호, 같은 데이터베이스인데 앞단이 달라지니 계정 표기가 달라진 것입니다.

이 부분은 제가 자초했습니다. 직결과 풀러가 계정이 다르다고 적어 두고, 정작 값을 만들 때는 직결 쪽 계정을 풀러 URL 에 넣었습니다. 아는 것과 넣는 것이 따로 놀았습니다.

도움이 되지 않은 롤백

운영이 죽었으니 먼저 되돌리려고 이전 배포로 롤백했습니다. 여전히 500 이었습니다.

그때 저는 "Vercel 환경변수는 배포별 스냅샷이 아니라 프로젝트 단위구나" 라고 결론지었습니다. 그 결론은 틀렸습니다.

롤백 대상이 17일 전 배포였는데, 그사이 데이터베이스 비밀번호를 재설정했습니다. 그 배포가 들고 있던 자격증명은 이미 유효하지 않았습니다. 옛 배포가 실패한 이유와 새 배포가 실패한 이유가 서로 달랐는데, 둘 다 500 이라 같은 원인으로 보였습니다.

증상이 같다고 원인이 같지 않습니다. 로그를 두 배포에서 각각 읽었어야 했는데 한 번만 읽고 일반화했습니다.

진짜로 막고 있던 것, 별칭

값을 고치고 다시 배포했는데도 운영 도메인은 계속 500 이었습니다. 그런데 그 배포의 *.vercel.app 주소로 들어가면 화면이 정상으로 떴습니다. 같은 프로젝트, 같은 커밋인데 주소에 따라 결과가 달랐습니다.

롤백이 도메인 별칭을 그 배포에 고정해 두었기 때문입니다. 새 배포가 여러 번 만들어지는 동안 도메인은 계속 롤백이 지정한 옛 배포를 가리키고 있었습니다. 값을 고쳐도, 다시 밀어도, 그 도메인으로는 옛것만 보였습니다.

승격 한 번으로 풀렸습니다.

vercel promote < 배포 URL>

정리하면 저는 고장을 고치는 동안 고장을 하나 더 만들고 있었습니다. 롤백은 코드 사고에는 맞는 도구인데, 이번 사고는 코드가 아니라 값이었습니다. 값이 원인일 때 롤백은 되돌려 주지 않으면서 별칭만 붙들어 둡니다.

아직 설명하지 못하는 것

배포 전에 접속 확인 스크립트를 돌렸고 통과했습니다. 볼트에서 값을 주입해 실제로 붙어 보고, 마이그레이션이 쓰는 어드바이저리 락까지 잡히는 것을 확인했습니다. 그런데 배포하니 같은 자격증명으로 실패했습니다.

검증이 통과한 값과 배포에 들어간 값이 왜 갈렸는지는 아직 모릅니다. 검증 시점과 밀어넣은 시점 사이에 볼트가 바뀌었을 수도 있고, 제가 검증한 경로와 밀어넣는 경로가 다른 것을 읽었을 수도 있습니다. 확인하지 않은 채로 원인을 적어 두면 다음에 같은 데서 또 속습니다.

다음에 다르게 할 것

검증은 배포처에서 합니다. 볼트에서 값을 꺼내 확인한 것은 "볼트에 든 값이 유효하다" 까지만 말해 줍니다. 실제로 배포에 들어간 값이 그것인지는 별개이고, 이번에 갈린 곳이 정확히 거기였습니다.

증상이 같아도 배포마다 로그를 읽습니다. 두 배포가 다른 이유로 같은 코드를 낼 수 있습니다.

값이 원인일 때는 롤백하지 않습니다. 되돌려 주지 않으면서 별칭을 고정해, 뒤에 이어지는 모든 수정이 화면에 안 보이게 만듭니다. 값을 고치고 새로 배포하는 것이 유일한 경로입니다.

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.