배포 검증이 실제로 잡아야 하는 것
200 을 세는 것은 검증이 아닙니다. 사이트가 200 을 주면서 알맹이만 사라지는 고장이 흔하고, 그 상태는 눈으로도 잘 보이지 않습니다.
이 문서는 그런 고장들과, 배포가 실제로 끝났는지 아는 방법, 그리고 검사 자체가 틀리는 방식을 정리한 것입니다. 마지막 항목이 제일 자주 사람을 속입니다.
200 을 주면서 망가지는 것들
섹션 제목: “200 을 주면서 망가지는 것들”빌드가 실패해도 이전 버전이 살아 있습니다
섹션 제목: “빌드가 실패해도 이전 버전이 살아 있습니다”정적 호스팅은 새 빌드가 실패하면 이전 배포를 계속 서빙합니다. 실패한 배포와 성공한 배포가 똑같이 200 입니다. 주소를 두드려 확인하는 방식으로는 구분할 수 없습니다.
데이터를 못 읽어도 화면은 그려집니다
섹션 제목: “데이터를 못 읽어도 화면은 그려집니다”목록 화면이 데이터베이스를 읽지 못하면 대개 빈 목록으로 응답합니다. 오류 화면이 아니라 “글이 없습니다” 입니다. 글이 열 편 있는데 없다고 말하는 화면이 200 을 줍니다.
빌드 시점에 데이터베이스가 없는 구성이라면 더 조용합니다. 빌드가 빈 목록으로 페이지를 구워 두고, 런타임에 요청이 들어와야 다시 만들어집니다. 트래픽이 없는 사이트에서는 그 빈 버전이 계속 나갑니다.
보안 정책이 기능만 죽입니다
섹션 제목: “보안 정책이 기능만 죽입니다”CSP 를 잘못 세우면 화면은 완벽하게 그려지고 검색이나 테마 전환 같은 기능만 조용히 죽습니다. “문서가 안 보인다” 가 아니라 “검색창에 입력해도 결과가 안 나온다” 라서 알아채기 어렵습니다.
소유확인 파일이 사라집니다
섹션 제목: “소유확인 파일이 사라집니다”검색엔진 소유확인 파일이나 색인 제출 키 파일은 사라져도 화면에 아무 영향이 없습니다. 몇 달 뒤 유입이 끊긴 다음에야 알게 됩니다.
없는 주소가 200 을 줍니다
섹션 제목: “없는 주소가 200 을 줍니다”404 를 줘야 할 자리가 200 을 주면 검색엔진이 빈 페이지를 색인합니다.
배포가 끝났는지 아는 방법
섹션 제목: “배포가 끝났는지 아는 방법”빌드가 자기 커밋을 결과물에 남기게 하면 대조할 수 있습니다. 대부분의 호스팅이 빌드 환경에 커밋 해시를 넣어 줍니다.
// 빌드 뒤에 돈다await writeFile('dist/build-id.txt', process.env.BUILD_COMMIT_SHA ?? gitHead())그러면 검증의 첫 단계가 정해집니다.
- 라이브에서 그 값을 읽는다
- 지금 밀어 넣은 것과 같아질 때까지 기다린다
- 같아진 뒤에야 나머지를 확인한다
기다리지 않고 바로 확인하면 옛 버전을 검사하고 통과시킵니다. 가장 나쁜 결과입니다 — 배포되지 않은 것을 배포됐다고 확정해 줍니다.
무엇을 확인할 것인가
섹션 제목: “무엇을 확인할 것인가”- 경로를 이름으로. 목록을 두고 하나씩 두드립니다. 화면을 늘리면 목록도 같이 늘립니다. 자동으로 훑는 방식은 새 화면이 빠져도 모릅니다.
- 화면에 알맹이가 있는지. 목록 화면이면 항목 링크 수를 셉니다. 200 만으로는 비어 있는 것을 못 잡습니다.
- 없는 주소가 404 인지.
- 소유확인·키 파일이 살아 있고 내용이 맞는지. 이름만 맞고 내용이 다르면 소용없습니다.
- 보안 헤더가 실제로 붙는지. 헤더 설정 파일이 배포물에 안 들어가면 조용히 사라집니다.
- 기능이 도는지. 검색이나 테마 전환처럼 화면만 봐서는 모르는 것은 실제 브라우저로 눌러 봐야 합니다.
검사가 스스로 틀리는 방식
섹션 제목: “검사가 스스로 틀리는 방식”여기가 이 문서의 핵심입니다. 검증 스크립트도 코드이고, 틀립니다. 그리고 두 방향으로 틀립니다.
| 무엇 | 얼마나 나쁜가 | |
|---|---|---|
| 거짓 통과 | 망가졌는데 통과 | 최악. 검증이 있다는 사실이 오히려 방심하게 만든다 |
| 거짓 실패 | 멀쩡한데 실패 | 눈에 보이니 덜 나쁘지만, 반복되면 검증을 끄게 된다 |
없는 것을 세면 조용히 틀립니다
섹션 제목: “없는 것을 세면 조용히 틀립니다”“빈 상태 문구가 보이면 고장”이라는 검사를 만들었다가 헛짚은 적이 있습니다. 그 문장은 화면에 안 보여도 다국어 메시지 번들에 직렬화되어 HTML 안에 늘 들어 있었습니다. 글이 멀쩡히 나오는 화면을 비었다고 읽었습니다.
원문 HTML 을 grep 하는 검사는 이런 식으로 틀립니다. 사람이 보는 것과 문서에 들어 있는 것이 다릅니다.
있는 것을 세십시오. 글 목록이면 글 상세로 가는 링크 수를 셉니다.
조건을 너무 좁게 잡으면 멀쩡한 배포가 막힙니다
섹션 제목: “조건을 너무 좁게 잡으면 멀쩡한 배포가 막힙니다”“보안 정책에 해시가 하나 이상 있어야 정상” 이라는 검사를 만들었다가 멀쩡한 배포를 실패로 읽은 적이 있습니다. 인라인 스크립트가 하나도 없는 사이트에서는 해시가 0개인 것이 정상이고, 그 편이 더 좁은 정책입니다.
있어야 할 것이 아니라 없어야 할 것을 물으십시오. 이 경우 물어야 할 것은 해시의 존재가 아니라 위험한 지시어의 부재였습니다.
없는 경로를 검사하고 통과합니다
섹션 제목: “없는 경로를 검사하고 통과합니다”한 사이트의 검사를 다른 사이트로 복사하면서 존재하지 않는 경로를 그대로 물려받은 적이 있습니다. 헤더 규칙이 전체 경로에 적용돼 있어서 404 응답에도 헤더가 붙었고 검사는 통과했습니다. 실제로 사람이 여는 화면을 본 것이 아니었습니다.
검사와 콘텐츠가 묶입니다
섹션 제목: “검사와 콘텐츠가 묶입니다”화면이 제대로 그려졌는지를 본문의 특정 문장으로 확인하는 방법이 있습니다. 좋은 방법인데, 그 문장을 고치면 검증도 같이 고쳐야 합니다.
첫 화면 문구를 갈아 끼웠더니 빌드와 기동은 성공했는데 검증만 실패했습니다. 이런 묶임은 주석으로 남겨 두는 편이 낫습니다. 다음에 문구를 고치는 사람이 검증까지 함께 볼 이유가 없기 때문입니다.
시간을 넉넉히 주십시오
섹션 제목: “시간을 넉넉히 주십시오”문서가 늘면 빌드가 길어집니다. 검색 색인을 다시 만드는 구성이라면 특히 그렇습니다. 대기 시간이 짧으면 페이지는 다 올라와 있는데 커밋 대조만 시간을 초과해 실패합니다.
거짓 실패는 거짓 통과보다 낫지만, 반복되면 사람이 검증을 믿지 않게 됩니다. 그것이 결국 검증을 끄는 길입니다.
| 고장 | 200 을 주는가 | 어떻게 잡나 |
|---|---|---|
| 빌드 실패 | 예 | 커밋 대조 |
| 데이터 못 읽음 | 예 | 항목 수를 셈 |
| 보안 정책 오류 | 예 | 실제 브라우저로 기능을 눌러 봄 |
| 소유확인 파일 소실 | 예 | 파일의 200 과 내용 일치 |
| 없는 주소 | 아니오 (200 을 주면 그게 고장) | 404 확인 |
