PTENES
MODULE 6.3

🚀 GitHub Pages: Publish for Free

Get your project online in minutes—for free, with automatic HTTPS and a global CDN. Enable Pages, configure the domain, understand caching, and confirm it's online.

6
Topics
~40
Minutes
⚡
Intermediate
🌐
Deploy
1

🌐 What is GitHub Pages

Free hosting for static websites directly from your repository

🎯 GitHub Pages in 30 seconds

You have HTML/CSS/JS files on GitHub. Pages serves them as a public site with its own URL, automatic HTTPS, and a global CDN — without paying anything or setting up a server.

REPO index.html style.css git push BUILD GitHub Actions CDN HTTPS free global 🌍 WEB user .github.io 1–10 min Fastly CDN

Push → automatic build → CDN → live site. The entire process is managed by GitHub.

✓ What Pages includes (free)

  • ✓Automatic HTTPS (Let's Encrypt)
  • ✓Global CDN (Fastly)
  • ✓URL usuario.github.io/repo
  • ✓Automatic deployments with every push

✗ What Pages DOESN'T do

  • ✗Backend/server (static only)
  • ✗Database
  • ✗Node.js, PHP, Python running
  • ✗Private repos (free plan)
🆓
Free
For public repos
🔒
HTTPS
Automatic Let's Encrypt
🌍
Global CDN
Fastly ~200 PoPs
📄
Static
HTML/CSS/JS/images
2

⚙️ Enable Pages

Branch/folder or GitHub Actions — 3 paths, 1 result

A

Via web interface (easier)

  1. Open the repository on GitHub
  2. Go to Settings → Pages
  3. Under "Source," select the branch (main) and folder (/ or /docs)
  4. Click Save — wait 1-5 minutes
B

Via gh CLI (quick and automatic)

# Ativar Pages na branch main, pasta raiz
$ gh api repos/:owner/:repo/pages \
  -X POST \
  -f source='{"branch":"main","path":"/"}'

# Verificar status
$ gh api repos/:owner/:repo/pages | jq '.status, .html_url'
C

Dedicated gh-pages branch

# Criar e fazer push para branch gh-pages
$ git checkout --orphan gh-pages
$ git rm -rf .              # limpa a branch
$ cp -r dist/* .             # copia os arquivos de build
$ git add . && git commit -m "deploy: v1.0"
$ git push -u origin gh-pages

💡 Which method should you use?

For simple projects (pure HTML/CSS): the main branch + the / folder. For projects with a build step (React, Vue, etc.): GitHub Actions builds and publishes automatically. The /docs folder is useful when code and docs are in the same repo.

🌿
main branch
Simpler
📂
/docs folder
Docs + code together
🔀
gh-pages branch
Isolated deployment
⚙️
Actions
Automatic build
3

🔗 usuario.github.io URL

Default address — share it on resumes and portfolios

📁 Project site (most common)

Repo: usuario/meu-projeto

URL: usuario.github.io/meu-projeto/

Requires index.html at the root of the configured branch/folder.

👤 User site (personal portfolio)

Repo: usuario/usuario.github.io

URL: usuario.github.io

Only 1 per account. Automatically serves from the main branch.

CHECK AND INSPECT URL
# Ver a URL do Pages do repo atual
$ gh api repos/:owner/:repo/pages --jq '.html_url'

# Abrir no browser diretamente
$ gh browse                     # abre o repositório
$ gh browse --settings          # vai para Settings

# Testar com curl (headless)
$ curl -I https://usuario.github.io/meu-projeto/
# Deve retornar: HTTP/2 200
🏠
index.html
Required at the root
🚫
404.html
Custom error page
⚠️
Case sensitive
Uppercase URLs matter
🔚
Trailing slash
/repo/ ≠ /repo
4

🌍 Custom domain and CNAME

meusite.com instead of usuario.github.io — professionalism for ~R$50/year

1

Create a CNAME file in the repo

# Na raiz do branch de Pages:
$ echo "meusite.com" > CNAME
$ git add CNAME && git commit -m "chore: adiciona domínio customizado"
$ git push
2

Configure DNS at the registrar

For www (subdomain):

Tipo: CNAME
Nome: www
Valor: usuario.github.io

For apex domain (root):

Tipo: A  |  Nome: @  |  Valor: 185.199.108.153
Tipo: A  |  Nome: @  |  Valor: 185.199.109.153
Tipo: A  |  Nome: @  |  Valor: 185.199.110.153
Tipo: A  |  Nome: @  |  Valor: 185.199.111.153
3

Enable HTTPS and verify

Under Settings → Pages, configure the domain and check "Enforce HTTPS". Wait for DNS propagation (up to 48h).

# Testar propagação DNS
$ dig www.meusite.com CNAME
$ nslookup meusite.com
📄
CNAME file
Domain in the repo
🌐
DNS CNAME
Points to GitHub
⏱️
Propagation
Up to 48h
🔒
Enforce HTTPS
Automatic redirect
5

⏱️ Cache and updates

Why hasn’t the site updated? Understand and fix it in seconds

🤔 "I pushed, but the site hasn't changed!"

This happens because of caching at two layers: (1) the GitHub Pages deploy takes 1-10 minutes; (2) your browser caches the files. Wait for the build to finish and do a hard refresh.

✓ How to verify the build

  • ✓GitHub Actions tab: "pages build" workflow status
  • ✓gh run list --workflow pages in the terminal
  • ✓gh run watch monitors in real time
  • ✓Settings → Pages shows "Your site is live at..."

🛠️ Force a Browser Refresh

  • →Windows/Linux: Ctrl+Shift+R
  • →macOS: Cmd+Shift+R
  • →DevTools → Network → Disable cache (while open)
  • →Add ?v=2 in the URL to test
MONITOR DEPLOY IN REAL TIME
# Ver último run do Pages
$ gh run list --limit 3
STATUS  TITLE                           WORKFLOW       ID
✓       pages build and deployment      pages          123456789
✓       pages build and deployment      pages          123456788

# Assistir deploy em curso
$ gh run watch
Refreshing run status every 3 seconds. Press Ctrl+C to quit.
✓ build (3s)
✓ deploy (8s)
✓ Run pages build and deployment completed with 'success'
⏳
1–10 min
Build time
🔄
Hard refresh
Ctrl+Shift+R
👁️
gh run watch
Live deployment
📦
?v=2
Cache busting
6

✅ Verify that it’s live

Confirm the deploy with real commands—no assumptions

POST-DEPLOYMENT VERIFICATION CHECKLIST
# 1. Confirmar que Pages está ativo
$ gh api repos/:owner/:repo/pages --jq '{status:.status, url:.html_url}'
{"status":"built","url":"https://usuario.github.io/repo/"}

# 2. Testar HTTP status
$ curl -s -o /dev/null -w "%{http_code}" https://usuario.github.io/repo/
200

# 3. Verificar HTTPS redirect
$ curl -I http://usuario.github.io/repo/
HTTP/1.1 301 Moved Permanently
Location: https://usuario.github.io/repo/

# 4. Verificar conteúdo correto
$ curl -s https://usuario.github.io/repo/ | grep ""
<title>Meu Projeto</title>

📊 Continuous monitoring

For production projects, configure UptimeRobot (free) to ping the site every 5 minutes and email you if it goes down. Also add the status badge to the README: ![Uptime](https://img.shields.io/website?url=...)

✓ Successful deploy

  • ✓Actions shows a green circle
  • ✓curl returns HTTP 200
  • ✓HTTPS active (lock icon in browser)
  • ✓Most recent visible content

✗ Problematic deploy

  • ✗Actions shows a red X → check the logs
  • ✗404 → check whether index.html exists in the right folder
  • ✗Old site → hard refresh + wait for the CDN
  • ✗HTTPS unavailable → wait for provisioning
🟢
HTTP 200
Accessible website
🔒
HTTPS
Lock icon in the browser
📡
UptimeRobot
Free monitor
🏷️
Uptime badge
Status in the README

🎯 Module summary

What you learned

  • ✓GitHub Pages: free hosting for static websites
  • ✓3 ways to activate: branch, /docs, or gh-pages
  • ✓Default URL usuario.github.io/repo
  • ✓Custom domain with CNAME + DNS
  • ✓Cache: wait for the build + hard refresh
  • ✓Complete verification with curl and gh CLI

Next module

Your project is live—now it’s time to improve it, version releases, build a portfolio, and keep the project going over time. Course wrap-up.

Module 6.4 — Evolve and promote→