들어가며
“이제와서 시작하는 GitHub 마스터하기” 실전편의 여섯 번째 시간입니다. 이번에는 GitHub Pages를 활용하여 무료로 정적 웹사이트를 호스팅하는 방법을 알아보겠습니다. 개인 블로그부터 프로젝트 문서까지 다양하게 활용할 수 있습니다.
1. GitHub Pages란?
GitHub Pages는 GitHub 저장소에서 직접 정적 웹사이트를 호스팅하는 서비스입니다.
GitHub Pages vs 다른 호스팅 서비스
| 서비스 | 무료 제공 | 대역폭 | 커스텀 도메인 | HTTPS | 빌드 시간 | 가격 |
| GitHub Pages | 1GB 저장소 | 100GB/월 | ✅ | ✅ | 10분 | 무료 |
| Netlify | 100GB 대역폭 | 100GB/월 | ✅ | ✅ | 300분/월 | 무료/$19 |
| Vercel | 100GB 대역폭 | 100GB/월 | ✅ | ✅ | 6000분/월 | 무료/$20 |
| Cloudflare Pages | 무제한 | 무제한 | ✅ | ✅ | 500회/월 | 무료 |
| GitLab Pages | 10GB 저장소 | 무제한 | ✅ | ✅ | 400분/월 | 무료 |
주요 특징
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| 무료 호스팅:
- Public 저장소: 무제한 무료
- Private 저장소: GitHub Pro 이상에서 가능
- 대역폭: 월 100GB
- 저장 공간: 1GB
지원 기능:
- HTTPS 기본 제공
- 커스텀 도메인
- Jekyll 내장 지원
- 정적 사이트 생성기 호환
제한 사항:
- 정적 콘텐츠만 가능
- 서버사이드 코드 실행 불가
- 상업적 사용 제한
- 파일 크기: 100MB 이하
|
GitHub Pages 유형
1
2
3
4
5
6
7
8
9
| User/Organization Pages:
- URL: username.github.io
- 저장소 이름: username.github.io
- 소스: main 브랜치 루트
Project Pages:
- URL: username.github.io/repository
- 저장소 이름: 아무거나
- 소스: gh-pages 브랜치 또는 docs 폴더
|
2. 빠른 시작 가이드
개인 사이트 만들기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| # 1. 저장소 생성 (username을 본인 GitHub 사용자명으로 변경)
# 저장소 이름: username.github.io
# 2. 로컬에 클론
git clone https://github.com/username/username.github.io.git
cd username.github.io
# 3. index.html 생성
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>내 GitHub Pages 사이트</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
background: #f6f8fa;
}
.container {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
}
h1 {
color: #24292e;
border-bottom: 1px solid #e1e4e8;
padding-bottom: 0.5rem;
}
.links a {
display: inline-block;
margin: 0.5rem;
padding: 0.5rem 1rem;
background: #0366d6;
color: white;
text-decoration: none;
border-radius: 6px;
}
.links a:hover {
background: #0256c7;
}
</style>
</head>
<body>
<div class="container">
<h1>안녕하세요! 👋</h1>
<p>GitHub Pages로 만든 내 웹사이트입니다.</p>
<div class="links">
<a href="https://github.com/username">GitHub</a>
<a href="/blog">블로그</a>
<a href="/projects">프로젝트</a>
</div>
</div>
</body>
</html>
EOF
# 4. 커밋 및 푸시
git add index.html
git commit -m "Initial GitHub Pages site"
git push origin main
# 5. 몇 분 후 https://username.github.io 접속
|
프로젝트 문서 사이트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| # 1. 기존 프로젝트에서 docs 폴더 생성
mkdir docs
cd docs
# 2. 문서 페이지 생성
cat > index.md << 'EOF'
# 프로젝트 문서
## 소개
이 프로젝트는 ...
## 설치 방법
```bash
npm install my-awesome-project
```
## 사용법
```javascript
const awesome = require('my-awesome-project');
awesome.doSomething();
```
## API 문서
- [시작하기](./getting-started.md)
- [API 레퍼런스](./api-reference.md)
- [예제](./examples.md)
## 기여하기
PR은 언제나 환영입니다!
EOF
# 3. Jekyll 설정 (선택사항)
cat > _config.yml << 'EOF'
theme: jekyll-theme-minimal
title: My Awesome Project
description: 프로젝트 설명
EOF
# 4. 커밋 및 푸시
git add docs/
git commit -m "Add project documentation"
git push origin main
# 5. GitHub 저장소 Settings → Pages
# Source: Deploy from a branch
# Branch: main / docs
|
3. Jekyll로 블로그 만들기
Jekyll 기본 구조
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Jekyll 사이트 생성
gem install bundler jekyll
jekyll new my-blog
cd my-blog
# 구조
├── _config.yml # 사이트 설정
├── _posts/ # 블로그 포스트
├── _layouts/ # 레이아웃 템플릿
├── _includes/ # 재사용 가능한 조각
├── _sass/ # Sass 스타일시트
├── assets/ # CSS, JS, 이미지
├── _data/ # 데이터 파일
├── _site/ # 생성된 사이트 (gitignore)
├── index.html # 홈페이지
└── about.md # 정적 페이지
|
Jekyll 설정
_config.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| # 사이트 설정
title: 내 기술 블로그
email: your-email@example.com
description: >-
프로그래밍과 기술에 대한 이야기를 나누는 블로그입니다.
baseurl: "" # 서브경로 (예: "/blog")
url: "https://username.github.io"
twitter_username: yourusername
github_username: yourusername
# 빌드 설정
markdown: kramdown
theme: minima
plugins:
- jekyll-feed
- jekyll-seo-tag
- jekyll-sitemap
- jekyll-paginate
# 페이지네이션
paginate: 10
paginate_path: "/page:num/"
# 한국어 설정
lang: ko
timezone: Asia/Seoul
# 퍼머링크
permalink: /:year/:month/:day/:title/
# 컬렉션
collections:
projects:
output: true
permalink: /projects/:name/
# 기본값
defaults:
- scope:
path: ""
type: "posts"
values:
layout: "post"
comments: true
- scope:
path: ""
type: "projects"
values:
layout: "project"
# 제외 파일
exclude:
- Gemfile
- Gemfile.lock
- node_modules
- vendor/bundle/
- vendor/cache/
- vendor/gems/
- vendor/ruby/
- README.md
|
블로그 포스트 작성
_posts/2025-01-28-my-first-post.md:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| ---
layout: post
title: "Jekyll로 블로그 시작하기"
date: 2025-01-28 10:00:00 +0900
categories: [블로그, Jekyll]
tags: [jekyll, github-pages, blog]
author: YourName
image: /assets/images/jekyll-blog.jpg
excerpt: "GitHub Pages와 Jekyll을 사용하여 무료 블로그를 만드는 방법을 소개합니다."
---
## 들어가며
Jekyll은 정적 사이트 생성기로, GitHub Pages와 완벽하게 통합됩니다.
## 주요 기능
### 1. Markdown 지원
마크다운으로 편하게 글을 작성할 수 있습니다.
### 2. 코드 하이라이팅
```ruby
def hello
puts "Hello, Jekyll!"
end
```
### 3. 수식 지원
LaTeX 수식도 지원합니다: $$E = mc^2$$
## 이미지 삽입

## 링크
- [내부 링크](/posts/github-basic-01-intro-and-signup/)
- [외부 링크](https://jekyllrb.com)
## 결론
Jekyll과 GitHub Pages로 쉽게 블로그를 시작할 수 있습니다!
|
커스텀 레이아웃
_layouts/post.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| ---
layout: default
---
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
<header class="post-header">
<h1 class="post-title p-name" itemprop="name headline">{{ page.title | escape }}</h1>
<p class="post-meta">
<time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
{%- assign date_format = site.minima.date_format | default: "%Y년 %m월 %d일" -%}
{{ page.date | date: date_format }}
</time>
{%- if page.author -%}
• <span itemprop="author" itemscope itemtype="http://schema.org/Person">
<span class="p-author h-card" itemprop="name">{{ page.author }}</span>
</span>
{%- endif -%}
• 읽는 시간: {% include read-time.html %}
</p>
{%- if page.tags.size > 0 -%}
<p class="post-tags">
{%- for tag in page.tags -%}
<span class="tag">{{ tag }}</span>
{%- endfor -%}
</p>
{%- endif -%}
</header>
<div class="post-content e-content" itemprop="articleBody">
{{ content }}
</div>
{%- if page.comments -%}
<!-- Comments section -->
{%- endif -%}
<nav class="post-nav">
{%- if page.previous -%}
<a href="{{ page.previous.url | relative_url }}" class="prev">
← {{ page.previous.title }}
</a>
{%- endif -%}
{%- if page.next -%}
<a href="{{ page.next.url | relative_url }}" class="next">
{{ page.next.title }} →
</a>
{%- endif -%}
</nav>
<a class="u-url" href="{{ page.url | relative_url }}" hidden></a>
</article>
|
4. 현대적인 정적 사이트 생성기
2025년 정적 사이트 생성기 비교
| 생성기 | 언어 | 특징 | 빌드 속도 | 생태계 | 학습 곡선 |
| Jekyll | Ruby | GitHub 기본 지원 | 중간 | 크다 | 쉬움 |
| Hugo | Go | 매우 빠른 빌드 | 매우 빠름 | 중간 | 중간 |
| Next.js | JavaScript | React 기반 | 빠름 | 매우 크다 | 중간 |
| Gatsby | JavaScript | GraphQL 내장 | 느림 | 크다 | 어려움 |
| Astro | JavaScript | 부분 수화 | 빠름 | 성장 중 | 쉬움 |
| SvelteKit | JavaScript | 컴파일러 기반 | 빠름 | 성장 중 | 중간 |
| VitePress | JavaScript | Vue 기반 | 매우 빠름 | 중간 | 쉬움 |
GitHub Pages 배포 플로우
graph LR
A[소스 코드] --> B{생성기 선택}
B --> C[Jekyll]
B --> D[기타 SSG]
C --> E[GitHub 자동 빌드]
D --> F[로컬/CI 빌드]
E --> G[gh-pages 브랜치]
F --> G
G --> H[GitHub Pages 배포]
H --> I[CDN 배포]
I --> J[사용자 접속]
subgraph "빌드 옵션"
K[GitHub Actions]
L[로컬 빌드]
M[외부 CI/CD]
end
K --> F
L --> F
M --> F
Next.js + GitHub Pages
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // package.json
{
"name": "my-nextjs-site",
"scripts": {
"dev": "next dev",
"build": "next build",
"export": "next export",
"deploy": "npm run build && npm run export && touch out/.nojekyll && gh-pages -d out -t true"
},
"dependencies": {
"next": "^14.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"gh-pages": "^6.0.0"
}
}
|
next.config.js:
1
2
3
4
5
6
7
8
9
10
| /** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
basePath: process.env.NODE_ENV === 'production' ? '/repository-name' : '',
images: {
unoptimized: true,
},
}
module.exports = nextConfig
|
Hugo + GitHub Actions
.github/workflows/hugo.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| name: Deploy Hugo site to Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
defaults:
run:
shell: bash
jobs:
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.120.0
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup Pages
id: pages
uses: actions/configure-pages@v4
- name: Build with Hugo
env:
HUGO_ENVIRONMENT: production
HUGO_ENV: production
run: |
hugo \
--gc \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/"
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: ./public
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v3
|
Vue.js 프로젝트
vue.config.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| module.exports = {
publicPath: process.env.NODE_ENV === 'production'
? '/repository-name/'
: '/',
outputDir: 'dist',
// PWA 설정
pwa: {
name: 'My Vue App',
themeColor: '#4DBA87',
msTileColor: '#000000',
appleMobileWebAppCapable: 'yes',
appleMobileWebAppStatusBarStyle: 'black',
},
}
|
.github/workflows/deploy-vue.yml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| name: Deploy Vue.js site
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
cname: custom-domain.com # 커스텀 도메인 사용 시
|
5. 커스텀 도메인 설정
도메인 연결하기
- DNS 설정 (도메인 제공업체에서)
1
2
3
4
5
6
7
8
| # Apex 도메인 (example.com)
A @ 185.199.108.153
A @ 185.199.109.153
A @ 185.199.110.153
A @ 185.199.111.153
# 서브도메인 (www.example.com)
CNAME www username.github.io
|
- GitHub Pages 설정
CNAME 파일 생성:
또는 저장소 Settings → Pages → Custom domain
HTTPS 강제 적용
1
2
3
4
5
6
7
| # _config.yml (Jekyll)
enforce_ssl: example.com
# 또는 .htaccess (정적 사이트)
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
리다이렉트 설정
404.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Redirecting...</title>
<script>
// 커스텀 리다이렉트 로직
const redirects = {
'/old-page': '/new-page',
'/blog': '/posts',
'/about-me': '/about',
};
const path = window.location.pathname;
const redirect = redirects[path];
if (redirect) {
window.location.replace(redirect);
} else {
// 404 페이지 표시
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('error').style.display = 'block';
});
}
</script>
</head>
<body>
<div id="error" style="display: none;">
<h1>404 - Page Not Found</h1>
<p>The page you're looking for doesn't exist.</p>
<a href="/">Go Home</a>
</div>
</body>
</html>
|
6. 고급 기능 구현
검색 기능 추가
assets/js/search.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| // Lunr.js를 사용한 클라이언트 사이드 검색
(function() {
function displaySearchResults(results, store) {
const searchResults = document.getElementById('search-results');
if (results.length) {
let resultHTML = '';
results.forEach(function(result) {
const item = store[result.ref];
resultHTML += `
<li>
<h3><a href="${item.url}">${item.title}</a></h3>
<p>${item.excerpt}</p>
</li>
`;
});
searchResults.innerHTML = resultHTML;
} else {
searchResults.innerHTML = '<li>검색 결과가 없습니다.</li>';
}
}
function getQueryVariable(variable) {
const query = window.location.search.substring(1);
const vars = query.split('&');
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split('=');
if (pair[0] === variable) {
return decodeURIComponent(pair[1].replace(/\+/g, '%20'));
}
}
}
const searchTerm = getQueryVariable('query');
if (searchTerm) {
document.getElementById('search-box').setAttribute('value', searchTerm);
// 검색 인덱스 로드
fetch('/search-index.json')
.then(response => response.json())
.then(data => {
const idx = lunr(function () {
this.field('id');
this.field('title', { boost: 10 });
this.field('author');
this.field('category');
this.field('content');
data.forEach(function (doc) {
this.add(doc);
}, this);
});
const results = idx.search(searchTerm);
displaySearchResults(results, data);
});
}
})();
|
댓글 시스템 통합
_includes/comments.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| <!-- Utterances (GitHub Issues 기반) -->
<script src="https://utteranc.es/client.js"
repo="username/username.github.io"
issue-term="pathname"
theme="github-light"
crossorigin="anonymous"
async>
</script>
<!-- 또는 Giscus (GitHub Discussions 기반) -->
<script src="https://giscus.app/client.js"
data-repo="username/username.github.io"
data-repo-id="REPO_ID"
data-category="Comments"
data-category-id="CATEGORY_ID"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="light"
data-lang="ko"
crossorigin="anonymous"
async>
</script>
|
Analytics 추가
_includes/analytics.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| <!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
<!-- Cloudflare Web Analytics -->
<script defer src='https://static.cloudflareinsights.com/beacon.min.js'
data-cf-beacon='{"token": "YOUR_TOKEN"}'></script>
<!-- 개인정보 보호를 위한 옵션 -->
<script>
// IP 익명화
gtag('config', 'G-XXXXXXXXXX', { 'anonymize_ip': true });
// Do Not Track 존중
if (navigator.doNotTrack === "1") {
window['ga-disable-G-XXXXXXXXXX'] = true;
}
</script>
|
7. 성능 최적화
이미지 최적화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <!-- 반응형 이미지 -->
<picture>
<source media="(max-width: 640px)"
srcset="/assets/images/hero-mobile.webp"
type="image/webp">
<source media="(max-width: 640px)"
srcset="/assets/images/hero-mobile.jpg"
type="image/jpeg">
<source srcset="/assets/images/hero-desktop.webp"
type="image/webp">
<img src="/assets/images/hero-desktop.jpg"
alt="Hero Image"
loading="lazy"
decoding="async">
</picture>
|
리소스 최적화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <!-- 중요 CSS 인라인 -->
<style>
/* Critical CSS */
body { margin: 0; font-family: -apple-system, sans-serif; }
.header { background: #24292e; color: white; padding: 1rem; }
</style>
<!-- 나머지 CSS 비동기 로드 -->
<link rel="preload" href="/assets/css/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/assets/css/main.css"></noscript>
<!-- JavaScript 지연 로드 -->
<script defer src="/assets/js/main.js"></script>
<!-- 리소스 힌트 -->
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
Service Worker로 오프라인 지원
sw.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| const CACHE_NAME = 'site-cache-v1';
const urlsToCache = [
'/',
'/assets/css/main.css',
'/assets/js/main.js',
'/offline.html',
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response;
}
return fetch(event.request).then(response => {
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
const responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
});
})
.catch(() => {
return caches.match('/offline.html');
})
);
});
|
8. 문제 해결
빌드 오류 해결
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| # Jekyll 빌드 오류 시
# .github/workflows/jekyll.yml
name: Build and Deploy
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: true
- name: Build site
run: bundle exec jekyll build
env:
JEKYLL_ENV: production
- name: Test site
run: |
bundle exec htmlproofer ./_site \
--disable-external \
--check-html \
--allow_hash_href
|
일반적인 문제들
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| 페이지가 나타나지 않음:
- GitHub Pages 활성화 확인
- 브랜치 이름 확인 (main vs master)
- index.html 또는 README.md 존재 확인
- 몇 분 대기 (최대 10분)
404 오류:
- baseurl 설정 확인
- 파일 경로 대소문자 확인
- .nojekyll 파일 추가 (Jekyll 비활성화)
CSS/JS 로드 실패:
- 상대 경로 사용: {{ "/assets/css/style.css" | relative_url }}
- HTTPS 혼합 콘텐츠 확인
- 캐시 비우기
빌드 실패:
- _config.yml 문법 확인
- Gemfile.lock 삭제 후 재빌드
- 플러그인 호환성 확인
|
2025년 GitHub Pages 최적화 팁
성능 최적화 체크리스트
| 최적화 항목 | 설명 | 효과 | 구현 난이도 |
| 이미지 최적화 | WebP, AVIF 형식 사용 | 50-80% 크기 감소 | 쉬움 |
| CDN 활용 | Cloudflare 연동 | 전 세계 빠른 로딩 | 중간 |
| Asset 압축 | Brotli 압축 | 20-30% 크기 감소 | 쉬움 |
| 코드 분할 | 페이지별 번들 | 초기 로딩 개선 | 중간 |
| PWA 구현 | 오프라인 지원 | UX 크게 개선 | 어려움 |
| 캐시 전략 | 브라우저 캐싱 | 재방문 속도 향상 | 쉬움 |
GitHub Pages 활용 사례
| 프로젝트 유형 | 예시 | 적합한 생성기 | 특징 |
| 개인 블로그 | 기술 블로그 | Jekyll, Hugo | SEO 최적화 |
| 포트폴리오 | 개발자 포트폴리오 | Next.js, Gatsby | 인터랙티브 |
| 문서 사이트 | API 문서 | VitePress, Docusaurus | 검색 기능 |
| 랜딩 페이지 | 제품 소개 | Astro, 11ty | 빠른 로딩 |
| 온라인 이력서 | CV/Resume | 순수 HTML/CSS | 간단함 |
마무리
GitHub Pages는 정적 웹사이트를 호스팅하는 가장 쉽고 빠른 방법입니다.
핵심 포인트:
- 무료이면서도 안정적인 호스팅
- Jekyll 내장 지원으로 쉬운 블로그 구축
- 다양한 정적 사이트 생성기 호환
- GitHub Actions와 통합으로 자동 배포
- 커스텀 도메인과 HTTPS 지원
개인 블로그, 프로젝트 문서, 포트폴리오 등 다양한 용도로 활용해보세요.
다음 편에서는 보안 설정과 모범 사례에 대해 알아보겠습니다.
📚 GitHub 마스터하기 시리즈
🌱 기초편 (입문자)
- GitHub 시작하기
- Repository 기초
- Git 기본 명령어
- Branch와 Merge
- Fork와 Pull Request
💼 실전편 (중급자)
- Issues 활용법
- Projects로 프로젝트 관리
- Code Review 잘하기
- GitHub Discussions
- Team 협업 설정
- [GitHub Pages] (현재 글)(/posts/github-practical-06-github-pages/)
🚀 고급편 (전문가)
- GitHub Actions 입문
- Actions 고급 활용
- Webhooks와 API
- GitHub Apps 개발
- 보안 기능
- GitHub Packages
- Codespaces
- GitHub CLI
- 통계와 인사이트
🏆 심화편 (전문가+)
- Git Submodules & Subtree
- Git 내부 동작 원리
- 고급 브랜치 전략과 릴리스 관리
- GitHub GraphQL API
-