rsync와 심볼릭 링크로 정적 사이트를 원자적으로 배포하기

목차 펼치기

정적 사이트 배포에서 가장 무서운 순간은 “절반만 올라간 상태”입니다. 파일을 웹루트에 직접 덮어쓰는 동안 방문자가 들어오면, 옛 HTML이 새 CSS를 읽는 깨진 화면을 만나게 됩니다. 이 글에서는 릴리스 디렉토리(Release Directory)와 심볼릭 링크(Symbolic Link) 교체로 이 문제를 구조적으로 없애는 방법을 다룹니다.

왜 원자적 전환이 필요한가

배포는 여러 파일을 옮기는 작업이라 본질적으로 시간이 걸립니다. 하지만 서빙 전환은 한순간이어야 합니다. 해법은 간단합니다. 새 버전을 옆에 다 만들어 두고, 마지막에 포인터만 바꾸는 것입니다.

디렉토리 구조

/var/www/site/
├── releases/
│   ├── 20260705-1200/
│   └── 20260706-0900/   ← 새 릴리스
└── current → releases/20260706-0900/   ← 웹서버 DocumentRoot

웹서버는 항상 current만 바라봅니다. 배포는 releases/ 아래에 새 디렉토리를 만드는 일이고, 공개는 링크 교체 한 번입니다.

배포 순서

  1. rsync로 새 릴리스 디렉토리에 산출물을 전송합니다. --link-dest 옵션을 쓰면 이전 릴리스와 같은 파일은 하드링크로 처리되어 디스크와 전송량을 아낍니다.
  2. 링크를 원자적으로 교체합니다. ln -sfn은 내부적으로 두 단계라 틈이 생길 수 있으므로, 임시 링크를 만들고 mv -Tf로 덮어씁니다.
ln -s /var/www/site/releases/20260706-0900 /var/www/site/tmp-link
mv -Tf /var/www/site/tmp-link /var/www/site/current
  1. 롤백은 같은 방법으로 이전 릴리스를 가리키게 하면 끝입니다.

정적 호스팅 방식 전반의 비교는 위키의 정적 사이트 호스팅 문서에 정리해 두었습니다.

마무리

배포를 “복사”가 아니라 “빌드 후 포인터 교체”로 바꾸면, 다운타임과 절반 배포라는 사고 클래스 자체가 사라집니다. 다음 글에서는 이 구조를 GitHub Actions와 연결하는 방법을 다룹니다.

참고문헌 · References