Full end-to-end guide for setting up your Jekyll website, pushing to a private GitHub repo, and deploying on Cloudflare Pages with enterprise security.
What is Jekyll, GitHub, and Cloudflare Pages?
Jekyll is a static site generator that transforms plain text into beautiful websites without a database. GitHub provides version control and private repository hosting for your project code. Cloudflare Pages is a lightning-fast JAMstack platform that automatically deploys your site whenever you push changes. Together, they create a secure, scalable, and maintenance-free publishing workflow perfect for developers who want full control over their web presence.
Part 1: Local Jekyll Setup (If You Haven’t Already)
Prerequisites
- Ruby installed (3.2.2+ recommended)
- Git installed
- A text editor (VS Code recommended)
Step 1: Install Ruby (if needed)
On macOS:
brew install rbenv
rbenv init
# Close and reopen terminal
rbenv install 3.2.2
rbenv global 3.2.2
ruby --version
On Windows: Download and install from https://www.ruby-lang.org/en/downloads/
On Linux:
sudo apt-get install ruby-full build-essential zlib1g-dev
ruby --version
Step 2: Install Jekyll and Bundler
gem install jekyll bundler
Step 3: Create Your Jekyll Site (or use existing)
If you already have a Jekyll site, skip to Part 2. If creating new:
jekyll new my-jekyll-site
cd my-jekyll-site
Step 4: Ensure Gemfile is Configured
Your Gemfile should look like this:
source "https://rubygems.org"
gem "jekyll", "~> 4.3.0"
gem "minima", "~> 2.5"
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.12"
gem "jekyll-seo-tag", "~> 2.8"
end
platforms :mingw, :x64_mingw, :mswin, :jemalloc do
gem "tzinfo", ">= 1", "< 3"
gem "tzinfo-data"
end
gem "wdm", "~> 0.1.1", platforms: [:mingw, :x64_mingw, :mswin]
Step 5: Test Locally
cd my-jekyll-site
bundle install
bundle exec jekyll serve
Visit http://localhost:4000 to verify everything works. Press Ctrl+C to stop the server.
Part 2: Create Gemfile.lock
This file is crucial for Cloudflare to build your site with the exact same dependencies.
cd /path/to/your/jekyll/site
bundle lock
This creates a Gemfile.lock file. Commit this to GitHub—Cloudflare needs it.
Part 3: Create GitHub Personal Access Token
You need a token to push code to GitHub from your PC.
- Go to https://github.com/settings/tokens
- Click Generate new token (classic)
- Name it something like “Jekyll Deploy”
- Under Select scopes, check:
repo(full control of private repositories)workflow(optional, for CI/CD)
- Click Generate token at the bottom
- Copy the token immediately and save it somewhere safe (you won’t see it again)
Part 4: Create Private GitHub Repository
Step 1: Create the Repo
- Go to https://github.com/new
- Repository name:
my-jekyll-site(or whatever you want) - Description: “My Jekyll website” (optional)
- Visibility: Select Private
- Initialize this repository with: Leave all unchecked (don’t add README, .gitignore, or license)
- Click Create repository
Step 2: You’ll See Instructions
GitHub will show you a page with commands. We’ll use these in the next step.
Part 5: Push Your Jekyll Site to GitHub
Step 1: Navigate to Your Jekyll Site Directory
cd /path/to/your/jekyll/site
Step 2: Initialize Git and Push
Run these commands in order (replace YOUR_USERNAME with your GitHub username):
git init
git add .
git commit -m "Initial Jekyll site commit"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/my-jekyll-site.git
git push -u origin main
Step 3: Authenticate with GitHub
When prompted for a password, paste your Personal Access Token (not your GitHub password).
Example interaction:
Username for 'https://github.com': YOUR_USERNAME
Password for 'https://YOUR_USERNAME@github.com': [paste your token here]
Step 4: Verify Upload
- Go to https://github.com/YOUR_USERNAME/my-jekyll-site
- You should see all your Jekyll files there
- Check that
GemfileandGemfile.lockare both present
Part 6: Create Cloudflare Account & Connect Domain
Step 1: Create Cloudflare Account
- Go to https://dash.cloudflare.com/signup
- Sign up with email and password
- Verify your email
Step 2: Add Your Domain (or use free .pages.dev domain)
Option A: Use Free Cloudflare Domain
- Your site will be at
your-site.pages.dev - Skip to Part 7
Option B: Add Your Own Domain
- In Cloudflare dashboard, click Add a domain
- Enter your domain name
- Select a plan (Free tier works great)
- Cloudflare will show you nameservers to add to your domain registrar
- Go to your domain registrar (Porkbun, GoDaddy, Namecheap, etc) and update nameservers
- Wait for propagation (5-30 minutes)
- Come back to Cloudflare and verify
Part 7: Connect GitHub to Cloudflare Pages
Step 1: Access Cloudflare Pages
- Go to https://dash.cloudflare.com
- In left sidebar, click Workers & Pages
- Click the Pages tab
- Click Connect to Git
Step 2: Authorize GitHub
- Click GitHub option
- You’ll be redirected to GitHub
- Click Authorize cloudflare (or Authorize Cloudflare)
- You may need to select which repositories Cloudflare can access—select your Jekyll repo
- Approve and return to Cloudflare
Step 3: Select Repository
- In the Cloudflare dashboard, under Select a repository, find and click your Jekyll repo (
my-jekyll-site) - Click Begin setup
Step 4: Configure Build Settings
You’ll see a form with these fields. Fill them in exactly:
- Project name:
my-jekyll-site(or whatever you want) - Production branch:
main - Framework preset: Select Jekyll from the dropdown
- Build command:
bundle install && bundle exec jekyll build - Build output directory:
_site
Step 5: Set Environment Variables
Click Environment variables to expand it.
Add one variable:
- Name:
RUBY_VERSION - Value:
3.2.2(or whatever version you’re using locally—check withruby --version)
Click Save to add the variable.
Step 6: Deploy
- Click Save and Deploy
- Cloudflare will start building your site (this takes 1-2 minutes)
- You’ll see a build log—look for “Build complete” message
- Once complete, you’ll get a unique URL like
my-jekyll-site.pages.dev
Step 7: Test Your Site
Click the URL provided. Your Jekyll site should be live!
Part 8: Connect Custom Domain (Optional)
If you added your own domain in Part 6:
- In Cloudflare Pages, go to your project settings
- Click Custom domains
- Click Set up a custom domain
- Enter your domain name
- Add DNS records as shown
- SSL certificate automatically provisions in 5-10 minutes
Part 9: Enterprise-Grade Security Configuration
Step 1: Enable HTTPS Everywhere
- Go to your Cloudflare dashboard → select your domain
- Click SSL/TLS in left sidebar
- Set SSL/TLS encryption mode to Full (Strict)
- Go to SSL/TLS → Edge Certificates
- Toggle Always use HTTPS → ON
- Toggle Automatic HTTPS Rewrites → ON
- Toggle HSTS → ON
- Set Max Age Header to
31536000(1 year) - Check Include subdomains
- Check Preload
- Set Max Age Header to
Step 2: Web Application Firewall (WAF)
- Click Security → WAF
- Under Managed rulesets, click Cloudflare Managed Ruleset
- Toggle it ON
- Scroll down and toggle OWASP ModSecurity Core Rule Set → ON
- Go back and toggle Additional Protection Rules → ON
Step 3: DDoS Protection
- Click Security → DDoS
- Set DDoS Sensitivity Level to High
Step 4: Bot Management
- Click Security → Bots
- Toggle Bot Fight Mode → ON (free, included)
Step 5: Security Headers
- Click Rules in left sidebar
- Click Transform Rules → Modify Response Header
- Click Create rule
Create rules to add these headers:
Rule 1:
- Name:
Add X-Content-Type-Options - When incoming requests match: (leave as “All incoming requests”)
- Header:
X-Content-Type-Options - Value:
nosniff - Click Deploy
Rule 2:
- Name:
Add X-Frame-Options - Header:
X-Frame-Options - Value:
DENY - Click Deploy
Rule 3:
- Name:
Add X-XSS-Protection - Header:
X-XSS-Protection - Value:
1; mode=block - Click Deploy
Rule 4:
- Name:
Add Referrer-Policy - Header:
Referrer-Policy - Value:
strict-origin-when-cross-origin - Click Deploy
Step 6: Content Security Policy (Optional but Recommended)
- In Transform Rules → Modify Response Header
- Click Create rule
Rule:
- Name:
Add Content-Security-Policy - Header:
Content-Security-Policy - Value:
default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: - Click Deploy
Step 7: Caching for Performance
- Click Caching in left sidebar
- Click Cache Rules
- Click Create rule
Rule for Static Assets:
- When incoming requests match:
(cf.mime_type eq "text/css" or cf.mime_type eq "application/javascript" or cf.mime_type eq "image/*") - Then: Set cache TTL to
1 year - Click Deploy
Rule for HTML:
- When incoming requests match:
(cf.mime_type eq "text/html") - Then: Set cache TTL to
1 hour - Click Deploy
Step 8: Enable Compression & Minification
- Click Speed in left sidebar
- Click Optimization
- Under Minification, toggle ON:
- Minify HTML
- Minify CSS
- Minify JavaScript
Part 10: Making Changes to Your Site
From now on, your workflow is super simple:
To Update Your Site:
- Make changes to your Jekyll site locally on your PC
-
Test locally:
bundle exec jekyll serve -
Commit and push to GitHub:
git add .git commit -m "Updated homepage"git push origin main - Cloudflare automatically detects the push, rebuilds your site, and deploys it (takes 1-2 minutes)
- Your live site updates automatically
You never have to touch Cloudflare’s dashboard again unless you want to tweak security settings.
Part 11: Troubleshooting
Build fails with “Gemfile not found”
- Make sure you committed
GemfileandGemfile.lockto GitHub - Push them again if missing:
git add Gemfile Gemfile.lock && git commit -m "Add Gemfiles" && git push
Build fails with Ruby version error
- Check your local Ruby version:
ruby --version - Update the
RUBY_VERSIONenvironment variable in Cloudflare Pages to match
Site looks broken (missing CSS/images)
- Clear your browser cache (Ctrl+Shift+Delete or Cmd+Shift+Delete)
- Wait a few minutes for cache to propagate
- Check that file paths in Jekyll are correct
GitHub authentication keeps failing
- Make sure you’re using your Personal Access Token, not your password
- Regenerate a new token if the old one expires
Cloudflare won’t connect to GitHub repo
- Make sure your GitHub repo is set to Private
- Re-authorize Cloudflare in your GitHub settings
Site is slow
- Check your Cloudflare caching rules are enabled
- Verify minification is turned on in Speed → Optimization
- Use Cloudflare’s Speed Insights tool to diagnose
Security Checklist
Before going live, verify:
- âś… GitHub repo is set to Private
- âś… HTTPS enabled with HSTS
- âś… WAF enabled with managed rulesets
- âś… DDoS protection set to High
- âś… Bot Fight Mode enabled
- âś… Security headers added (X-Content-Type-Options, X-Frame-Options, etc.)
- âś… Caching rules configured for performance
- âś… Minification enabled
- âś… SSL certificate is provisioned (green checkmark in Cloudflare)
- âś… Custom domain DNS records configured (if using custom domain)
Useful Commands Reference
Check Ruby version:
ruby --version
Check if Git is installed:
git --version
View Git remote:
git remote -v
Check Git status:
git status
View local commits:
git log --oneline
Push to GitHub:
git push origin main
Pull from GitHub:
git pull origin main
Create a new branch (for experiments):
git checkout -b my-feature-branch
git push origin my-feature-branch
Resources
- Jekyll Documentation: https://jekyllrb.com/docs/
- Cloudflare Pages: https://developers.cloudflare.com/pages/
- GitHub Docs: https://docs.github.com/
- Cloudflare Security: https://developers.cloudflare.com/fundamentals/security/