Home DevOps GitHub Pages — The Custom Domain That Went to the Wrong Server
Beginner 3 min · July 07, 2026
GitHub Pages: Host Static Sites from Your Repository

GitHub Pages — The Custom Domain That Went to the Wrong Server

A GitHub Pages custom domain pointed to the wrong server after a CNAME file was accidentally deleted.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Production
production tested
July 07, 2026
last updated
214
articles · all by Naren
Before you start⏱ 15 min
  • Basic programming fundamentals (variables, functions, control flow)
  • No prior devops experience needed — we start from first principles
 ● Production Incident
Quick Answer

1. Push your site to a repo. 2. Go to Settings → Pages. 3. Select source branch (gh-pages or main) and folder (/root or /docs). 4. (Optional) Add a custom domain via CNAME record. GitHub serves your site automatically.

✦ Definition~90s read
What is GitHub Pages?

GitHub Pages hosts static websites directly from a GitHub repository. Push HTML/CSS/JS to a branch (gh-pages or main in a special repo), and GitHub serves it at <username>.github.io/<repo> or a custom domain.

GitHub Pages is like having a free web host built into every GitHub repo.
Plain-English First

GitHub Pages is like having a free web host built into every GitHub repo. You push your website files to a special branch, and GitHub automatically serves them to visitors. It's like dropping PDFs into a Dropbox folder and getting a URL to share — but for websites. No server setup, no hosting bills, no deployment scripts needed.

GitHub Pages is the simplest way to host a static site: push code, get a URL. It powers documentation sites, personal portfolios, project landing pages, and even full static blogs (via Jekyll). The simplicity is the killer feature: there's no server to manage, no CI/CD pipeline to configure, no hosting bill. But simplicity has edge cases: the CNAME file, 404 handling, and custom domain DNS propagation. This guide covers setup, the custom domain incident that took down a product launch, and how to avoid the most common Pages pitfalls.

Setting Up GitHub Pages With a Custom Domain

For a project site: push your static files to a gh-pages branch or the docs/ folder on main. Go to Settings → Pages → select source. Your site is live at <username>.github.io/<repo>.

For a user/organization site: create a repo named <username>.github.io. Push to main. Your site is live at https://<username>.github.io.

For a custom domain: add a CNAME record via your DNS provider pointing <yourdomain.com> to <username>.github.io. Create a CNAME file in your repo root with just your domain name: www.yourdomain.com. Or configure via Settings → Pages → Custom domain.

Enable HTTPS: GitHub Pages provides auto-renewing TLS certificates via Let's Encrypt. Check 'Enforce HTTPS' in Settings → Pages.

01_pages_setup.shBASH
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
# Create a project site (branch-based)
git checkout -b gh-pages
echo '<h1>My Project</h1>' > index.html
git add . && git commit -m 'Initial site'
git push origin gh-pages

# Create a user site (repo-based)
mkdir myusername.github.io
cd myusername.github.io
git init
echo '<h1>Hello World</h1>' > index.html
git add . && git commit -m 'Initial site'
git remote add origin git@github.com:myusername/myusername.github.io.git
git push -u origin main

# Add a custom domain
echo 'www.myproject.com' > CNAME
git add CNAME
git commit -m 'Add custom domain'
git push

# Build with Jekyll (built-in)
echo 'theme: jekyll-theme-cayman' > _config.yml
git add . && git commit -m 'Add Jekyll config'
git push
Output
Branch 'gh-pages' set up to track remote branch 'gh-pages'.
Initialized empty Git repository
[main (root-commit) a1b2c3d] Initial site
Enumerating objects: 3, done.
* [new branch] main -> main
Your site is published at https://myusername.github.io/myproject/
Custom domain www.myproject.com configured.
Don't Delete the CNAME File
The CNAME file is how GitHub maps your custom domain to your repository. If it's deleted, your custom domain returns a 404. Add a CI check: test -f CNAME to prevent accidental deletion. Also add a post-deploy.sh script that curls your domain and checks for HTTP 200.
Production Insight
For production GitHub Pages sites, set up a second deployment method as backup: Netlify or Cloudflare Pages. They can serve the same repo and act as a fallback if GitHub Pages has an issue. Use Cloudflare for DNS with proxying enabled — Cloudflare can serve a cached version of your site if the origin is down, giving you an additional protection layer.
Key Takeaway
GitHub Pages serves static sites from a branch or /docs folder. Custom domains need a CNAME file in the repo root. Enable HTTPS enforcement. Add CI checks that verify CNAME exists and the URL returns 200.
● Production incidentPOST-MORTEMseverity: high

Custom Domain Resolved to Wrong Server During Product Launch

Symptom
A team launched a product with a landing page on GitHub Pages. The CNAME file was accidentally deleted in a merge conflict resolution. DNS propagated and the custom domain resolved to a 404. The launch page was down for 3 hours.
Assumption
The DNS changes propagated correctly (checked with dig), but the site returned 404. The team assumed a GitHub Pages outage.
Root cause
1. The CNAME file in the repository root told GitHub which custom domain to serve. 2. A merge conflict during a team member's PR accidentally deleted the CNAME file. 3. Without the CNAME file, GitHub stopped serving the custom domain. 4. DNS still pointed to GitHub's servers (can't change DNS quickly). 5. Visitors hit GitHub's servers, which had no mapping from the custom domain to the repo, returning a 404. 6. The team didn't notice because the CI preview URL (github.io) still worked.
Fix
1. Identified the missing CNAME file via git log --all --full-history -- CNAME. 2. Found the merge commit that deleted it. 3. Restored the CNAME file: git revert <merge-sha> (or manually recreated it). 4. Waited 5 minutes for GitHub to detect the CNAME file and re-enable the custom domain. 5. Added a CI check: test -f CNAME && echo 'CNAME exists' || exit 1. 6. Added a post-deploy check that fetches the custom domain URL and verifies HTTP 200.
Key lesson
  • CNAME file must exist in the repo for custom domains to work.
  • A deleted CNAME file causes the custom domain to 404.
  • Add CI checks that verify CNAME exists.
  • Monitor the custom domain URL with a health check — don't rely on the github.io preview URL.
Production debug guideUse this when production is on fire3 entries
Symptom · 01
Need to host a project documentation site
Fix
Use GitHub Pages from the repo's /docs folder or gh-pages branch
Symptom · 02
Need a personal portfolio site
Fix
Create <username>.github.io repo — serves automatically from main branch
Symptom · 03
Need a custom domain
Fix
Create a CNAME record pointing to <username>.github.io, add CNAME file to repo

Key takeaways

1
GitHub Pages serves static sites from repo branches
no server needed
2
CNAME file maps custom domains
deleting it breaks the site
3
Enable 'Enforce HTTPS' for free TLS via Let's Encrypt
4
Add CI checks to verify CNAME and URL health post-deploy
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 07, 2026
last updated
214
articles · all by Naren
🔥

That's Git. Mark it forged?

3 min read · try the examples if you haven't

Previous
GitHub Issues and Projects: Track Work Beyond Code
35 / 47 · Git
Next
GitHub CLI: Manage Repositories from the Terminal