검사는 전부 통과했는데 라이브만 404였다
사이트맵도 내부링크도 빌드 검사도 모두 초록불인데 실제 주소만 404였습니다. 원인과, 같은 사고를 막으려고 새로 세운 검사 하나.
새 코너를 하나 만들었습니다. 페이지를 생성하고, 사이트맵에 등록하고, 내부 링크를 걸고, 커밋하고, 배포했습니다.
검사는 전부 초록불이었습니다.
- 사이트맵 등재 검사 ✓
- 내부 링크 유효성 검사 ✓
- 생성물이 생성기 출력과 일치하는지 ✓
- 메타 태그 길이 ✓
그리고 실제 주소를 열었더니 404였습니다.
처음엔 배포가 덜 된 줄 알았다
정적 사이트 배포는 보통 1~2분이면 끝납니다. 그래서 처음엔 그냥 기다렸습니다. 5분, 8분. 그래도 404였습니다.
이상한 건 상태 코드가 404가 아닐 때도 있었다는 점입니다. 어떤 요청에는 200이 오는데 내용이 홈 화면이었습니다. 없는 페이지인데 200을 주는 상태, 이른바 소프트 404입니다.
여기서 원인을 잘못 짚었습니다. "소프트 404 처리가 잘못됐나 보다" 하고 그쪽 코드를 한참 봤습니다. 아니었습니다.
진짜 원인
배포 과정을 한 줄씩 읽다가 찾았습니다. 배포는 필요한 폴더를 하나씩 골라 담는 방식이었습니다.
cp -r guide dist/
cp -r news dist/
cp about.html contact.html privacy.html dist/
새로 만든 폴더를 담는 줄이 없었습니다.
그래서 이런 상태가 됐습니다.
- 저장소에는 파일이 있다 → 파일 기준 검사는 전부 통과
- 사이트맵에는 주소가 있다 → 등재 검사도 통과
- 배포본에는 파일이 없다 → 라이브만 404
200이 섞여 나온 이유도 여기 있었습니다. 사이트맵에 있는 주소라 "없는 페이지"를 걸러내는 규칙을 통과했고, 정작 파일이 없으니 기본 화면이 대신 나갔던 것입니다. 두 개의 옳은 규칙이 만나서 틀린 결과를 만들었습니다.
왜 어떤 검사도 못 잡았나
검사들을 다시 보니 전부 저장소를 보고 있었습니다.
| 검사 | 무엇을 보나 |
|---|---|
| 사이트맵 등재 | 저장소 파일 ↔ 사이트맵 |
| 내부 링크 | 저장소 파일끼리 |
| 생성물 동기 | 저장소 파일 ↔ 생성기 출력 |
"배포본"을 보는 검사가 하나도 없었습니다. 저장소가 옳으면 배포본도 옳을 것이라고 암묵적으로 믿고 있었던 것입니다. 폴더를 하나씩 골라 담는 방식에서는 그 믿음이 성립하지 않는데도요.
세운 검사
그래서 검사를 하나 만들었습니다. 규칙은 한 줄로 요약됩니다.
저장소에 파일이 있는 주소는 배포본에도 파일이 있어야 한다.
구현할 때 한 가지를 신경 썼습니다. 대상 폴더를 목록으로 적지 않았습니다. 목록을 적으면 다음에 새 폴더를 만들 때 또 빠뜨립니다 — 방금 겪은 사고를 그대로 반복하는 셈입니다.
대신 사이트맵의 모든 주소를 훑으면서 "저장소에 이 주소에 해당하는 파일이 실제로 있는가"를 먼저 봅니다. 있으면 검사 대상이고, 없으면(앱이 그리는 화면 같은 경우) 건너뜁니다. 이러면 새 폴더가 생겨도 자동으로 검사 범위에 들어옵니다.
배포 단계 중간에 넣었습니다. 파일을 다 담은 직후, 실제로 올리기 전입니다. 여기서 걸리면 배포가 멈춥니다.
만들자마자 잡혔다
검사를 넣고 시험 삼아 새 폴더가 빠진 상태를 만들어 돌려 봤더니, 빠진 폴더 이름을 그대로 짚어 줬습니다. 그리고 정상 상태에서는 조용히 통과했습니다.
실제 배포에서도 곧바로 한 번 일했습니다. 다른 작업 중에 자동 갱신이 끼어들면서 파일 하나가 최신이 아닌 상태로 남았는데, 그때 배포가 멈췄습니다. 아프지만 옳은 동작입니다. 틀린 걸 올리는 것보다 안 올리는 게 낫습니다.
남는 교훈
정적 사이트에서 검사를 세울 때 이걸 기억해 두면 좋겠습니다.
검사가 보는 것과 사용자가 보는 것이 다르면, 그 사이 어딘가에 사고가 숨습니다. 저장소를 아무리 검사해도 배포본이 다르면 소용이 없고, 배포본을 검사해도 캐시가 다르면 또 소용이 없습니다.
그래서 가장 마지막 단계, 즉 사용자가 실제로 받는 것에 가장 가까운 지점에 검사를 하나 두는 게 값어치가 큽니다. 앞의 검사들이 다 초록불이어도 여기서 걸리면, 그건 앞의 검사들이 놓친 종류의 문제라는 뜻이니까요.
그리고 하나 더. "검사가 전부 통과했는데 이상하다"는 느낌이 들면, 검사가 무엇을 보고 있는지부터 확인하는 게 빠릅니다. 저는 그러지 않고 엉뚱한 코드를 한참 봤습니다.