정적 사이트: 파일에서 도메인까지
랜딩 페이지나 React, Vue 빌드를 위한 전체 과정: VPS에 파일을 업로드하고, 웹 서버로 제공하고, 도메인을 연결하며, 중단 없이 업데이트하는 방법을 알아봐요.
업데이트 2026년 8월 23일
정적 사이트는 완성된 파일의 집합이에요. HTML, CSS, 이미지, 프런트엔드 빌드로 구성되죠. PHP도 데이터베이스도 필요 없어서 VDS-1에서도 쾌적하게 돌아가고, 최대 500 Mbit/s까지 눈에 띄는 트래픽을 감당해요.
파일을 어디에 둘까요
사이트마다 별도의 디렉터리를 만들어요:
mkdir -p /var/www/example.ru
chown -R www-data:www-data /var/www/example.ru
로컬 머신에서 scp나 rsync로 업로드해요:
scp -r ./dist/* root@YOUR_ADDRESS:/var/www/example.ru/
rsync -avz --delete ./dist/ root@YOUR_ADDRESS:/var/www/example.ru/
rsync --delete는 빌드에 더 이상 없는 파일을 서버에서 삭제해요. 이 옵션이 없으면 오래된 JS 청크가 몇 년씩 쌓여요.
웹 서버로 서빙하기
최소 Nginx 설정이에요:
server {
listen 80;
server_name example.ru;
root /var/www/example.ru;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.(js|css|png|jpg|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
try_files ... /index.html 줄은 React, Vue, Svelte로 만든 싱글 페이지 애플리케이션에 필요해요. 이게 없으면 /about으로 바로 접속할 때 404가 반환돼요.
다음으로 Let's Encrypt 인증서를 설정하면 사이트가 HTTPS로 열려요.
도메인
도메인 패널에서 머신의 공인 주소(/hosting/vds/m/<id>의 “Overview” 탭)를 가리키는 A 레코드와 www용 레코드를 같은 값으로 만들어요. 확인해요:
dig +short example.ru
레코드가 전파되는 데 최대 몇 시간이 걸릴 수 있어요. 기다리는 동안에는 머신 주소로 사이트에 접속할 수 있어요.
다운타임 없이 업데이트하기
운영 중인 디렉터리 위에 파일을 덮어쓰지 마세요. 방문자가 절반만 빌드된 사이트를 볼 수 있어요. 옆에 빌드하고 심볼릭 링크를 전환해요:
rsync -avz ./dist/ /var/www/releases/$(date +%s)/
ln -sfn /var/www/releases/1724400000 /var/www/example.ru-current
systemctl reload nginx
그러면 설정의 root가 /var/www/example.ru-current를 가리켜요.
흔한 실수
| 증상 | 원인 |
|---|---|
| 빈 페이지, 콘솔에 JS 404 | 잘못된 base로 파일을 빌드했어요 — 번들러 설정을 확인하세요 |
| 일부 방문자에게 옛 버전이 보임 | 브라우저 캐시예요 — 해시가 붙은 파일 이름을 사용하세요 |
| 모든 요청에 403 | 디렉터리를 웹 서버 사용자가 읽을 수 없어요 |
| 홈 페이지만 작동함 | 싱글 페이지 애플리케이션용 try_files가 없어요 |
프런트엔드는 로컬에서 빌드하고 완성된
dist를 업로드하는 게 좋아요. 메모리 2 GB인 VDS-1에서는 큰 프로젝트를 빌드하다가 메모리 부족으로 실패할 수 있어요.