화면에 사이트 두 개가 있습니다. 첫 번째는 게임 페이지입니다: 게임판, 점수, "다시 하기" 버튼. 두 번째는 공방 페이지로, "주문하기" 양식이 있습니다. 둘 다 브라우저에서 열리고, 둘 다 HTML, CSS, JavaScript로 만들어졌고, 둘 다 완성된 것처럼 보입니다. 첫 번째는 1분 만에 배포됩니다: 폴더를 호스팅에 올리면 링크가 바로 나옵니다. 두 번째에서는 에이전트가 멈춰 서서 서버는 어디에 둘지, 주문은 어디에 저장할지 물어볼 가능성이 큽니다.

차이는 복잡함이나 디자인에 있지 않습니다. 방문자가 버튼을 눌렀을 때 누가 무언가를 해야 하는지, 그리고 그 뒤에 데이터가 어디에 있어야 하는지에 있습니다. 정적 사이트, frontend, backend라는 세 단어를 살펴보고, 데이터가 어디에 사는지, 그리고 이것이 왜 배포 방식을 좌우하는지 알아보겠습니다. 마지막에는 여러분이 "배포해 주세요"라고 하기 전에 에이전트가 스스로 묻는 것과, 여러분이 에이전트에게 물어봐야 할 것을 정리합니다.

1. 정적 사이트

정적 사이트란 완성된 파일로 이루어진 사이트입니다: index.html, style.css, 스크립트, 이미지, 폰트. 서버는 이 파일들을 그대로 저장해 두었다가 모든 방문자에게 똑같이 내어 줄 뿐, 아무것도 계산하지 않고 방문자에 대해 아무것도 기억하지 않습니다. 화면을 보여 주고, 계산하고, 클릭에 반응하는 모든 작업은 방문자의 컴퓨터에서 브라우저가 합니다.

한 페이지짜리 포트폴리오를 예로 들어 봅시다. 폴더 안에는 자기소개와 작업 목록이 담긴 index.html, style.css, 이미지 열 장 남짓, 짧은 스크립트가 들어 있습니다. 방문자가 링크를 열면 브라우저가 파일을 내려받아 페이지를 만듭니다. 작업물을 클릭하면 사진이 크게 열리고, 다크 모드 스위치를 누르면 색이 바뀝니다. 이건 모두 브라우저 안의 스크립트가 하는 일입니다. 서버는 파일을 넘겨준 뒤로는 여기에 관여하지 않습니다. 누가 왔는지, 무엇을 눌렀는지 서버는 신경 쓰지 않습니다. 새 작업물이 생기면 여러분이 index.html을 고치고 사진을 옆에 넣고 폴더를 다시 배포합니다. 여기서 무언가를 바꿀 방법은 그것뿐이고, 사이트를 바꾸는 사람은 방문자가 아니라 여러분입니다.

같은 구조로 만들어진 것들:

  • 콘서트나 모임 안내 페이지: 날짜, 장소, 프로그램, 오시는 길; "티켓 구매" 버튼은 티켓 판매 사이트로 연결될 뿐, 안내 페이지 자체는 아무것도 팔지 않습니다;
  • 신청 양식 대신 전화번호와 이메일만 적혀 있는 제품이나 서비스 랜딩 페이지;
  • 프로젝트 문서: 메뉴와 서로 연결된 링크가 있는 수십 개의 페이지지만, 결국은 파일일 뿐입니다;
  • 댓글 없는 블로그: 게시글 하나하나가 파일이고, 새 글도 나머지와 똑같은 방식으로 올라갑니다;
  • 브라우저 게임. 네, 게임도 마찬가지입니다: 진행, 점수, 애니메이션은 모두 브라우저에서 계산되고, 서버는 그것과 상관없습니다.
정적이라고 화면까지 멈춰 있는 건 아니다

이 단어는 화면이 아니라 서버를 설명합니다. 서버가 파일을 아무것도 바꾸지 않고 그대로 내어 준다는 것, 그것이 바로 정적입니다. 화면에서는 모든 것이 움직이고, 깜빡이고, 클릭마다 반응해도 마찬가지입니다.

정적 사이트가 어디까지인지는 사이트가 하는 일을 두 부분으로 나눠 보면 보입니다: 브라우저가 하는 일과 서버가 하는 일. 이 두 부분에는 이름이 있습니다.

2. Frontend는 브라우저에서 동작한다

Frontend란 방문자의 컴퓨터에서 실행되는 모든 것입니다: 마크업, 스타일, 그리고 브라우저가 받아서 직접 실행하는 스크립트. "앞쪽 부분", 눈에 보이는 부분입니다. (흔히 "그냥 마크업"이라고도 부르지만, 사실 사람이 다루는 사이트 부분 전체를 뜻하고, 정적 사이트라면 사이트 전체가 바로 이것입니다.)

frontend가 할 수 있는 일은 많습니다: 페이지를 보여 주고, 게임의 진행을 계산하고, 전송 전에 양식 칸이 비어 있지 않은지 확인하고, 다음 방문까지 무언가를 기억해 둡니다. 이를 위해 브라우저에는 자체 저장 공간이 있는데, 에이전트는 이것을 localStorage라고 부릅니다. 다만 frontend가 못 하는 일이 있습니다. 공유입니다. 저장 공간은 이 브라우저, 이 기기에만 존재하고 다른 곳에는 없습니다. 이 경계가 문제가 되는 경우와 아닌 경우를 예시 두 개로 살펴봅시다.

게임 최고 점수. 한 판이 끝나면 스크립트가 결과를 이전 기록과 비교해 새 기록을 브라우저 저장 공간에 적습니다. 다음 날 같은 브라우저, 같은 노트북에서 페이지를 열면 기록이 그대로 남아 있습니다. 스마트폰에서 열면 비어 있습니다. 스마트폰은 자기만의 저장 공간을 갖고 있으니까요. 게임을 만든 여러분은 이 기록을 영영 볼 수 없습니다. 문제 될 건 없습니다. 그 기록은 오직 그 플레이어에게만 필요한 것이고, 사이트는 여전히 정적으로 남습니다.

공방 주문. 고객이 필요한 것을 적고 전화번호를 남기고 "전송"을 눌렀습니다. 스크립트는 칸이 채워졌는지 확인할 수는 있지만, 그다음에는 갈 곳이 없습니다. 주문을 브라우저 저장 공간에 적으면 그 주문은 고객의 스마트폰에 남을 뿐, 공방 주인은 알 방법이 없습니다. 주문은 다른 사람이 다른 기기에서 읽어야 하니, 데이터가 고객의 컴퓨터를 떠나야 하고, 반대편에서 누군가가 그것을 받아서 저장해야 합니다. 파일로만 이루어진 사이트에는 그 "누군가"가 없습니다.

한 방문자, 한 기기에 관한 일이라면 frontend가 전부 알아서 합니다. 나머지는 다른 절반의 몫입니다.

사이트 파일 안에는 비밀이 없다

사이트 파일에 들어 있는 것은 무엇이든 방문자가 열어서 읽을 수 있습니다. 스크립트도 마찬가지입니다. 날씨 예보, 지도, 결제 같은 외부 서비스의 키를 frontend에 넣으면 누구든 그것을 읽고 여러분 대신 사용할 수 있습니다. 그런 키를 실제로 어디에 두는지는 또 다른 이야기지만, 적어도 페이지 파일 안은 아닙니다.

3. Backend는 서버에서 동작한다

Backend는 서버에서 실행되며 브라우저의 요청에 응답하는 프로그램입니다. 주문을 받아서 저장합니다. 로그인과 비밀번호를 확인합니다. 상품 목록을 내려줍니다. 방문자가 이미 탭을 닫은 뒤에도 동작하고, 항상 켜져 있어야 한다는 점에서 서버, 즉 절대 끄지 않는 컴퓨터와 같은 처지입니다.

세 단계씩 두 줄. 정적 사이트에서는 게임의 한 수를 두면 브라우저 안의 JavaScript가 진행과 점수를 계산하고, 기록을 브라우저에 저장하고, 게임판을 다시 그립니다. 모두 방문자의 컴퓨터에서 일어납니다. backend가 있는 사이트에서는 "주문 전송" 클릭 후 서버의 프로그램이 브라우저의 요청을 받아, 서버에 주문을 저장하고, 브라우저에 응답합니다클릭게임 한 수브라우저의 JavaScript진행과 점수를 계산기록을 브라우저에 저장게임판을 다시 그림결과새 점수클릭주문 전송서버의 프로그램브라우저의 요청을 받음서버에 주문을 저장브라우저에 응답결과"주문 접수됨"정적 사이트backend가 있는 사이트방문자의 컴퓨터서버, 항상 켜져 있음
경로의 형태는 같고, 차이는 가운데에 있습니다: 클릭 뒤에 누가 무슨 일을 하는가

다이어그램에는 같은 형태의 경로 두 개가 있습니다: 클릭, 작업, 결과. 다른 것은 가운데 칸, 즉 누가 무슨 일을 하는가입니다. 위쪽에서는 게임의 한 수 뒤에 브라우저의 JavaScript가 점수를 계산하고, 기록을 저장하고, 게임판을 다시 그립니다. 모두 방문자의 컴퓨터에서 일어납니다. 아래쪽에서는 "전송" 클릭이 요청이 되어 서버로 갑니다. 프로그램이 요청을 받아 서버 쪽에 주문을 저장하고 브라우저에 응답하며, 바로 그 응답이 화면에 나타납니다. 주문이 서버의 정확히 어디에 저장되는지는 다음 절에서 다룹니다. "누가 일을 하는가"라는 질문이 곧 두 유형의 사이트를 가르는 경계입니다.

backend 없이는 안 된다는 것을 알아볼 수 있는 세 가지 신호:

  • 비밀번호 로그인: 누군가는 비밀번호를 저장하고 확인해야 하는데, 방문자의 브라우저가 그 역할을 할 수는 없습니다;
  • 다른 사람이 봐야 하는 데이터: 댓글, 주문, 공용 목록;
  • 여러분을 대신하는 동작: 메일 전송, 결제 처리, 여러분의 키로 외부 서비스에 무언가를 기록하기.

backend에 쓰는 언어는 무엇이든 상관없습니다: JavaScript(이 경우 Node.js), Python, Java, 그 밖에도 여러 가지가 있습니다. 이 글에서 중요한 것은 언어가 아니라, 프로그램이 어딘가에서 계속 돌아가야 하고 그 "어딘가"가 브라우저가 아니라는 점입니다. 사이트 주소는 정적 사이트와 마찬가지로 서버의 한 지점을 가리키지만, 이제 그 자리에 있는 것은 파일이 아니라 즉석에서 응답을 만들어 내는 프로그램입니다.

4. 데이터는 어디에 사는가

클릭 뒤에 누가 일해야 하는지는 데이터가 결정합니다: 데이터가 어디에 있고 누가 봐야 하는지. 사이트의 외관이나 복잡함이 아닙니다. 장소는 세 곳입니다.

프로젝트 파일 안. 페이지 텍스트, 이미지, 게임 규칙. 모든 방문자에게 동일하고, 새로 배포할 때만 바뀝니다: 파일을 고치고 다시 올립니다.

방문자의 브라우저 안. 설정, 최고 점수, 새로고침 때 잃고 싶지 않은 양식 초안. 오직 이 방문자, 이 기기에서만 보입니다. 사이트 데이터를 지우면 사라지고, 시크릿 창에는 없으며, 다른 브라우저나 다른 기기에도 없고, 여러분은 그 존재조차 알 수 없습니다.

서버의 데이터베이스 안. 주문, 댓글, 계정. 봐야 할 모든 사람이 보고, 여러분도 마찬가지입니다. 누군가 탭을 열어 두었는지와 상관없이 계속 존재합니다. 여기에 무언가가 들어가려면 데이터를 받아서 기록하는 서버 프로그램이 있어야 합니다.

데이터가 있는 세 곳. 방문자의 컴퓨터: 사이트 파일의 사본으로 만들어진 페이지, 그리고 데이터가 밖으로 나가지 않는 브라우저 저장 공간. 서버: 모두에게 동일한 사이트 파일, 그리고 프로그램을 거쳐야만 데이터가 들어가고 봐야 할 모든 사람이 볼 수 있는 프로그램과 데이터베이스파일에서 만든 페이지사이트 파일의 사본방문자마다 각자 하나씩브라우저 저장 공간최고 점수, 양식 초안이 방문자만 볼 수 있음사이트 파일텍스트, 이미지, 게임 규칙모두 동일, 배포로 바뀜프로그램받아서 기록함데이터베이스주문, 댓글, 계정봐야 할 모든 사람과 여러분이 봄방문자의 컴퓨터서버
브라우저 저장 공간에서는 화살표가 나가지 않습니다: 데이터는 있지만 기기 밖으로 나가지 않습니다

다이어그램에는 위에서 본 것과 같은 두 세계가 있지만, 이번에는 그 안에 일하는 주체가 아니라 데이터가 들어 있습니다. 사이트 파일은 방문자마다 사본으로 전달되기 때문에 페이지는 모두에게 똑같습니다. 브라우저 저장 공간은 화살표가 없는 유일한 칸입니다: 데이터는 그 안에 있지만 기기 밖으로 나가지 않고, 여러분은 그것을 볼 수 없습니다. 데이터베이스에는 프로그램을 거쳐야만 데이터가 들어가지만, 그 대신 봐야 할 모든 사람이 그것을 볼 수 있습니다.

이론 대신 질문 하나만 던져 보세요: 이 사람이 입력한 것을 다른 사람이 봐야 하는가? "최고 점수를 기억하기"는 아니오이니, 브라우저 저장 공간으로 충분하고 사이트는 정적으로 남습니다. "주문을 저장하기"는 예이니, 데이터베이스와 거기에 기록하는 프로그램이 필요합니다. 이 질문에는 예외가 하나 있고, 데이터와는 관련이 없습니다: 외부 서비스의 키입니다. 키가 있다면 "아니오"라는 답으로는 해결되지 않습니다. 파일 안에 둘 수 없으니, 여러분을 대신해 외부 서비스에 접속하는 서버 프로그램이 필요하거나, 그 일을 대신해 줄 외부 중개 서비스가 필요합니다.

중간 경우도 있습니다. 주문 양식을 외부 서비스가 대신 받아 줄 수 있습니다. 방문자가 "전송"을 누르면 데이터는 여러분의 서버가 아니라 그 서비스로 가고, 거기서 메일로 여러분에게 전달됩니다. 이것도 여전히 backend입니다. 다만 여러분의 것이 아닐 뿐입니다. 물어보면 에이전트가 이런 서비스를 알려 줄 것입니다. 지금 중요한 것은, 서버에서 돌아가는 누군가의 프로그램 없이는 양식이 작동하지 않는다는 사실입니다.

5. 배포 방식이 다른 이유

정적 사이트는 복사로 배포합니다: 폴더를 호스팅(여러분의 파일을 원하는 모든 사람에게 내어 주는 남의 서버)에 올리면 링크가 바로 생기고, 업데이트할 때는 다시 복사하면 됩니다. 그걸로 끝입니다.

backend는 다릅니다. 서버에는 프로그램 언어의 실행 환경, 즉 Python이나 Node.js 자체가 있어야 하고, 이것 없이는 코드를 실행할 방법이 없습니다. 프로그램은 실행되어 있어야 하고, 멈추면 다시 시작되어야 합니다. 옆에서는 데이터베이스도 돌아가야 합니다. 데이터베이스와 외부 서비스의 키는 프로그램은 읽을 수 있지만 방문자는 읽을 수 없도록 보관해야 합니다. 이 각각의 부분은 따로 업데이트되고 저마다 다른 방식으로 고장 납니다.

그래서 호스팅도 다릅니다: 파일만 내어 주는 것이 아니라 프로그램을 실행하는 호스팅입니다. 보통 프로그램이 돌아가는 시간과 데이터베이스 용량에 대해 요금을 냅니다. 무료 옵션도 있지만, 이 글보다 더 자주 바뀌는 조건이 붙습니다.

정적 사이트backend가 있는 사이트
보내는 것파일이 담긴 폴더프로그램 코드
서버에 있어야 하는 것여러분의 것은 없음: 파일을 내어 주는 일은 호스팅이 알아서 함언어용 환경, 실행 중인 프로그램, 데이터베이스
데이터의 위치파일 안과 방문자의 브라우저서버의 데이터베이스
비밀로 지켜야 할 것사이트 파일 자체에는 없음데이터베이스와 외부 서비스의 키
업데이트 방법폴더를 다시 복사코드를 업데이트하고 프로그램을 재시작, 가끔 데이터베이스도 업데이트
비용작은 페이지라면 보통 무료보통 실행 시간과 데이터베이스에 대해 요금을 냄

비밀 값 항목에 하나만 짚고 넘어갑시다. 고정된 링크를 위해 호스팅 키를 만들었다면 정적 사이트에도 그런 키는 있지만, 사이트 폴더와는 별개로 존재하며 폴더 안에 들어가지 않습니다.

에이전트의 답변에서 "서버를 띄우자"는 말은 "파일을 만들자"처럼 대수롭지 않게 들립니다. 하지만 그 한마디 뒤에는 표의 오른쪽 열 전체가 있고, 거의 모든 줄을 나중에 계속 관리해야 합니다.

6. 정적 사이트는 어디에 올릴까

정적 사이트는 복사로 배포하는 만큼 호스팅 선택지도 많고, 작은 페이지라면 대부분 무료입니다. 가장 흔히 쓰이는 다섯 곳을 소개합니다. 표에 "저장소"라는 단어가 나오는데, 지금은 버전 관리 아래 있는 프로젝트 폴더 정도로 이해하면 충분하고, 자세한 내용은 나중에 다룹니다.

호스팅입력으로 요구하는 것링크 형태작은 페이지라면 무료인가
Tiiny Host사이트에서 폴더나 파일 업로드; 에이전트가 직접 올릴 수도 있음이름.tiiny.site무료, 단 사이트 수 제한 있음; 계정 없이도 임시 링크
GitHub PagesGitHub 저장소, 파일을 그대로 가져옴이름.github.io 또는 이름.github.io/프로젝트공개 저장소라면 무료, 상거래 용도는 불가
Netlify브라우저에 폴더를 끌어다 놓기, 터미널 명령, 또는 저장소이름.netlify.app무료
Vercel폴더 끌어다 놓기, 명령, 또는 저장소이름.vercel.app개인 비상업 프로젝트라면 무료
Cloudflare Pages대시보드로 폴더나 압축 파일, 명령으로 폴더, 또는 저장소이름.pages.dev무료

고르는 기준. 보여 주고 의견을 나누는 용도라면 가입 없이 링크가 나오는 곳. 오래 남겨 둘 것이라면 계정을 만든 곳 아무 데나. 프로젝트가 저장소에 있다면 저장소와 연동되어 변경할 때마다 스스로 업데이트되는 곳. 배포된 페이지가 어떻게 보이는지에는 선택이 영향을 주지 않습니다. 파일은 동일하니까요.

사이트에 backend가 있다면

프로그램에는 파일만 내어 주는 것이 아니라 여러분의 코드를 실행하고 계속 돌아가게 해 주는 호스팅이 필요합니다. 입력으로 들어가는 것은 폴더가 아니라 프로그램이고, 그것을 위한 환경은 호스팅이 알아서 준비합니다. 위 표의 서비스 중 일부에도 이런 모드가 있지만, 보통은 프로그램 전용으로 만들어진 두 곳부터 시작합니다:

호스팅입력으로 요구하는 것링크 형태무료 옵션
RenderGitHub나 비슷한 서비스의 저장소; 연동된 저장소는 변경할 때마다 스스로 업데이트됨이름.onrender.com있지만, 오래 요청이 없으면 프로그램이 잠들고 바로 깨어나지 않음; 무료 데이터베이스는 한정된 기간만 유지됨
Railway저장소 또는 터미널 명령이름.up.railway.app매달 소액의 크레딧이 주어지는 플랜이 있고, 그 이후는 유료

무료 backend에는 항상 대가가 따릅니다. 한 서비스에서는 프로그램이 잠들어서, 한동안 요청이 없다가 처음 온 방문자는 프로그램이 깨어날 때까지 기다려야 하고, 다른 서비스에서는 크레딧이 바닥납니다. 방문자가 많아지면 계속 돌아가게 하는 데 돈을 내게 됩니다. 정적 사이트에는 이런 문제가 없습니다. 파일은 잠들지 않으니까요.

모든 서비스의 조건과 한도는 계속 바뀌고, 제품 이름도 바뀌거나 합쳐집니다. 예를 들어 Cloudflare는 이미 새 프로젝트를 Pages가 아니라 Workers에서 시작하라고 권하고 있으며, 거기서도 정적 파일은 같은 방식으로 배포됩니다. 두 표에는 일부러 구체적인 숫자를 넣지 않았습니다. 선택하기 전에 요금제 페이지를 확인하세요.

7. 배포 전에 에이전트에게 물어볼 것

에이전트는 폴더를 보고 보통 알아서 프로젝트 유형을 말해 줍니다. 프로그램 없이 파일뿐이면 정적 호스팅을 제안합니다. 파일 중에 보낼 곳이 없는 양식이 있어도 마찬가지인데, 그런 부분까지 늘 알아채지는 못하기 때문입니다. server.js나 app.py가 있으면 서버가 필요하다고 말하고 어디에 둘지 물어봅니다. 아무 말이 없거나 너무 빨리 결론을 냈다면 직접 물어보세요:

이 프로젝트를 보고 정적 사이트인지, 서버가 필요한지 알려 주세요.
정확히 무엇이 서버를 요구하는지 항목별로 나열해 주세요.
각 항목마다 서버 없이 처리하거나 나중으로 미룰 수 있는지 제안해 주세요.

답변은 프로젝트마다 다르므로 여기에는 없습니다. 대신 어떤 답변을 받든 살펴봐야 할 것들이 있습니다.

  • "서버가 필요하다"는 말에 덮어놓고 동의하지 마세요. 정확히 무엇이 서버를 요구하는지, 브라우저에서 처리하거나 뒤로 미룰 수 있는지 물어보세요. 예를 들어 양식 없이 첫 버전을 먼저 내놓는 식으로요. 에이전트는 브라우저 저장 공간만으로 충분한 곳에서도 기꺼이 backend를 만들려 합니다.
  • 반대의 경우도 있습니다. 데이터를 여러 사람이 공유해야 한다면 에이전트는 대체로 정적으로는 안 된다고 말할 것입니다. 이건 과한 게 아니라 사실을 있는 그대로 말하는 것뿐입니다. 여기에는 딱히 반박할 게 없습니다.
  • 외부 서비스의 키에 대해서는 에이전트가 어디에 둘지 물어볼 것입니다. "사이트 파일 안에"라는 답은 틀렸고, 좋은 에이전트라면 스스로 그렇게 말합니다. 그런 키에는 사이트 파일 밖의 자리가 있고, 그 자리를 에이전트가 직접 말해야지 페이지에 키를 적어 넣자고 제안해서는 안 됩니다.
  • 정적 사이트를 배포하려면 에이전트에게 폴더만 있으면 됩니다. backend를 배포하려면 데이터베이스, 환경, 비밀 값에 대한 답변도 더 필요합니다. 질문이 없었는데 서버가 "떴다"면, 정확히 무엇을 어디에 했는지 살펴보세요.
"배포해 주세요" 전에 질문 하나

"이거 정적 사이트인가요? 여기서 서버가 필요한 부분은 뭔가요? 서버 없이 할 수 있을까요?" 한 줄에 담긴 세 가지 질문이면, 에이전트는 무언가를 띄우기 전에 프로젝트를 먼저 차근차근 정리해 보여 줄 것입니다.

"정적"과 "backend"라는 말은 복잡함이 아니라 장소를 설명합니다. 일이 어디서 일어나고 데이터가 어디에 사는지. 그 장소를 알고 나면 배포 방식은 저절로 정해집니다.


호스팅 조건은 시간이 지나면서 바뀌니, 요금제 페이지에서 직접 확인하세요.