Back to Blog

Deploy Jekyll to GitHub Pages in 2026: GitHub Actions, Custom Domain & Cloudflare

DevOpsGitHub PagesJekyllGitHub ActionsCloudflareCI/CDHTTPS
Jekyll deployed to GitHub Pages with GitHub Actions CI/CD and Cloudflare CDN

GitHub Pages remains the best free static site host for developers in 2026. The catch: the built-in Jekyll builder is limited to a small set of allowed gems. The solution is a GitHub Actions workflow that builds Jekyll with full plugin support and deploys the output to GitHub Pages. This guide walks through the complete setup, from a blank repo to a custom domain served over HTTPS via Cloudflare.

Prerequisites

  • A GitHub account with a repository for your Jekyll site
  • A custom domain (optional but recommended)
  • A Cloudflare account (free tier is sufficient)
  • Ruby ≥ 3.1 and Jekyll ≥ 4.3 installed locally for testing

Step 1: Configure Jekyll for Production

Ensure _config.yml sets the correct URL:

yaml
# _config.yml url: "https://yourdomain.com" baseurl: "" plugins: - jekyll-feed - jekyll-sitemap - jekyll-seo-tag

Add a Gemfile:

ruby
source "https://rubygems.org" gem "jekyll", "~> 4.3" group :jekyll_plugins do gem "jekyll-feed" gem "jekyll-sitemap" gem "jekyll-seo-tag" end

Step 2: Create the GitHub Actions Workflow

Create .github/workflows/deploy.yml:

yaml
name: Deploy Jekyll to GitHub Pages on: push: branches: [main] workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: false jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: '3.3' bundler-cache: true # Caches gems for faster builds - name: Configure GitHub Pages uses: actions/configure-pages@v5 - name: Build with Jekyll run: bundle exec jekyll build --destination ./_site env: JEKYLL_ENV: production - name: Upload artifact uses: actions/upload-pages-artifact@v3 deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4

This workflow uses the official upload-pages-artifact + deploy-pages pattern, the recommended approach since 2024 that avoids pushing to a gh-pages branch.

Step 3: Enable GitHub Pages in Repository Settings

  1. Go to Settings > Pages
  2. Under Source, select GitHub Actions (not a branch)
  3. Save

Push to main, the workflow runs automatically and your site deploys within ~2 minutes.

Step 4: Configure a Custom Domain

4a. Create the CNAME File

Add a CNAME file to the root of your repo (no extension, plain text):

yourdomain.com

Commit and push it. GitHub Pages reads this file to know which custom domain to serve.

4b. Set the Domain in GitHub Pages Settings

In Settings > Pages > Custom domain, enter yourdomain.com and save.

Step 5: Configure DNS (Cloudflare)

In the Cloudflare dashboard for your domain, add these records:

TypeNameContentProxy
A@185.199.108.153✔ On
A@185.199.109.153✔ On
A@185.199.110.153✔ On
A@185.199.111.153✔ On
CNAMEwwwyourusername.github.io✔ On

These are GitHub's current (2026) IP addresses. The old addresses from 2016 (192.30.252.x) are deprecated.

Step 6: Enable HTTPS

Once DNS propagates (usually minutes with Cloudflare):

  1. In Settings > Pages, check Enforce HTTPS
  2. In Cloudflare SSL/TLS, set mode to Full (not Full Strict)
  3. Add a Cloudflare Redirect Rule: www.yourdomain.comhttps://yourdomain.com (301)

Step 7: Cloudflare Performance Optimizations (Free Tier)

In the Cloudflare dashboard, enable:

  • Speed > Optimization > Auto Minify: HTML, CSS, JS
  • Caching > Configuration > Browser Cache TTL: 4 hours
  • Speed > Optimization > Brotli: on

Verify Everything Works

bash
# Check DNS resolves to GitHub Pages IPs dig yourdomain.com A +short # Verify HTTPS and response headers curl -I https://yourdomain.com # Look for: strict-transport-security, cf-ray (Cloudflare edge hit)

The Result

FeatureStatus
Unlimited plugins & custom gems✔ via GitHub Actions
Custom domain✔ CNAME file + DNS
HTTPS / TLS✔ Let's Encrypt via GitHub
Global CDN✔ Cloudflare
DDoS protection✔ Cloudflare
Deploy on push✔ Auto via Actions
Cost$0

Your Jekyll site is now fully production-grade: CI/CD deploys on every push, TLS is enforced, and Cloudflare caches assets at 300+ edge nodes worldwide.

X / Twitter
LinkedIn
Facebook
WhatsApp
Telegram

About Pooya Golchian

Common questions about Pooya's work, AI services, and how to start a project together.

Get practical AI and engineering playbooks

Weekly field notes on private AI, automation, and high-performance Next.js builds. Each edition is concise, implementation-ready, and tested in production work.

Open full subscription page

Get the latest insights on AI and full-stack development.