← 전체 글로 돌아가기

서버 운영

Nginx 정적 파일 캐시가 배포 후에도 남았을 때 헤더를 기준으로 고친 방법

새 CSS를 배포했는데 이전 화면이 보였던 현상을 캐시 헤더와 파일명 전략으로 해결한 기록

모바일에서만 이전 CSS가 보였다

새 번들을 올린 뒤에도 일부 기기에서 예전 화면이 나왔다. 서버 파일은 바뀌었지만 응답 헤더에 긴 max-age가 있었고 HTML은 고정된 /assets/app.css를 가리키고 있었다.

curl -I https://example.com/assets/app.css
curl -s https://example.com | grep -oE 'assets/[^" ]+\.css'

같은 URL의 내용이 바뀌면 이미 받은 응답을 계속 써도 되는 정책이었다. 브라우저 탓으로 넘길 문제가 아니었다.

문서와 자원의 수명을 분리했다

빌드가 해시 파일명을 만든다는 전제에서 자원은 오래 캐시하고 HTML은 새 파일명을 빨리 확인하도록 했다. 해시 없는 파일을 덮어쓰는 구조에는 immutable을 적용하지 않았다.

location /assets/ {
  add_header Cache-Control "public, max-age=31536000, immutable";
  try_files $uri =404;
}

location / {
  add_header Cache-Control "no-cache";
  try_files $uri /index.html;
}

배포 확인 목록

  • HTML이 새 해시 파일을 참조하는가
  • CDN과 원본의 헤더가 같은가
  • Age, ETag, Cache-Control을 실제 응답에서 봤는가
  • 롤백할 때 이전 해시 파일도 잠시 제공되는가

이번부터 캐시 삭제를 첫 해결책으로 두지 않는다. 변하지 않는 파일은 이름을 바꾸고, 바뀌는 문서는 짧게 검증하는 편이 예측 가능했다.