NixOS + Caddy - 파일 서버 설정하기
문제
Caddy는 별다른 설정이 없는 경우 파일의 modified time 만을 이용해서 ETag를 생성한다. 정상적인 사용 사례의 경우 보통 파일이 변경될 때 modified time이 변경되니 큰 문제가 없는데, NixOS의 경우, 빌드 과정에서 모든 시간 정보를 제거하기 때문에 의도한 바와 다르게 브라우저 캐시가 그대로 남아 보이게 되는 문제가 생길 수 있다. 그동안 임시방편으로 서버에서 캐시에 필요한 헤더를 제거하는 방식으로 매번 새 데이터를 받아가도록 하고 있었지만, 200kb에 달햐는 폰트 등의 데이터를 매번 새로 보내려니 데이터 낭비가 심한 듯하여, 어떻게 개선해볼 방법을 찾아보게 되었다.
목표
브라우저 캐시를 제대로 적용할 수 있게 제대로 된 헤더를 보내주자
접근
브라우저가 제대로 캐시를 적용하려면, 서버에서 적절한 etag와 if-modified-since 등등의 태그를 잘 보내줘야 할 테고, 그러려면 파일 시스템에 제대로 된 modified time이 들어가 있어야 한다고 본다. 그런데 NixOS에서 빌드한 파일은 어떻게 해도 UNIX epoch 타임을 쓸 테니 거기서 막혔던 건데, 이번에 도전해본 방법은 그냥 별도의 파일 시스템에 빌드 결과물을 복사하고 그럴듯한 mtime으로 덮어씌우는 것이다.
단순히 복사하고 파일들을 touch해도 되기야 하겠지만, 어차피 대부분의 파일은 변경되지 않을 것이기 때문에, 그것도 rsync를 써서 변경된 파일만 복사하는 방법을 강구해봤다. 이렇게 하면 또 좋은점이, 변경된 파일들만 mtime을 설정하면 브라우저에서도 가능한 한 캐시를 잘 사용할 수 있는 보조적인 효과도 얻을 수 있었다.
하여튼 결론은
system.activationScripts.script.text = ''
#/bin/bash
# recursive, use checksum (instead of time/size), verbose, delete old files after copy
${pkgs.rsync}/bin/rsync -rcv --delete --delete-after ${srcs.awesome-blog-build}/ /srv/web-thegreatblog/
'';
services.caddy =
let
blog-config = ''
file_server
root * /srv/web-thegreatblog/
'';
in { ... }
결론
근데 이 포스팅이 제대로 갱신되어 보여야 제대로 작동한다는 것을 확인할 수 있는데 잘 될런지…