<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloudflare Pages on kenji.blog</title><link>http://kenji.blog/ko/tags/cloudflare-pages/</link><description>Recent content in Cloudflare Pages on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ko</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 12:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ko/tags/cloudflare-pages/index.xml" rel="self" type="application/rss+xml"/><item><title>Cloudflare Pages나 GitHub Pages로 Hugo 블로그를 무료로, 초고속으로 공개하는 방법</title><link>http://kenji.blog/ko/p/hugo-hosting-cloudflare-vs-github-pages/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/ko/p/hugo-hosting-cloudflare-vs-github-pages/</guid><description>&lt;img src="http://kenji.blog/p/hugo-hosting-cloudflare-vs-github-pages/img/eyecatch.jpg" alt="Featured image of post Cloudflare Pages나 GitHub Pages로 Hugo 블로그를 무료로, 초고속으로 공개하는 방법" />&lt;p>웹사이트나 블로그를 운영하는 데 있어서 표시 속도(퍼포먼스), 운영 비용, 그리고 보안은 매우 중요한 요소입니다. 예전에는 WordPress와 같은 동적 CMS(Content Management System)와 렌탈 서버의 조합이 주류를 이루었지만, 현재는 &amp;lsquo;Jamstack&amp;rsquo;이라고 불리는 아키텍처가 큰 주목을 받고 있습니다. 그 중에서도 Go 언어로 만들어진 초고속 정적 사이트 생성기(SSG)인 &amp;lsquo;Hugo&amp;rsquo;와, Cloudflare Pages나 GitHub Pages 같은 모던 호스팅 서비스를 조합하면 &lt;strong>완전 무료이면서 초고속&lt;/strong>인 블로그 환경을 구축할 수 있습니다.&lt;/p>
&lt;p>이 글에서는 Hugo를 사용한 정적 사이트를 Cloudflare Pages나 GitHub Pages에 공개하기 위한 구체적인 절차, 각 플랫폼의 아키텍처 차이, GitHub Actions를 이용한 CI/CD(지속적 통합/지속적 배포) 구축, DNS 최적화, 캐시 전략, 그리고 프라이버시를 고려한 접속 분석 도입에 이르기까지 기술적인 관점에서 매우 깊이 있게 설명합니다.&lt;/p>
&lt;hr>
&lt;h2 id="1-정적-사이트-생성기ssg와-jamstack의-기초">1. 정적 사이트 생성기(SSG)와 Jamstack의 기초
&lt;/h2>&lt;h3 id="11-왜-정적-사이트인가">1.1 왜 정적 사이트인가?
&lt;/h3>&lt;p>기존의 동적 CMS(예: WordPress)는 사용자로부터 요청이 있을 때마다 데이터베이스(MySQL 등)에 쿼리를 실행하고, 서버 사이드(PHP 등)에서 HTML을 동적으로 생성하여 반환합니다. 이 방식은 유연성이 높은 반면, 트래픽의 급증(이른바 화제성 집중이나 DDoS 공격)에 대한 내성이 낮아 캐시 서버(Redis나 Varnish)를 전면에 두는 등 인프라 구성이 복잡해지기 쉽습니다.&lt;/p>
&lt;p>반면, Jamstack(JavaScript, APIs, and Markup) 아키텍처를 채택한 정적 사이트 생성기(SSG)에서는 사전에(빌드 시에) 모든 HTML 파일, CSS, JavaScript를 생성해 둡니다. 사용자의 요청에 대해서는 이미 생성된 정적 파일을 웹 서버(또는 CDN)가 그대로 반환하기만 하므로, 압도적인 고속성과 견고한 보안을 실현할 수 있습니다.&lt;/p>
&lt;h3 id="12-hugo의-우위성">1.2 Hugo의 우위성
&lt;/h3>&lt;p>SSG에는 Next.js, Gatsby, Jekyll, Astro 등 다양한 선택지가 있지만, Hugo의 가장 큰 특징은 바로 &lt;strong>빌드 속도&lt;/strong>입니다. Go 언어의 병행 처리 혜택 덕분에, 수천에서 수만 페이지의 사이트라도 불과 몇 초 만에 빌드가 완료됩니다. 이는 CI/CD 파이프라인에서의 대기 시간을 대폭 줄여주며, 개발자 경험(DX: Developer Experience) 향상과 직결됩니다.&lt;/p>
&lt;hr>
&lt;h2 id="2-호스팅-서비스의-아키텍처-비교">2. 호스팅 서비스의 아키텍처 비교
&lt;/h2>&lt;p>Hugo로 생성한 정적 파일을 어디에 호스팅할 것인지가 다음 과제입니다. 대표적인 선택지로 Cloudflare Pages, GitHub Pages, 그리고 Netlify를 들 수 있는데, 각각 배후에 있는 네트워크 아키텍처가 다릅니다.&lt;/p>
&lt;h3 id="21-cdn과-엣지-컴퓨팅">2.1 CDN과 엣지 컴퓨팅
&lt;/h3>&lt;p>이러한 플랫폼들은 모두 글로벌하게 분산된 CDN(Content Delivery Network)을 이용하여 콘텐츠를 전송합니다. 하지만 단순한 정적 파일의 캐싱뿐만 아니라, &amp;lsquo;엣지 컴퓨팅&amp;rsquo;을 통해 요청 라우팅이나 헤더 수정을 사용자와 가장 가까운 PoP(Point of Presence)에서 실행할 수 있는지가 차별화 요소가 되고 있습니다.&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;사용자 (도쿄)&amp;#34;] --&amp;gt;|Low Latency| B[&amp;#34;엣지 노드 (NRT)&amp;#34;]
C[&amp;#34;사용자 (뉴욕)&amp;#34;] --&amp;gt;|Low Latency| D[&amp;#34;엣지 노드 (EWR)&amp;#34;]
E[&amp;#34;사용자 (런던)&amp;#34;] --&amp;gt;|Low Latency| F[&amp;#34;엣지 노드 (LHR)&amp;#34;]
B --&amp;gt; G[&amp;#34;오리진 스토리지 / 오브젝트 스토어&amp;#34;]
D --&amp;gt; G
F --&amp;gt; G
&lt;/pre>
&lt;h3 id="22-github-pages">2.2 GitHub Pages
&lt;/h3>&lt;p>GitHub Pages는 GitHub 저장소에서 직접 HTML, CSS, JavaScript 파일을 공개할 수 있는 서비스입니다. 그 배후에는 Fastly 같은 CDN이 이용되고 있어 충분한 퍼포먼스를 발휘합니다. 단, 헤더의 커스터마이즈(예: &lt;code>Cache-Control&lt;/code>이나 보안 헤더 설정)에 제약이 있는 데다, 리다이렉트 설정에는 HTML의 meta refresh나 Jekyll의 플러그인에 의존하는 등 순수한 인프라로서의 기능은 약간 부족한 편입니다.&lt;/p>
&lt;h3 id="23-cloudflare-pages">2.3 Cloudflare Pages
&lt;/h3>&lt;p>Cloudflare Pages는 Cloudflare가 자랑하는 세계 최대 규모의 Anycast 네트워크(275개 이상의 도시에 전개) 위에 구축된 정적 사이트 호스팅 서비스입니다.
HTTP/3(QUIC)의 기본 지원, 이미지 최적화, 엣지 함수(Cloudflare Workers)의 통합 등 압도적인 퍼포먼스 튜닝이 가능합니다. 또한 대역폭에 대한 과금이 없어, 아무리 트래픽이 급증해도 무료로 운영할 수 있다는 점이 큰 장점입니다.&lt;/p>
&lt;h3 id="24-netlify">2.4 Netlify
&lt;/h3>&lt;p>Netlify는 Jamstack의 선구자적인 존재로, 폼 기능, 인증(Identity), 서버리스 함수 등을 통합한 올인원 DX를 제공합니다. 그러나 무료 제공량의 대역폭(월간 100GB)을 초과하면 고액의 종량제 과금이 발생하므로, 이미지나 동영상을 많이 사용하는 블로그에서는 비용 관리에 주의가 필요합니다.&lt;/p>
&lt;hr>
&lt;h2 id="3-퍼포먼스와-지연-시간의-이론적-계산-latex에-의한-수리-모델">3. 퍼포먼스와 지연 시간의 이론적 계산 (LaTeX에 의한 수리 모델)
&lt;/h2>&lt;p>웹 퍼포먼스를 평가하는 데 있어서 지연 시간(Latency)의 감소는 가장 중요한 지표입니다. CDN(엣지)을 이용함으로써 오리진 서버에 직접 접속할 때와 비교하여 지연 시간이 얼마나 줄어드는지를 모델화해 봅시다.&lt;/p>
&lt;p>사용자의 요청이 캐시에 적중할 확률을 &amp;lsquo;캐시 적중률(Cache Hit Ratio)&amp;lsquo;이라 하고, $C$ 로 둡니다. $0 \le C \le 1$ 입니다.
오리진 서버까지의 지연 시간을 $L_{origin}$, 가장 가까운 엣지 노드까지의 지연 시간을 $L_{edge}$ 라고 합니다.&lt;/p>
&lt;p>새로운 평균 지연 시간 $L_{new}$ 는 다음의 기댓값으로 계산됩니다.&lt;/p>
$$ L_{new} = C \times L_{edge} + (1 - C) \times (L_{edge} + L_{origin}) $$&lt;p>이 식을 간략화하면 다음과 같습니다.&lt;/p>
$$ L_{new} = L_{edge} + (1 - C) \times L_{origin} $$&lt;p>예를 들어, 도쿄의 사용자가 미국 동부 해안(뉴욕)에 있는 오리진 서버에 접속할 경우, 광섬유의 물리적인 거리와 라우터에서의 처리 지연을 고려하면 $L_{origin}$ 은 약 200 ms 정도가 됩니다. 반면, Cloudflare와 같은 CDN을 이용하면 도쿄의 엣지 노드에 연결할 수 있으므로 $L_{edge}$ 는 약 10 ms 정도로 단축됩니다.&lt;/p>
&lt;p>만약 캐시 적중률이 $C = 0.95$ (95%)라고 가정하면,&lt;/p>
$$ L_{new} = 10 + (1 - 0.95) \times 200 = 10 + 0.05 \times 200 = 10 + 10 = 20 \text{ ms} $$&lt;p>이처럼 CDN 도입을 통해 평균 지연 시간을 210 ms에서 20 ms로 극적으로(약 90%) 줄이는 것이 가능해집니다.&lt;/p>
&lt;hr>
&lt;h2 id="4-github-actions를-이용한-cicd-파이프라인-구축">4. GitHub Actions를 이용한 CI/CD 파이프라인 구축
&lt;/h2>&lt;p>Hugo 블로그의 업데이트 프로세스를 자동화하기 위해, GitHub Actions를 이용한 CI/CD 파이프라인을 구축합니다. 이를 통해 로컬에서 Markdown 글을 작성하고 &lt;code>git push&lt;/code> 하기만 하면, 자동으로 빌드가 실행되어 Cloudflare Pages나 GitHub Pages에 배포됩니다.&lt;/p>
&lt;p>다음의 시퀀스 다이어그램은 글을 Push한 후 사용자에게 전송될 때까지의 전체 흐름을 보여줍니다.&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant U as &amp;#34;사용자 (작성자)&amp;#34;
participant G as &amp;#34;GitHub 저장소&amp;#34;
participant A as &amp;#34;GitHub Actions&amp;#34;
participant C as &amp;#34;Cloudflare Pages&amp;#34;
participant V as &amp;#34;방문자&amp;#34;
U-&amp;gt;&amp;gt;G: &amp;#34;git push origin main&amp;#34;
G-&amp;gt;&amp;gt;A: &amp;#34;Push 이벤트 트리거&amp;#34;
A-&amp;gt;&amp;gt;A: &amp;#34;체크아웃 및 Hugo 설정&amp;#34;
A-&amp;gt;&amp;gt;A: &amp;#34;hugo --minify (빌드)&amp;#34;
A-&amp;gt;&amp;gt;C: &amp;#34;Cloudflare Pages에 배포 (직접 업로드)&amp;#34;
C--&amp;gt;&amp;gt;A: &amp;#34;배포 URL (성공)&amp;#34;
V-&amp;gt;&amp;gt;C: &amp;#34;웹 페이지 요청&amp;#34;
C--&amp;gt;&amp;gt;V: &amp;#34;캐시된 HTML 반환 (엣지)&amp;#34;
&lt;/pre>
&lt;h3 id="41-cloudflare-pages를-위한-배포-설정-direct-upload">4.1 Cloudflare Pages를 위한 배포 설정 (Direct Upload)
&lt;/h3>&lt;p>Cloudflare Pages에는 GitHub 저장소를 연동시켜 Cloudflare의 인프라 위에서 빌드하는 방법과, GitHub Actions에서 빌드한 정적 파일을 &amp;lsquo;Direct Upload(직접 업로드)&amp;lsquo;하는 방법이 있습니다. Hugo의 버전 관리를 더 엄격하게 하고 다른 작업(테스트나 이미지 최적화 등)과 연동하고 싶다면, GitHub Actions에서 빌드하고 Direct Upload 하는 방식을 추천합니다.&lt;/p>
&lt;p>다음은 Cloudflare Pages에 배포하기 위한 &lt;code>.github/workflows/deploy.yml&lt;/code> 의 실전 예시입니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Deploy Hugo site to Cloudflare Pages&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">push&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">workflow_dispatch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build-and-deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;ubuntu-latest&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Checkout repository&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;actions/checkout@v4&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">submodules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;recursive&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fetch-depth&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Setup Hugo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;peaceiris/actions-hugo@v3&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hugo-version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;0.125.0&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">extended&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Build Hugo Site&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;hugo --minify --gc&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">HUGO_ENVIRONMENT&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;production&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Deploy to Cloudflare Pages&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;cloudflare/pages-action@v1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">apiToken&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.CLOUDFLARE_API_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">accountId&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.CLOUDFLARE_ACCOUNT_ID }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">projectName&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;your-project-name&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;public&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">gitHubToken&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.GITHUB_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>이 파이프라인에서는 &lt;code>--minify&lt;/code> 옵션으로 HTML/CSS/JS를 축소하고, &lt;code>--gc&lt;/code> 로 불필요한 파일을 삭제하고 있습니다. 이것들은 퍼포먼스 최적화의 기본입니다.&lt;/p>
&lt;hr>
&lt;h2 id="5-dns-설정-깊게-파고들기-커스텀-도메인과-cname--alias-레코드">5. DNS 설정 깊게 파고들기: 커스텀 도메인과 CNAME / ALIAS 레코드
&lt;/h2>&lt;p>독자 도메인(예: &lt;code>kenji.blog&lt;/code>)을 이용할 경우, DNS(Domain Name System)의 적절한 설정이 필수적입니다.&lt;/p>
&lt;h3 id="51-cname-레코드의-제약과-zone-apex">5.1 CNAME 레코드의 제약과 Zone Apex
&lt;/h3>&lt;p>보통 서브 도메인(예: &lt;code>www.kenji.blog&lt;/code>)을 외부 서비스로 연결할 경우에는 &lt;code>CNAME&lt;/code> 레코드를 이용합니다. 그러나 DNS의 사양(RFC 1034)에 따라 루트 도메인(Zone Apex, 네이키드 도메인이라고도 불림. 예: &lt;code>kenji.blog&lt;/code>)에는 &lt;code>CNAME&lt;/code> 레코드를 설정할 수 없습니다. 이는 Zone Apex에는 SOA(Start of Authority) 레코드나 NS(Name Server) 레코드, MX(Mail Exchange) 레코드가 반드시 존재해야 하며, CNAME은 다른 리소스 레코드와 공존할 수 없다는 규칙이 있기 때문입니다.&lt;/p>
&lt;h3 id="52-해결책-alias--aname--cname-flattening">5.2 해결책: ALIAS / ANAME / CNAME Flattening
&lt;/h3>&lt;p>이 문제를 해결하기 위해, 모던 DNS 제공업체들은 자체적인 확장 기능을 제공하고 있습니다.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>ALIAS / ANAME 레코드&lt;/strong>: DNS 서버 측에서 동적으로 이름 확인을 수행하여, 최종적인 A 레코드(IP 주소)를 클라이언트에 반환합니다. Amazon Route 53 등이 지원하고 있습니다.&lt;/li>
&lt;li>&lt;strong>CNAME Flattening&lt;/strong>: Cloudflare가 제공하는 기능입니다. Zone Apex에 CNAME을 설정한 것처럼 작동하면서, Cloudflare의 권한(Authoritative) DNS 서버가 자동으로 확인한 IP 주소들(A 레코드 및 AAAA 레코드)을 클라이언트에게 투명하게 반환합니다.&lt;/li>
&lt;/ul>
&lt;p>Cloudflare Pages를 이용할 경우, 도메인의 네임 서버를 Cloudflare에 위임하고, 이 &amp;lsquo;CNAME Flattening&amp;rsquo;을 활용하는 것이 가장 매끄럽고 고성능인 구성이 됩니다.&lt;/p>
&lt;hr>
&lt;h2 id="6-캐시-전략과-http-헤더-제어">6. 캐시 전략과 HTTP 헤더 제어
&lt;/h2>&lt;p>정적 사이트의 고속화에 있어서 또 하나의 핵심이 되는 것은 &amp;lsquo;캐시 전략&amp;rsquo;입니다. Cloudflare Pages에서는 생성된 파일(&lt;code>_headers&lt;/code> 파일)을 이용하여, HTTP 응답 헤더를 세밀하게 제어할 수 있습니다.&lt;/p>
&lt;h3 id="61-엣지-캐시edge-cache-vs-브라우저-캐시browser-cache">6.1 엣지 캐시(Edge Cache) vs 브라우저 캐시(Browser Cache)
&lt;/h3>&lt;p>캐시에는 크게 나누어 CDN 측에서 유지되는 &amp;lsquo;엣지 캐시&amp;rsquo;와 사용자의 브라우저에 저장되는 &amp;lsquo;브라우저 캐시&amp;rsquo; 2종류가 있습니다.&lt;/p>
&lt;p>정적 파일(이미지, CSS, JS 등 파일명에 해시가 포함된 것)은 브라우저 측에 장기간 캐싱시키는 것이 이상적입니다. 반면, HTML 파일은 업데이트를 즉시 반영하기 위해 브라우저 캐시를 짧게(혹은 무효화) 하고, 엣지 캐시로 처리하는 구성이 일반적입니다.&lt;/p>
&lt;p>Cloudflare Pages에서의 &lt;code>_headers&lt;/code> 설정 예시:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># HTML 파일은 브라우저 캐시를 하지 않고, 매번 검증한다
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/*.html
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=0, must-revalidate
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># 에셋 파일(CSS/JS/이미지)은 1년간 브라우저에 캐시한다
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/assets/*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=31536000, immutable
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/img/*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=31536000, immutable
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-대역폭-비용-절감-계산식">6.2 대역폭 비용 절감 계산식
&lt;/h3>&lt;p>적절한 캐시 헤더를 설정함으로써 서버(엣지)로부터의 데이터 전송량을 대폭 줄일 수 있습니다. 월간 대역폭 비용 $Cost$ 는 각 리소스의 전송량 $B_i$, 캐시 적중률 $C_i$, 그리고 대역폭 단가 $R$ 에 의해 다음과 같은 모델로 나타낼 수 있습니다.&lt;/p>
$$ Cost = \sum_{i=1}^{n} \left( B_i \times (1 - C_i) \times R \right) $$&lt;p>Cloudflare는 다운로드 전송량이 무료($R = 0$)이므로 직접적인 금전적 비용은 $0$ 이 됩니다. 그러나 GitHub Pages 등 다른 인프라를 병용하는 경우나 AWS 구성을 백엔드로 삼는 경우에는, 이 캐시 적중률 $C_i$ 를 극대화하는 것이 인프라 비용 절감의 핵심이 됩니다.&lt;/p>
&lt;hr>
&lt;h2 id="7-프라이버시와-퍼포먼스를-양립하는-접속-분석">7. 프라이버시와 퍼포먼스를 양립하는 접속 분석
&lt;/h2>&lt;p>블로그를 운영하는 데 있어서, 얼마나 많은 사용자가 방문하고 있는지를 알기 위한 접속 분석(Web Analytics)은 필수적입니다. 오랫동안 Google Analytics(GA4)가 사실상의 표준(De facto standard)이었지만, 최근의 프라이버시 보호 흐름(GDPR, CCPA)이나 서드파티 쿠키 폐지에 따라 상황이 변하고 있습니다.&lt;/p>
&lt;h3 id="71-웹-퍼포먼스에-미치는-영향">7.1 웹 퍼포먼스에 미치는 영향
&lt;/h3>&lt;p>Google Analytics(구체적으로는 &lt;code>gtag.js&lt;/code> 나 Google Tag Manager)를 도입하면, 수많은 외부 스크립트의 로딩과 실행이 발생하여 퍼포먼스(특히 TTFB나 메인 스레드 차단 시간)에 악영향을 미칩니다.&lt;/p>
&lt;p>사이트의 로드 시간을 다음과 같이 분해해서 생각해 봅시다.&lt;/p>
&lt;pre class="mermaid">
pie title 일반적인 사이트 로딩 시간 분석
&amp;#34;TTFB (첫 바이트 도달 시간)&amp;#34; : 15
&amp;#34;콘텐츠 다운로드 (HTML/CSS)&amp;#34; : 20
&amp;#34;DOM 파싱 및 렌더링&amp;#34; : 45
&amp;#34;분석 및 서드파티 JS&amp;#34; : 20
&lt;/pre>
&lt;p>서드파티의 JS 분석 도구는 전체 로딩 시간의 약 20%~30%를 차지하는 일도 드물지 않습니다.&lt;/p>
&lt;h3 id="72-cloudflare-web-analytics의-도입">7.2 Cloudflare Web Analytics의 도입
&lt;/h3>&lt;p>그래서 주목받고 있는 것이 Cloudflare Web Analytics나 Plausible Analytics 같은, 쿠키를 사용하지 않는(Cookieless) 프라이버시 퍼스트 접속 분석입니다.&lt;/p>
&lt;p>Cloudflare Web Analytics는 매우 가벼운 JavaScript 스니펫을 삽입하기만 하면 작동하며, 쿠키를 발행하지 않기 때문에 번거로운 쿠키 동의 배너(Cookie Consent Banner)를 설치할 필요가 없습니다.&lt;/p>
&lt;p>Hugo에서의 구현도 매우 간단합니다. &lt;code>layouts/partials/head.html&lt;/code> 이나 &lt;code>layouts/partials/analytics.html&lt;/code> 에 제공받은 스니펫을 추가하기만 하면 됩니다.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">{{ if eq hugo.Environment &amp;#34;production&amp;#34; }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Cloudflare Web Analytics --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">defer&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;https://static.cloudflareinsights.com/beacon.min.js&amp;#39;&lt;/span> &lt;span class="na">data-cf-beacon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;{&amp;#34;token&amp;#34;: &amp;#34;YOUR_CLOUDFLARE_BEACON_TOKEN&amp;#34;}&amp;#39;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- End Cloudflare Web Analytics --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>defer&lt;/code> 속성을 부여함으로써 HTML 파싱을 차단하지 않고 스크립트를 비동기적으로 불러와, DOM 구축 후에 실행시킬 수 있습니다. 이를 통해 초기 표시 속도(LCP: Largest Contentful Paint 나 FCP: First Contentful Paint)에 미치는 영향을 최소화할 수 있습니다.&lt;/p>
&lt;hr>
&lt;h2 id="8-요약-및-베스트-프랙티스">8. 요약 및 베스트 프랙티스
&lt;/h2>&lt;p>Hugo를 이용한 정적 사이트 운영에 있어, Cloudflare Pages나 GitHub Pages와 같은 모던 호스팅 플랫폼을 채택하는 것은 가성비, 표시 속도, 보안의 모든 측면에서 압도적인 장점이 있습니다.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>초고속 빌드&lt;/strong>: Hugo의 고속성을 살려 CI/CD 파이프라인(GitHub Actions)의 실행 시간을 최소화한다.&lt;/li>
&lt;li>&lt;strong>엣지 전송&lt;/strong>: Cloudflare의 엣지 네트워크를 이용하여 전 세계 사용자에게 밀리초 단위의 지연 시간으로 콘텐츠를 전달한다.&lt;/li>
&lt;li>&lt;strong>적절한 DNS 구성&lt;/strong>: CNAME Flattening을 활용하여 Zone Apex(독자 도메인)를 안전하고 빠르게 운영한다.&lt;/li>
&lt;li>&lt;strong>캐시 전략 최적화&lt;/strong>: &lt;code>_headers&lt;/code> 를 사용하여 브라우저 캐시와 엣지 캐시를 리소스 종류에 따라 적절하게 분리한다.&lt;/li>
&lt;li>&lt;strong>가벼운 애널리틱스&lt;/strong>: 프라이버시를 배려하면서 퍼포먼스를 손상시키지 않는 Cloudflare Web Analytics 등을 도입한다.&lt;/li>
&lt;/ol>
&lt;p>이것들을 조합함으로써 월간 수백만 PV 클래스의 대규모 트래픽도 견뎌낼 수 있는, 확장 가능하고 견고한 블로그 시스템을 무료로 구축할 수 있습니다. 기술 블로그나 기업 사이트, 포트폴리오 사이트 개설을 검토하고 계신 분들은 꼭 이 Jamstack + Hugo + Cloudflare Pages 구성을 시도해 보시기 바랍니다.&lt;/p></description></item></channel></rss>