000%

수정

NOTES · SEO / GEO / AEO11 · 2026.10

호스팅·도메인·캐시를 운영 환경에 연결하기

페이지 생성 방식에 맞는 실행 환경을 고르고 DNS·HTTPS·CDN·방화벽을 연결한다. 원본 데이터와 저장된 응답의 갱신을 구분해 수정·철회가 전달되는 시점을 관리한다.

§ 01SEO / GEO / AEO

호스팅과 실행 환경을 데이터 갱신 방식에 맞춘다

서버 코드가 정확해도 수집기가 도메인에 연결하지 못하거나 CDN에서 이전 원고를 받으면 새 안내를 읽을 수 없다. 검색·AI는 실제 URL에서 받은 응답을 처리한다. 호스팅·도메인·캐시 설정은 그 URL이 현재의 공개 문서를 계속 전달하도록 만드는 일과 연결된다.

호스팅(hosting)은 파일이나 애플리케이션을 인터넷에서 사용할 수 있게 실행·제공하는 서비스다. 정적 호스팅은 미리 만든 파일을 제공한다. Node.js는 서버에서 JavaScript를 실행하는 환경이다. 요청마다 DB를 읽어 HTML을 만들려면 해당 기능을 지원하는 서버 런타임이나 관리형 플랫폼이 필요하다.

서버리스 함수(serverless function)는 요청이 들어올 때 코드를 실행하고 서버 운영을 플랫폼이 관리하는 방식이다. 컨테이너(container)는 코드와 실행에 필요한 파일을 묶어 배포하는 방식이다. VM(Virtual Machine)은 가상 장비이며 운영체제와 서버를 직접 관리할 수 있다. 어느 방식이든 실행 시간·메모리·동시 요청·DB 연결 제한을 확인한다.

콜드 스타트(cold start)는 새 실행 환경을 준비하느라 첫 요청이 지연되는 현상이다. 리전(region)은 서버가 배치된 지역이다. 서버와 DB 사이 거리가 멀면 조회 왕복 시간이 늘 수 있다. 페이지의 HTML 생성 시간과 DB 조회 시간을 따로 기록한 뒤 실행 지역·연결 재사용·캐시를 조정한다.

여러 서버를 운영하면 같은 공개 원고와 캐시 갱신 상태를 읽게 구성한다. 서버마다 로컬 디스크에 다른 캐시가 남으면 같은 URL이 요청마다 다른 글을 줄 수 있다. 여러 인스턴스의 캐시 공유와 재검증 전달 방식은 Next.js 자체 호스팅 안내 및 배포 플랫폼의 지원 범위에 맞춘다. 인스턴스(instance)는 실행 중인 서버 프로그램 하나를 뜻한다.

§ 02SEO / GEO / AEO

DNS와 HTTPS로 운영 주소를 연결한다

DNS(Domain Name System)는 도메인 이름을 접속할 주소로 찾는 체계다. A 레코드는 IPv4 주소, AAAA는 IPv6 주소를 연결하고, CNAME은 다른 호스트 이름을 가리킨다. TXT는 소유 확인 등 텍스트 값을 담는다. DNS 제공자의 관리 화면에서 호스팅 서비스가 요구하는 레코드를 설정한다. 도메인 루트에 CNAME과 같은 연결을 제공하는 방법은 제공자마다 다르다. 도메인과 DNS 설명을 참고한다.

TTL(Time To Live)은 DNS 응답을 얼마 동안 재사용할 수 있는지 나타내는 시간이다. 주소를 변경해도 이전 레코드를 저장한 요청자는 TTL이 남아 있는 동안 이전 서버에 연결할 수 있다. 전환 전에 새 서버에서 대표 도메인을 받을 준비를 하고, 전환 뒤에는 이전·새 연결이 모두 의도한 페이지를 제공하는지 확인한다. AAAA를 등록했다면 IPv6 경로도 확인한다.

HTTPS는 TLS(Transport Layer Security)로 보호하는 HTTP 통신이다. 인증서(certificate)는 접속한 도메인의 신원 확인에 사용된다. 운영 도메인과 www 등 실제 접속 이름이 인증서에 포함돼 있는지, 유효 기간과 자동 갱신이 정상인지 확인한다. 인증서 오류가 나면 브라우저나 수집기가 본문을 받기 전에 연결을 중단할 수 있다. TLS 설명에 연결 보호와 인증서의 역할이 정리돼 있다.

대표 주소는 HTTPS로 정하고 HTTP·www 변형은 정한 주소로 영구 이동시킨다. DNS는 연결할 서버를 지정하고, HTTP 리다이렉트는 방문자가 이동할 URL을 지정한다. 호스팅의 도메인 설정과 리다이렉트 설정을 각각 확인한다. 이미지·CSS·스크립트 주소도 HTTPS로 맞춰 보안 연결 안에서 HTTP 자원을 불러오는 혼합 콘텐츠 문제를 줄인다.

§ 03SEO / GEO / AEO

CDN·프록시·WAF가 공개 문서를 통과시키게 한다

리버스 프록시(reverse proxy)는 서버 앞에서 요청을 받아 내부 서버에 전달하는 중계 서버다. 로드 밸런서(load balancer)는 요청을 여러 서버에 나눈다. CDN의 엣지(edge)는 사용자 가까이에서 요청을 처리하는 지점이다. 플랫폼이 이 역할들을 함께 제공할 수 있으므로 현재 요청이 통과하는 서비스부터 그린다.

WAF(Web Application Firewall)는 HTTP 요청을 검사하고 공격으로 판단한 요청을 차단하는 방화벽이다. 레이트 리밋(rate limit)은 일정 시간의 요청 수를 제한한다. 봇 챌린지(challenge)는 사람의 클릭이나 브라우저 코드 실행을 요구하는 확인 화면이다. 공개 글 앞에 이 화면이 나오면 수집기는 기사 대신 확인 안내를 받을 수 있다.

CDN·WAF의 요청 로그에서 차단된 경로·시각·규칙·상태 코드를 찾는다. 공개 글과 robots.txt·사이트맵·필요한 이미지가 정상 전달되도록 해당 규칙을 조정한다. 관리자·초안에 대한 인증과 공격 차단은 유지한다. 검색 봇을 허용할 때는 이름 문자열만 믿지 말고 운영자가 제공한 IP 범위나 검증 방법을 적용한다.

Google 요청은 공식 IP 목록과 대조하거나 역방향 DNS로 이름을 찾은 뒤 정방향 DNS 결과가 원래 IP와 같은지 확인할 수 있다. Google 수집기 검증 방법에 봇 종류별 확인 방법이 있다. User-Agent는 요청 프로그램이 보내는 식별 문자열이라 다른 프로그램도 같은 이름을 보낼 수 있다.

프록시가 전달하는 호스트·프로토콜 정보를 사용할 때는 신뢰하는 프록시의 값만 처리한다. 대표 URL은 확정한 운영 도메인 설정에서 만든다. CDN이나 프록시가 오류 응답을 200으로 바꾸거나 모든 없는 경로를 홈으로 돌리는 설정도 확인한다. 원본 서버와 앞단 응답이 다르면 어느 단계가 상태 코드·헤더·본문을 바꿨는지 비교한다.

예를 들어 브라우저에서는 확인 버튼을 누른 뒤 글이 열려도, 자동 수집 요청에는 그 확인 화면만 반환될 수 있다. 이 경우 SSR로 본문을 만들어 둬도 수집기에 도달하지 않는다. 원본 서버의 200과 CDN을 거친 403 또는 확인 HTML을 비교하면, 본문 생성 코드와 접근 차단 중 어디를 고쳐야 하는지 구분할 수 있다.

§ 04SEO / GEO / AEO

상태 코드로 문서·이동·오류를 정확히 응답한다

상태 코드는 HTTP 요청의 결과를 세 자리 숫자로 전달한다. 정상 글은 본문과 함께 200, 영구 이동은 301 또는 308, 없는 문서는 404를 사용한다. 410은 자원이 영구히 사라졌음을 뜻한다. 서비스의 삭제 정책과 프레임워크 지원에 맞춰 선택한다.

소프트 404(soft 404)는 상태는 200인데 내용이 없는 문서나 오류 안내처럼 보이는 경우다. 없는 slug를 홈 화면으로 바꾸거나 DB 오류를 빈 글로 처리하면 생길 수 있다. 실제 문서 없음과 일시적인 조회 실패를 구분해 응답한다. Google의 상태 코드 처리는 각 코드가 수집에 미치는 영향을 설명한다.

일시적인 서버 장애는 5xx 계열로 전달하고 오류 원인을 복구한다. 요청량 제한은 429, 임시 서비스 중단은 상황에 맞는 503을 사용할 수 있다. Retry-After 헤더는 다시 요청하기까지 기다릴 시간이나 시각을 알린다. 제한이 반복되면 정상 수집도 줄어들 수 있으므로 오류율과 처리 용량을 함께 확인한다.

상태 코드로 문서·이동·오류를 정확히 응답한다
200
뜻
요청 성공
구성·확인 방법
본문이 실제 글인지 확인
301·308 / 302·307
뜻
영구 이동 / 임시 이동
구성·확인 방법
Location과 최종 문서, 이동 횟수 확인
304
뜻
저장한 응답이 아직 유효함
구성·확인 방법
조건부 요청의 ETag·Last-Modified와 비교
401·403
뜻
인증 필요 / 접근 거부
구성·확인 방법
공개 글에 로그인·차단 규칙이 걸렸는지 확인
404·410
뜻
문서 없음 / 영구 제거
구성·확인 방법
오류 화면과 실제 상태 코드 일치
429·5xx
뜻
요청 제한·서버 오류
구성·확인 방법
WAF·서버·DB 로그에서 원인과 반복 범위 확인
§ 05SEO / GEO / AEO

캐시 저장 위치와 갱신 조건을 정한다

캐시는 브라우저, CDN, 애플리케이션의 데이터 조회와 페이지 생성 결과에 각각 존재할 수 있다. 캐시 키(cache key)는 저장한 결과를 찾는 기준이다. URL 외에 언어·사용자·쿼리에 따라 응답이 달라지면 그 차이를 키에 반영하거나 공유 저장을 피한다. Cache-Control은 HTTP 캐시를 제어하고, 프레임워크 내부 데이터 캐시는 별도 설정으로 갱신한다.

max-age는 응답을 새것으로 재사용할 수 있는 초 단위 기간이고, s-maxage는 CDN 같은 공유 캐시에 적용하는 기간이다. private는 사용자별 캐시에만 저장하도록 하고, no-store는 응답 저장을 금지한다. no-cache는 저장할 수 있지만 재사용 전에 서버에 유효성을 확인하게 한다. 이름이 비슷해도 동작이 다르므로 HTTP 캐시 설명에 따라 응답 헤더를 선택한다.

ETag는 응답 버전을 식별하는 검증 값이고 Last-Modified는 수정 시각이다. 저장한 값으로 조건부 요청을 보냈을 때 내용이 같으면 서버는 304를 반환할 수 있다. Vary는 어떤 요청 헤더에 따라 응답이 달라지는지 캐시에 알린다. 플랫폼이 요구하는 Vary 값을 임의로 지우면 서로 다른 요청의 응답이 섞일 수 있다. HTTP 캐시 표준에서 검증과 저장 조건을 확인한다.

stale-while-revalidate는 일정 범위에서 이전 응답을 보내면서 뒤에서 갱신하는 조건이다. immutable은 유효 기간 중 내용이 바뀌지 않는 자원에 사용하는 지시다. 내용 해시가 파일명에 들어간 공개 CSS·JavaScript에는 긴 캐시가 적합할 수 있다. 수정·철회해야 하는 본문이나 사진은 허용할 잔존 시간과 무효화 방법을 먼저 정한다.

재검증(revalidation)은 저장한 내용이 여전히 유효한지 확인하거나 새 결과를 만드는 작업이다. 무효화(invalidation)·퍼지(purge)는 이전 캐시를 더 사용하지 않게 처리하는 일이다. CMS 게시 후 상세·목록·사이트맵에 해당하는 데이터와 페이지 캐시를 갱신하고, 외부 CDN이 별도로 저장한다면 그 갱신도 연결한다. Next.js 캐시 안내를 설치 버전에 맞춰 적용한다.

철회 직후 접근을 막아야 하는 자료는 캐시가 남아 있는 상태에서도 공개 판정을 거치게 설계한다. 이전에 브라우저가 내려받은 파일까지 서버가 회수할 수는 없다. 서버와 CDN에서 새 요청에 반환할 내용과 차단 시점을 정하고, 여러 지역과 첫 요청·재요청에서 확인한다.

운영 시간이 17시에서 16시로 바뀌었는데 CDN이 이전 HTML을 반환하면, 변경 뒤 방문한 수집기도 17시를 읽는다. 사이트의 dateModified만 오늘로 바꿔도 전달하는 사실은 여전히 옛 값일 수 있다. 저장 후 캐시를 갱신하고 실제 응답의 시간과 revision을 확인하는 이유다. 그 뒤 외부 검색의 최근 수집 시각과 인용된 원문을 비교한다.

§ 06SEO / GEO / AEO

환경변수·배포·로그를 운영 주소에 맞춘다

환경변수(environment variable)는 코드 밖에서 주입하는 설정 값이다. 운영 도메인, DB 접속 주소, 저장소 키 등을 개발·미리보기·운영 환경별로 구분한다. Next.js의 NEXT_PUBLIC_ 접두사가 붙은 값은 브라우저 코드에 포함될 수 있고 빌드 시 값이 고정된다. 비밀키는 서버 전용 값으로 둔다. 공개 URL을 만드는 설정은 운영 도메인과 일치시킨다.

CI(Continuous Integration)는 변경을 합칠 때 검사·빌드를 자동으로 실행하는 과정이고, CD(Continuous Delivery 또는 Deployment)는 결과물을 배포 가능한 상태로 만들거나 배포하는 과정이다. 아티팩트(artifact)는 빌드에서 만든 배포 파일이다. 검사한 결과물과 실제 배포한 결과물이 같은지 버전 식별자로 연결한다.

미리보기(preview)·스테이징(staging)은 운영 전 확인 환경이다. 운영 데이터와 비밀값의 사용 범위를 정하고 인증으로 접근을 제한한다. 이 환경의 검색 제외 설정이 운영에 복사되지 않도록 확인한다. 운영 도메인 연결을 바꾼 뒤에는 해당 도메인으로 본문·헤더·자산을 다시 요청한다.

로그(log)는 요청과 처리 결과를 남긴 기록이다. 상태 코드·경로·처리 시간·응답량·배포 버전을 기록하고, 요청 ID로 CDN·애플리케이션·DB 처리를 연결한다. 타임아웃(timeout)은 정한 시간 안에 끝나지 않아 작업을 중단한 상태다. 본문 생성이 느리면 DB 조회, 외부 API, 이미지 처리 시간을 나누어 확인한다.

모니터링(monitoring)은 오류율과 지연 등을 계속 관측하는 일이고, 알림(alert)은 정한 조건을 넘었을 때 담당자에게 알리는 기능이다. 정상 공개 글의 5xx 증가, 인증서 만료, 게시 뒤 캐시 갱신 실패를 관측한다. 장애 때 사용할 이전 배포와 DB 백업을 정하고, 복구 후 실제 공개 URL을 다시 확인한다.

§ 07SEO / GEO / AEO

공개 문서와 사용자별 응답의 캐시를 나눈다

응답이 누구에게나 같고 일정 시간의 지연을 허용하면 공유 캐시를 사용할 수 있다. 로그인 상태에 따라 달라지는 응답과 즉시 철회해야 하는 자료는 공유 저장을 피하거나 반환 전에 권한을 확인하는 구조를 선택한다. 프레임워크가 설정하는 헤더를 앞단에서 덮어쓸 때는 그 동작을 함께 검토한다.

예를 들어 사용자의 비공개 자료는 Cache-Control: private, no-store로 저장을 막을 수 있다. 내용을 바꿀 때 URL도 바뀌는 공개 자산은 긴 max-age와 immutable을 사용할 수 있다. 공개 HTML의 캐시 시간은 수정 허용 지연과 무효화 수단을 정한 뒤 선택한다. HTTP 헤더를 바꿔도 내부 DB 조회 캐시가 자동으로 갱신되는 것은 아니다.

공개 문서와 사용자별 응답의 캐시를 나눈다
공개 HTML
관측할 내용
내용 변경과 철회 시점을 기준으로 저장 기간 결정
다음 조치
상세·목록·사이트맵을 함께 갱신
해시가 붙은 공개 자산
관측할 내용
새 내용은 새 URL로 제공
다음 조치
이전 URL 잔존과 저장 비용 관리
로그인 응답·초안
관측할 내용
사용자별 접근 검사와 공유 저장 차단
다음 조치
비로그인·다른 계정 요청 대조
내부 데이터 캐시
관측할 내용
게시 버전·태그·경로를 기준으로 갱신
다음 조치
HTTP 캐시와 각각 확인
§ 08SEO / GEO / AEO

게시가 끝난 뒤 캐시를 갱신한다

실습의 현재 글 경로는 force-dynamic으로 설정해 요청마다 렌더링한다. CMS 조회를 캐시하거나 정적·ISR 경로를 운영할 때는 저장이 완료된 뒤 재검증을 호출한다. 아래 함수는 인증과 권한 검사를 마친 서버 게시 처리에서 사용한다.

// lib/refresh-guide.ts — cacheComponents: false 구성 import { revalidatePath } from 'next/cache' export function refreshGuide(slug: string) { if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug)) { throw new Error('Invalid slug') } revalidatePath(`/guides/${slug}`) revalidatePath('/') revalidatePath('/sitemap.xml') } // 순서: 사용자 권한 확인 → 게시 DB 저장 완료 → refreshGuide(slug)

revalidatePath는 해당 경로의 재검증을 요청한다. 호출 위치와 캐시 구성에 따라 다음 방문에서 갱신될 수 있다. 별도 CDN은 그 플랫폼의 무효화 경로를 사용한다. 여러 페이지가 같은 태그의 데이터를 읽으면 태그 단위 갱신도 검토한다. revalidatePath 안내의 적용 범위와 실제 첫 재요청을 비교한다.

Cache Components를 켠 구성에서는 cacheLife·cacheTag·revalidateTag·updateTag의 수명과 호출 위치를 따로 선택한다. 오래된 내용을 먼저 반환하는 재검증과 즉시 만료는 동작이 다르다. 철회 시에는 원본 서버에 도착하기 전에 CDN이 이전 문서를 반환하는지도 확인한다. 재검증 안내는 사용 중인 캐시 모델을 구분해 읽는다.

이 함수를 서버 게시 처리에서 DB 저장이 끝난 뒤 호출한다. slug를 검사한 다음 상세·홈·사이트맵의 캐시를 갱신한다. DB 저장 전에 호출하면 아직 바뀌지 않은 내용을 다시 캐시할 수 있다. 저장 후 재요청에서 이전 revision이 보이면 Next.js 캐시와 외부 CDN을 각각 확인한다. DB를 연결한 서비스에서는 게시·철회 후 상세·목록·사이트맵을 다시 요청해 공개 상태와 내용을 대조한다.

상세만 재검증하면 홈페이지의 요약이나 사이트맵 날짜는 이전 상태일 수 있다. refreshGuide가 상세·홈·사이트맵을 함께 대상으로 삼는 이유는 한 번의 게시가 바꾼 공개 출력을 함께 갱신하기 위해서다. 각 경로가 읽는 자료와 캐시가 추가되면 그 경로도 이 갱신 관계에 포함한다.

§ 09SEO / GEO / AEO

캐시 장애를 원본과 공개 응답으로 구분한다

공개 데이터 실습의 두 번째 테스트는 같은 시각의 원본 조회와 캐시 조회를 비교한다. 원본의 운영 시간이 10–16시이고 캐시가 10–17시라면 원고 저장은 성공했지만 전달 갱신이 실패한 상태다. 이때 편집자가 원고를 다시 저장하게 하는 대신 실패한 경로의 캐시를 무효화한다.

상세가 철회 후 404를 반환해도 목록과 사이트맵 캐시에는 글이 남을 수 있다. 메모리 캐시는 clearCache로 비운다. CDN을 함께 사용하면 문서 ID·revision·갱신할 경로를 게시 작업에 기록하고 CDN의 무효화 API를 호출한다. 실패한 요청은 재시도한다. 철회 직후 CDN 주소에서도 404 또는 접근 차단 응답이 나오는지 확인한다.

§ 10SEO / GEO / AEO

HTTP 저장 금지와 서버의 이미지 재사용을 함께 읽는다

이미지를 받을 때마다 변환하면 같은 원본을 반복해서 디코딩하고 인코딩한다. 서버 내부에 변환 결과를 보관하면 이 비용을 줄일 수 있다. HTTP 응답의 no-store는 응답을 받은 캐시에 저장하지 말라는 지시다. 서버가 자기 비공개 저장소에서 같은 파생 파일을 재사용하는 것과는 저장 위치와 접근 경로가 다르다. Cache-Control

이미지 실습에서 /media/photo?w=640을 두 번 요청하면 두 응답 모두 private, no-store, max-age=0을 가진다. 서버의 transforms 값은 1이다. 두 번째 요청도 이미지 바이트를 받지만 서버는 다시 변환하지 않는다. 전송량은 작은 WebP를 보낸 효과이고 서버 작업 감소는 변환 결과를 재사용한 효과다.

철회 가능한 자료는 요청마다 현재 공개 상태를 확인하는 경로가 필요하다. 이미 공개 CDN에 저장한 파일은 원본 서버의 공개 판정을 거치지 않고 나갈 수 있다. 반면 영구 공개 로고처럼 내용 해시로 주소를 고정한 자산은 장기 캐시가 전송을 줄이는 데 적합할 수 있다. 파일의 변경·철회 요구를 정하고 응답 캐시와 저장소를 선택한다.

실습 저장소의 setPublished는 프로세스 내부 상태를 바꾼다. DB를 사용하는 환경에서는 게시 트랜잭션 완료 후 새 요청이 그 상태를 읽는지 확인한다. 외부 CDN을 추가했다면 철회 후 원본·파생본 주소를 CDN 경유로도 요청해 잔존 파일과 무효화 결과를 확인한다.

— FIN —