도메인을 구매했는데 바로 열리지 않았다 — DNS 대기를 고려한 연결 자동화
도메인 구매와 DNS 설정, HTTPS 인증서 발급, 검색 등록을 자동화하며 겪은 실패를 정리했습니다. DNS 확인 이후 후속 작업을 실행하고 기존 주소를 유지하도록 연결 흐름을 바꿨습니다.
목차
들어가며
위블로그 커스텀 도메인 도입기 · 2편
위블로그에서는 사용자가 도메인을 구매하면 별도 설정 없이 자신의 블로그에 연결할 수 있도록 기능을 만들었습니다. 구매와 DNS 설정, HTTPS 인증서 발급, 구글 검색 등록까지 자동화하는 것이 목표였습니다.
하지만 테스트를 위해 도메인을 네 번 구매하는 동안 연결 과정에서 매번 다른 문제가 생겼습니다. 어떤 도메인은 한동안 주차 페이지가 보였고, 어떤 도메인은 서버 설정이 끝났는데도 접속되지 않았습니다. 새 주소가 열리기 전에 기존 블로그 주소가 새 주소로 이동해, 멀쩡하던 블로그까지 볼 수 없었던 경우도 있었습니다.
여러 문제를 추적해 보니 공통점이 있었습니다. 도메인을 구매하고 네임서버를 변경해도, 외부 DNS에서 새 설정을 확인하기까지는 시간이 필요했습니다. 그런데 초기 구현은 그 시간을 기다리지 않고 다음 작업을 실행했습니다.
이후 즉시 처리할 작업과 DNS 확인 이후 실행할 작업을 분리했습니다. 첫 테스트에서는 연결까지 38분이 걸리고 세 번 수동으로 개입했지만, 마지막 테스트에서는 11분 만에 수동 개입 없이 연결을 마쳤습니다. 두 사례의 비교이므로 모든 도메인에서 같은 시간이 걸린다는 뜻은 아닙니다.
1편 — 글은 발행됐는데 검색되지 않았다에서는 위블로그가 커스텀 도메인을 권장하게 된 배경을 다뤘습니다. 이번 글은 별도의 구현 기록입니다. 시리즈 순서는 읽는 흐름에 맞춘 것이며, 아래 개발과 테스트의 실제 진행 순서를 바꿔 서술한 것은 아닙니다.
1. 구매 완료와 연결 완료는 달랐습니다
도메인 연결은 한 번의 API 호출로 끝나는 작업이 아니었습니다.
- 도메인 구매: Dynadot에서 도메인을 등록합니다.
- DNS 설정: Cloudflare에 서버 주소를 등록하고 도메인의 네임서버를 변경합니다.
- HTTPS 설정: 새 주소로 접속할 수 있도록 Caddy 설정과 인증서를 준비합니다.
- 검색 등록: Google Search Console(GSC)에서 도메인 소유권을 확인하고 사이트맵을 제출합니다.
서로 다른 서비스가 관여하기 때문에 앞 단계의 API가 성공했다고 다음 단계도 준비됐다고 볼 수 없었습니다.
실제로 네임서버 변경 사항이 확인되기까지 걸린 시간은 테스트한 도메인마다 달랐습니다.
| 테스트 사례 | 네임서버 변경 사항을 확인하기까지 걸린 시간 |
|---|---|
| 도메인 A | 약 2분 |
| 도메인 B | 약 13분 |
둘 다 같은 연결 코드를 사용했습니다. 이 시간은 당시의 관찰값이지 DNS 변경이 항상 2~13분 안에 완료된다는 뜻은 아닙니다.
초기 구현에서는 네임서버 변경 요청 직후 Caddy 설정을 적용하고 GSC 소유권 확인도 시도했습니다. 그러나 외부 DNS에서 새 도메인 설정을 아직 찾지 못하는 상황이라면 HTTPS 인증서 발급이나 소유권 확인은 실패할 수 있습니다.
연결 준비가 끝났는지 확인한 뒤 다음 작업을 실행하도록 바꾸는 것이 필요했습니다.
2. 구매 직후에는 기다릴 필요 없는 설정만 처리했습니다
사용자가 구매 버튼을 누른 뒤 오래 기다리지 않도록, 처음 요청에서는 바로 할 수 있는 작업만 처리했습니다.
- 검색 시 확인한 가격과 실제 결제 가격이 달라졌다면 구매를 중단하고 다시 확인받습니다.
- Dynadot에서 도메인을 구매합니다.
- Cloudflare에 서버 주소를 가리키는 A 레코드를 등록합니다.
- 등록기관에 Cloudflare 네임서버 사용을 요청합니다.
- 소유권 확인용 TXT 레코드를 등록합니다.
- 남은 연결 작업은 큐에 등록하고 화면에는 ‘연결 중’ 상태를 표시합니다.
여기서 A 레코드를 준비한 다음 네임서버를 바꾸는 순서가 중요했습니다.
네임서버 변경이 먼저 반영됐는데 Cloudflare에 A 레코드가 없다면, DNS 조회에서 요청한 주소 정보가 없다는 부정 응답이 반환될 수 있습니다. 그 응답이 캐시에 남으면 레코드를 추가한 뒤에도 일부 사용자에게 접속 문제가 계속될 수 있습니다.
네임서버 변경 API의 성공 응답만 믿을 수도 없었습니다. 구매 직후 등록기관에서 도메인 준비가 끝나기 전에 변경을 요청하면, 성공 응답을 받았지만 기대한 네임서버가 실제로 설정되지 않은 사례가 있었습니다. 그래서 변경 후 설정값을 다시 조회하고 일치하지 않으면 재시도하도록 했습니다.
GSC 소유권 확인은 이 단계에서 하지 않았습니다. TXT 레코드를 등록했더라도 외부 DNS에서 새 네임서버를 아직 조회하지 못하면 구글이 해당 레코드를 확인할 수 없기 때문입니다.
3. 네임서버 변경을 확인한 뒤 HTTPS를 열었습니다
구매 요청에서 넘긴 작업은 별도의 워커가 처리합니다. 워커는 공개 DNS 서비스(1.1.1.1과 8.8.8.8)를 통해 네임서버 설정을 조회했습니다.
- 두 공개 DNS 중 어느 곳에서도 Cloudflare 네임서버가 확인되지 않으면 Caddy 설정을 적용하지 않고 재시도합니다.
- 한 곳에서 Cloudflare 네임서버가 확인되면 Caddy에 새 도메인과 기존 주소의 리다이렉트 설정을 함께 적용합니다.
- 이후 새 주소의 HTTPS 응답을 확인하고 활성화 기록과 캐시 정리를 진행합니다.
기존 구현에서는 DNS가 준비되지 않은 상태에서 Caddy가 인증서 발급을 시도한 뒤, 재시작하기 전까지 새 주소가 열리지 않았던 사례가 있었습니다. 당시 관찰한 장애는 여기에 해당하지만, 모든 환경에서 같은 실패가 영구적으로 발생한다는 뜻은 아닙니다.
또 다른 문제는 기존 주소를 너무 일찍 새 주소로 보내는 것이었습니다. 이전에는 새 도메인이 열리지 않는데도 기존 서브도메인을 새 주소로 리다이렉트해, 원래 접속할 수 있던 블로그까지 접근하기 어려워졌습니다.
네임서버 변경이 확인되기 전까지 기존 주소는 그대로 서비스하도록 순서를 바꿨습니다. 다만 리다이렉트 설정은 HTTPS 응답 확인보다 먼저 적용되므로, 인증서 준비가 늦어지는 동안의 접근 문제까지 없어진다고 보장하지는 않습니다.
워커는 당시 1분 간격으로 최대 6시간 재시도하도록 설정했습니다. 이것은 DNS가 6시간 안에 반드시 반영된다는 보장이 아니라, 그동안 자동으로 상태를 확인하기 위한 운영 정책입니다. 공개 DNS 두 곳의 확인만으로 모든 사용자의 DNS 캐시가 갱신됐다고 보장할 수 없다는 한계도 있습니다.
4. 검색엔진 등록은 별도 작업으로 처리했습니다
HTTPS 연결이 준비돼도 검색엔진 등록은 별도의 단계가 필요했습니다. GSC의 도메인 소유권을 확인하려면 구글이 DNS TXT 레코드를 읽을 수 있어야 합니다.
처음에는 도메인 구매 직후 약 18초 동안 확인을 재시도했습니다. 하지만 테스트에서 이 구간에 소유권 확인이 성공하지 않아 사용자만 더 기다리게 됐습니다.
이를 없애고 다음처럼 바꿨습니다.
| 실행 시점 | 작업 |
|---|---|
| 구매 직후 | 소유권 확인용 TXT 레코드 등록 |
| 네임서버 확인 이후 | GSC 소유권 확인 및 사이트맵 제출 시도 |
| 30분마다 | 이전 시도가 실패했거나 누락된 도메인 재처리 |
주기적인 확인을 추가한 이유는 네임서버 변경이 끝나도 구글 API 오류나 작업 중단으로 검색 등록이 실패할 수 있기 때문입니다. 실제로 자동 등록이 누락돼 수동 복구 스크립트를 실행해야 했던 사례가 있었습니다.
한 시점에서 같은 요청을 빠르게 반복하는 대신, 연결 가능 상태가 된 뒤 시도하고 실패한 작업은 나중에 다시 확인하도록 했습니다.
5. 사용자에게는 실제 접속 상태를 보여줬습니다
사용자 화면에는 ‘연결 중’ 모달을 띄우고 약 5초마다 상태를 확인하도록 했습니다.
단순히 데이터베이스의 작업 완료 여부만 읽는 대신, 서버에서 DNS와 HTTPS 상태를 조회해 실제 접근 가능 여부를 판단했습니다. 큐의 작업 상태와 사용자가 접속할 수 있는 상태는 반드시 같지 않기 때문입니다.
새 도메인 연결이 확인되기 전에는 클릭 가능한 링크로 제공하지 않았습니다. 브라우저나 다른 소프트웨어가 링크 주소를 미리 조회할 경우, 아직 준비되지 않은 DNS 응답이 캐시될 가능성을 줄이기 위해서였습니다. 연결 전에는 기존 블로그 주소를 계속 제공했습니다.
이렇게 구매 완료와 실제 서비스 가능 상태를 구분해 표시했습니다.
6. 마지막 구매 테스트에서는 수동 개입 없이 연결됐습니다
초기 테스트와 마지막 테스트의 기록은 다음과 같습니다.
| 항목 | 첫 테스트 | 마지막 테스트 |
|---|---|---|
| 연결까지 걸린 시간 | 38분 | 11분 |
| 수동 개입 | 3회 | 0회 |
| 연결을 위해 서버 재시작 | 필요 | 불필요 |
| 이전 블로그 주소 | 새 주소 문제의 영향을 받음 | 네임서버 확인 전까지 유지 |
개선 과정에서 중요했던 설정 중 하나는 등록기관 계정의 기본 네임서버를 처음부터 Cloudflare로 지정한 것입니다.
첫 테스트에서는 도메인이 잠시 등록기관의 기본 주차 페이지를 가리키는 상태로 시작했습니다. 일부 DNS 캐시에 그 응답이 남아 새 사이트 대신 주차 페이지가 표시되는 문제가 있었습니다. 초기 네임서버 설정을 바꾼 뒤에는 테스트에서 이 중간 상태를 피할 수 있었습니다.
결과가 좋아진 이유를 하나의 변경으로만 설명할 수는 없습니다. 레코드 생성 순서, 네임서버 확인, 인증서 발급 시점, 리다이렉트 전환, 주기적인 복구 작업을 함께 바꿨기 때문입니다. 첫 테스트와 마지막 테스트는 서로 다른 도메인을 사용했으므로, 소요 시간 차이 전체가 코드 개선 덕분이라고 단정하지도 않습니다.
다만 마지막 테스트에서는 도메인 연결을 마치기 위해 직접 재시작하거나 복구 스크립트를 실행할 필요가 없었습니다.
마무리하며
처음에는 도메인 구매부터 HTTPS 연결, 검색엔진 등록까지 한 번에 끝내려고 했습니다. 실제로는 DNS 설정이 외부에서 확인되기 전에 다음 작업이 시작되면서 장애가 생겼습니다.
그래서 구매 직후 처리할 작업과 외부 DNS 확인 이후 실행할 작업을 분리했습니다. 네임서버 변경이 확인되기 전까지 기존 주소를 유지하고, 검색 등록에 실패한 작업은 주기적으로 다시 처리하도록 바꿨습니다.
이 경험에서 중요했던 것은 DNS 대기 시간을 없애는 방법이 아니라, 기다리는 동안 사용자가 기존 블로그를 계속 사용할 수 있게 하고 이후 작업을 자동으로 이어가는 구조였습니다.
댓글