서버 운영
Nginx 정적 파일 캐시를 무효화하지 못한 배포 실수와 해시 기준
CSS를 수정했는데 일부 사용자에게 이전 화면이 남은 배포 실수를 파일명 해시와 캐시 헤더로 나눠 해결한 기록
CSS를 고쳤는데 휴대폰만 예전 화면이었다
강력 새로고침을 하면 고쳐져서 애플리케이션 문제처럼 보이지 않았다. Network 탭에서 JS는 새 파일인데 CSS 응답의 Age가 오래된 것을 확인하고 Nginx 캐시로 원인을 좁혔다.
캐시를 전역으로 끄지 않았다
정적 파일마다 no-cache를 주면 비용이 커진다. 빌드 산출물에 콘텐츠 해시가 붙는지 확인하고, 해시 파일은 오래 캐시하며 HTML만 짧게 캐시하는 정책으로 나눴다.
server {
location = / {
add_header Cache-Control "no-cache" always;
try_files $uri /index.html;
}
location ~* \.(?:css|js|woff2|png|jpg|svg)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
try_files $uri =404;
}
}
파일명이 styles.css처럼 고정된 구조라면 긴 캐시는 위험하다. 그 경우 캐시 키를 배포 때 비우거나 캐시 시간을 짧게 둬야 한다. 프로젝트는 해시 파일명으로 바꾸고 새 HTML이 참조할 파일을 먼저 올리는 순서를 적용했다.
응답 헤더와 내용 비교
curl -sSI https://example.com/assets/app.abc123.css
curl -sS https://example.com/assets/app.abc123.css | sha256sum
재발 방지 목록
- 콘텐츠가 바뀌면 산출물 URL도 바뀌는가
- HTML과 정적 파일의 캐시 정책이 분리됐는가
- 새 HTML이 참조하는 파일이 먼저 올라가는가
- 외부 주소에서 Age, ETag, Cache-Control을 확인했는가
캐시를 없애기보다 변경 파일의 이름을 바꾸고, 바뀌지 않는 파일만 오래 보관하는 편이 운영하기 쉬웠다.