개발
Cloudflare 도메인 구매하기
| 서론
안녕하세요, 팡일입니다.
Vercel, Netlify 같은 플랫폼으로 웹 서비스를 배포해보셨다면 .vercel.app, .netlify.app 주소를 한 번쯤 써보셨을 겁니다.
기본 도메인을 그대로 써도 서비스를 운영하는 데에는 문제가 없습니다. 개인 프로젝트나 테스트용이라면 굳이 도메인을 사지 않는 것도 충분히 좋은 선택입니다.
다만 서비스를 조금 더 본격적으로 운영하거나 다른 사람에게 공개하려고 하면 이야기가 달라집니다.
my-service.vercel.app
보다는
my-service.com
쪽이 기억하기 쉽고, 보는 사람에게도 조금 더 완성된 서비스라는 인상을 줍니다. 포트폴리오로 쓰거나 실제 사용자를 받고 있다면 커스텀 도메인을 붙여볼 만합니다.
도메인은 국내에서는 호스팅케이알, 가비아 같은 업체에서, 해외에서는 Cloudflare를 비롯한 여러 등록 업체에서 구매할 수 있습니다.
이번 글에서는 Cloudflare에서 도메인을 직접 구매하고, 그 도메인을 Vercel에 연결하는 과정을 처음부터 하나씩 정리해보려고 합니다. 실제로 제가 이 블로그의 도메인을 붙이면서 겪은 것들을 그대로 담았습니다.
| 근데 왜 Cloudflare인가요?
국내에도 도메인을 살 수 있는 곳이 많은데, 저는 이번에 Cloudflare를 골랐습니다.
1. 가격에 마진이 붙지 않습니다
도메인은 한 번 사고 끝나는 게 아니라 보통 1년 단위로 갱신해야 합니다. 그래서 처음 구매 가격보다 갱신 가격이 더 중요합니다.
Cloudflare Registrar는 등록·갱신 과정에서 별도의 마진을 붙이지 않는 가격 정책을 내세우고 있습니다. 원가에 가깝게 판다는 뜻이고, 무엇보다 첫해 할인 뒤 갱신 때 값이 뛰는 구조가 아니라는 점이 좋았습니다.
다만 최종 가격은 .com, .net, .dev 등 TLD(최상위 도메인, Top-Level Domain)에 따라 다르니 구매 전에 최초 등록 가격과 연간 갱신 가격을 함께 확인하시는 걸 추천합니다. Cloudflare Registrar가 지원하지 않는 TLD도 있습니다.
2. 여러 TLD를 한 번에 비교할 수 있습니다
원하는 이름을 검색하면 여러 TLD를 같이 보여줍니다. 이미 누가 쓰고 있는 이름이라면 다른 TLD를 찾아볼 수도 있고, 서비스 성격에 맞는 걸 비교하면서 고를 수 있습니다.
3. WHOIS에 개인정보가 노출되지 않습니다
도메인을 등록하면 등록자 정보가 WHOIS라는 공개 데이터베이스에 올라갑니다. 업체에 따라 이걸 가려주는 옵션을 유료로 파는 곳도 있는데, Cloudflare는 기본으로 가려줍니다. 개인이 자기 이름으로 도메인을 사는 경우라면 꽤 중요한 부분입니다.
4. 구매한 곳에서 DNS까지 관리합니다
Cloudflare에서 도메인을 사면 네임서버가 처음부터 Cloudflare로 잡힙니다. 그래서 네임서버를 따로 옮기는 과정 없이 곧바로 DNS 레코드를 추가할 수 있습니다. 뒤에서 Vercel에 연결할 때 이 점이 편했습니다.
| Cloudflare에서 도메인 구매하기
1. 회원가입
먼저 Cloudflare에 접속해 회원가입을 진행합니다. 계정이 이미 있다면 넘어가셔도 됩니다.

2. 로그인 후 도메인 등록 페이지로 이동
회원가입을 마친 뒤에는 로그인하고, 왼쪽 메뉴에서 다음 경로로 이동합니다.
Domains > Domain Registration
새로 도메인을 사는 경우 이 메뉴에서 원하는 이름을 바로 검색할 수 있습니다.

3. 원하는 도메인 검색
사고 싶은 이름을 검색하면 구매 가능 여부와 가격이 나옵니다. 같은 이름이라도 .com, .net, .dev 등 TLD(최상위 도메인, Top-Level Domain)에 따라 가격이 달라집니다. 원하는 도메인을 클릭합니다.
여기서 한 가지만 더 볼 점!
: 최초 구매 가격과 연간 갱신 비용을 같이 확인해 주세요. 도메인은 매년 갱신해야 하기 때문에, 처음에 저렴해 보여도 갱신 가격이 높으면 장기적으로 부담이 됩니다.

4. 등록자 정보 입력
도메인을 사려면 등록자 정보를 입력해야 합니다. 해외 서비스라 주소는 영문으로 넣는 게 좋습니다. 한국 주소를 그대로 번역하려고 하기보다는, 각 입력란에 맞춰 나눠 넣는다고 생각하시면 쉽습니다.

서울역을 예로 들면 이렇게 됩니다.

휴대폰 번호는 국가번호를
+82로 고른 뒤 맨 앞의0을 빼고 넣습니다.010-1234-5678이라면1012345678이 되는 식입니다.주소를 영문으로 어떻게 써야 할지 모르겠다면 도로명주소 안내 시스템(juso.go.kr)의 영문 주소 검색을 쓰면 편합니다. 검색한 결과를 각 칸에 나눠 넣으면 됩니다.
5. 결제
등록자 정보를 다 적었다면 결제 정보를 입력하고 최종 금액을 확인합니다. 여기서도 지금 결제되는 금액과 다음 갱신 때 결제될 금액을 같이 보시길 권합니다. 카드사나 결제 수단에 따라 추가 인증이 뜰 수 있습니다.

6. 결제 완료
결제가 끝나면 구매한 도메인이 계정에 등록됩니다.

이제 도메인을 소유하게 됐습니다. 다만 아직 이 주소로 서비스에 접속할 수는 없습니다.
구매 직후의 도메인은 레코드가 하나도 없는 빈 상태입니다. 네임서버는 Cloudflare를 가리키고 있지만, 그 안에 "이 주소로 온 요청을 어디로 보내라"는 내용이 아직 없는 거죠. 다음 단계에서 그걸 채워 넣습니다.
| Cloudflare 도메인을 Vercel에 연결하기
전체 흐름은 이렇습니다.
Vercel에 도메인 추가 → Vercel이 알려주는 DNS 값 확인 → Cloudflare DNS에 등록 → 연결 확인
1. Vercel의 Domains 메뉴로 이동
연결하고 싶은 프로젝트를 고른 뒤 도메인 설정으로 들어갑니다.
Project → Domains > Add Existing
2. 도메인 추가하기
구매한 도메인을 입력하고 추가합니다. example.com을 샀다면 그대로 넣으면 됩니다.
이때 Redirect apex domains to www (recommended) 라는 체크박스가 기본으로 켜져 있습니다. 켜두면 example.com으로 온 사람을 www.example.com으로 넘기고, 그쪽이 정식 주소가 됩니다.
저는 이걸 껐습니다. 앱에서 "우리 서비스의 호스트"를 환경변수로 들고 있었는데, www를 정식 주소로 삼으면 그 값이 www.example.com이 되고, 그러면 쿠키를 심는 도메인이 .www.example.com이 되어 다른 서브도메인과 공유되지 않기 때문입니다. 서브도메인을 여럿 쓸 계획이라면 apex를 정식 주소로 두는 쪽이 단순합니다.
www를 쓸지 말지는 취향의 영역이지만, 한쪽을 정해서 나머지는 그쪽으로 넘기는 것만은 지키는 게 좋습니다. 같은 글이 두 주소로 열리면 검색엔진 입장에서는 중복 문서가 됩니다.

3. Invalid Configuration은 오류가 아닙니다
도메인을 추가하면 십중팔구 빨간 경고와 함께 Invalid Configuration이 뜹니다.

당황하실 필요 없습니다. Vercel에 도메인을 등록한 것과 그 도메인의 DNS가 Vercel을 가리키는 것은 별개인데, 지금은 앞의 것만 끝난 상태입니다. Vercel이 "이 도메인이 나를 가리키나?"를 DNS로 확인하는데, 아직 가리키는 게 없으니 저렇게 뜨는 겁니다.
등록 직후에는 원래 이 상태입니다. 이제 DNS를 채우면 됩니다.
각 도메인 줄의 좌측에 있는 View DNS Configuration을 클릭하면 넣어야 할 레코드가 표로 나옵니다.
여기서 볼 값은 세 가지입니다.
Type
Name
Value
두 가지를 짚고 넘어가겠습니다.
첫째, 루트 도메인인데도 CNAME이 나올 수 있습니다.
예전 자료를 보면 루트 도메인(example.com)에는 A 레코드에 76.76.21.21을 넣으라고 되어 있는 경우가 많습니다. 그런데 지금 Vercel은 루트에도 CNAME을 안내하는 쪽으로 바뀌었습니다.
DNS 표준상 루트에는 CNAME을 둘 수 없지만, Cloudflare는 CNAME Flattening 기능으로 조회 시점에 알아서 A 레코드처럼 응답해줍니다. 그래서 Cloudflare에서는 루트에 CNAME을 넣는 게 정상 동작이고, 요즘은 이 조합이 권장 경로입니다. 화면에 CNAME이 떴다고 잘못 본 게 아닙니다.
둘째, CNAME 값은 프로젝트마다 다릅니다.
cname.vercel-dns.com 같은 공통 주소를 기대하실 수 있는데, 지금은 프로젝트마다 고유한 값이 발급됩니다. 이런 모양입니다.
k28dh1721ch12345.vercel-dns-011.com
그래서 글에 적힌 예시값이 아니라 본인 화면에 뜬 값을 그대로 복사해야 합니다. 이건 단순한 주의사항이 아니라, 남의 값을 넣으면 절대 연결되지 않는다는 뜻입니다.
4. Cloudflare에서 DNS 레코드 추가하기
Cloudflare로 돌아와 구매한 도메인의 DNS → Records 화면으로 이동한 뒤 Add record를 누릅니다.

이제 앞에서 확인한 값을 그대로 넣습니다.


Name 칸에서 한 번씩 헷갈리는데, 루트 도메인은 @ 입니다. 서브도메인은 dev.example.com 전체가 아니라 dev만 적습니다. 전체를 적으면 dev.example.com.example.com이 되어버립니다.
유의할 점
Cloudflare에서 레코드를 추가하면 Proxy status가 기본으로
Proxied(주황 구름)로 켜져 있습니다. 이걸 끄고DNS only(회색 구름)로 바꿔야 합니다.켜둔 채로 두면 Cloudflare가 자기 IP로 응답하기 때문에 Vercel이 "이 도메인이 나를 가리킨다"는 걸 확인하지 못합니다.
Invalid Configuration이 계속 안 풀리거나, 풀리더라도 인증서 발급이나 리다이렉트에서 문제가 생깁니다. 특히 루트 도메인은 CNAME Flattening 결과까지 Cloudflare IP로 바뀌기 때문에 더 확실하게 막힙니다.애초에 Vercel이 이미 CDN이라 Cloudflare 프록시를 그 앞에 한 겹 더 얹을 이유도 없습니다.
저도 이 한 칸 때문에 한참을 헤맸습니다. 연결이 안 될 때 가장 먼저 확인해야 할 곳입니다.
5. 입력한 값 확인하기
레코드를 추가했다면 Type, Name, Value에 오타가 없는지 다시 확인합니다. DNS는 한 글자만 틀려도 연결되지 않습니다.

터미널에서 바로 확인해볼 수도 있습니다.
dig +short example.com
Vercel 대역의 IP(216.198.79.x, 64.29.17.x 등)가 나오면 제대로 붙은 겁니다. 만약 104.x.x.x나 172.67.x.x가 나온다면 주황 구름이 아직 켜져 있는 것입니다. 6번으로 돌아가세요.
아무것도 나오지 않는다면 레코드가 아직 저장되지 않았거나 Name을 잘못 적은 경우입니다.
6. Vercel에서 연결 상태 확인하기
다시 Vercel의 Domains 화면으로 돌아옵니다. DNS가 제대로 반영되면 Valid Configuration으로 바뀝니다.

Cloudflare에서 산 도메인은 네임서버가 이미 Cloudflare라서 DNS 자체는 보통 몇 분 안에 반영됩니다. 그보다 조금 더 걸리는 건 HTTPS 인증서입니다.
http://로는 열리는데 https://에서만 연결이 끊긴다면 인증서를 발급받는 중일 가능성이 큽니다. 저도 서브도메인 하나가 이 상태로 몇 분 머물렀습니다. 보통은 기다리면 해결되고, 10분이 넘도록 그대로면 Vercel 도메인 화면에서 Refresh를 눌러 재발급을 시도해 볼 수 있습니다.
curl -sI https://example.com | head -1
HTTP/2 200이 돌아오면 끝난 겁니다.
이제 프로젝트명.vercel.app뿐 아니라 구매한 도메인으로도 같은 서비스에 접속할 수 있습니다.
| 서브도메인도 같이 붙이는 경우
저는 이번에 루트 도메인 하나와 서브도메인 두 개를 함께 붙였습니다.
example.com
dev.example.com
blog.example.com
Vercel의 Add Domains 모달에서는 여러 개를 한 번에 입력할 수 있고, 한 프로젝트에 여러 도메인을 붙여 같은 배포를 바라보게 할 수 있습니다.
Cloudflare 쪽에서는 그만큼 레코드를 추가하면 됩니다. Name만 @, dev, blog로 달라지고 Value는 같습니다. 물론 셋 다 회색 구름이어야 합니다.
한 프로젝트가 여러 호스트를 받게 되면, 애플리케이션에서 "지금 어떤 호스트로 들어온 요청인가"를 보고 화면을 나누게 됩니다. 그렇다면 다음 이야기로 자연스럽게 이어집니다.
| 연결이 끝이 아니었습니다
솔직하게 덧붙이자면, 저는 Valid Configuration을 보고 다 끝났다고 생각했습니다. 그런데 실제로 사이트를 눌러보니 내부 링크들이 404를 뱉고 있었습니다.
원인은 이랬습니다. 도메인을 붙이기 전에는 호스트가 하나였기 때문에 지면을 경로로 나누고 있었습니다.
프로젝트명.vercel.app/blog/글주소
그런데 도메인을 붙이면서 지면을 호스트로 나누게 됐습니다.
blog.example.com/글주소
화면이 만들어내는 링크는 여전히 예전 방식대로 /blog/글주소를 적고 있었고, 그게 blog.example.com에서 한 번 더 붙어 /blog/blog/글주소가 되면서 전부 404가 난 것이었습니다.
무서운 점은 로컬에서는 멀쩡했다는 것입니다. 로컬은 호스트가 하나라 예전 경로가 그대로 통했거든요. 도메인이 붙은 프로덕션에서만 깨졌습니다.
그래서 이 글을 보시는 분들께 두 가지를 남기고 싶습니다.
하나, 도메인을 붙였다면 환경변수를 함께 갱신하세요. 사이트 주소를 환경변수로 들고 있다면(NEXT_PUBLIC_SITE_URL 같은 것들) 새 도메인으로 바꾸고 재배포해야 합니다. 빌드 시점에 굳는 값이라면 재배포 전까지는 옛 주소가 그대로 박혀 있습니다.
둘, 연결 직후에 링크를 한 바퀴 눌러보세요. 특히 RSS나 사이트맵처럼 절대 주소를 쓰는 곳은 멀쩡한데 화면 링크만 깨지는 식으로, 한쪽만 조용히 어긋나 있을 수 있습니다.
옛 주소가 이미 공유되어 있다면 예전 형태로 들어온 요청을 새 주소로 301/308 리다이렉트해 두는 것도 방법입니다. 읽으러 온 사람에게 404를 보여줄 이유는 없으니까요.
| 마무리
이번 글에서는 Cloudflare에서 도메인을 사고, 그 도메인을 Vercel에 배포된 프로젝트에 연결하는 과정을 정리해봤습니다.
크게 보면 순서는 이렇습니다.
Cloudflare에서 도메인 구매
→ Vercel에 도메인 등록
→ Vercel에서 DNS 값 확인
→ Cloudflare에 DNS 레코드 추가 (회색 구름!)
→ 연결 확인
→ 환경변수 갱신 & 링크 점검
처음에는 등록자 정보, DNS 레코드, 프록시 같은 낯선 말이 많아 복잡해 보이지만 실제로 하는 일은 단순합니다. "이 주소로 온 요청을 Vercel로 보내라"는 한 줄을 DNS에 적는 것이 전부입니다.
막히는 곳은 대개 정해져 있습니다. 주황 구름을 안 껐거나, Name에 도메인 전체를 적었거나, 남의 CNAME 값을 복사했거나. 셋 중 하나라면 위에서 해당하는 부분을 다시 확인해보세요.
개인 프로젝트를 실제로 공개하고 있거나 포트폴리오로 쓰고 있다면, .vercel.app에서 한 걸음 더 나아가 자기 도메인을 붙여보는 것도 좋을 것 같습니다. 저도 막상 해보니 생각보다 어렵지 않았고, 무엇보다 주소를 소개할 때의 기분이 다르더군요.
도움이 되었으면 좋겠습니다.