Skip to content

How to Publish GitHub Pages from Private Repositories

GitHub Pages Private

What You Can Achieve

  • Private Repository Protection

    Keep source code private while publishing your site

  • Custom Domain Support

    Professional publishing with your own domain

  • Access Control

    Organization-only access and IP restrictions

  • Plan-Specific Features

    Understand free vs paid plan differences

📖 GitHub Pages and Private Repositories Basics

GitHub Pages is a static site hosting service, but using it with private repositories requires specific conditions.

Important Prerequisites

Plan Requirements

To use GitHub Pages with private repositories, you need one of the following:

  • GitHub Pro (for individuals)
  • GitHub Team (for organizations)
  • GitHub Enterprise (for enterprises)
  • GitHub Free for organizations (with conditions)

💰 Detailed GitHub Plan Comparison

Individual Account Plans

PlanMonthly PricePages SupportKey Features
Free$0Public onlyBasic features, unlimited public repos
Pro$4Private supportedPrivate Pages, advanced analytics, Wiki
Pro with Copilot$10+Private supportedPro + AI assistance

Organization Account Plans

PlanMonthly PricePages SupportKey Features
Free for organizations$0Public only*Basic organization features
Team$4/userPrivate supportedTeam management, SAML SSO
Enterprise$21/userPrivate supportedAdvanced security, audit logs

*Note: Educational and non-profit organizations may have special conditions for private support

🔍 How to Check Your Current Plan

1. For Individual Accounts

# Check via browser
1. Log in to GitHub
2. Click your profile picture (top right)
3. Select "Settings"
4. Click "Billing and plans" in the left sidebar
5. Check the "Current plan" section

2. For Organization Accounts

# Check from organization settings
1. Navigate to your organization page
2. Click the "Settings" tab
3. Select "Billing and plans"
4. Check "Current plan"

3. Using CLI

# Using GitHub CLI
gh api user --jq '.plan.name'

# For organizations
gh api orgs/ORG_NAME --jq '.plan.name'

🚀 Setting Up Pages with Private Repositories

Step 1: Upgrade Your Plan (if needed)

# Steps to upgrade to GitHub Pro
1. Settings  Billing and plans
2. Click "Upgrade" button
3. Select "GitHub Pro"
4. Enter payment information
5. Confirm with "Purchase"

Step 2: Create and Configure Repository

# Create a new private repository
gh repo create my-private-site --private

# Change existing repository to private
gh repo edit --visibility private

Step 3: Enable GitHub Pages

  1. Access Repository Settings

    Repository → Settings → Pages
    

  2. Select Source

    Source: Deploy from a branch
    Branch: main (or gh-pages)
    Folder: / (root) or /docs
    

  3. Verify Visibility Settings

!!! info "Important Setting Options"

   For private repositories, you'll see these options:

   - **Visibility**: Public (default)
   - The site itself will be public, but source code remains private

Step 4: Configure Custom Domain (Optional)

# Create CNAME file
echo "www.example.com" > CNAME
git add CNAME
git commit -m "Add custom domain"
git push

🔒 Security and Access Control

1. Basic Access Control

Note that with private repositories, the GitHub Pages site itself is still public!

# Key Understanding
- Repository: Private (source code hidden)
- Pages site: Public (accessible to anyone)

2. Organization-Only Access (Enterprise Only)

GitHub Enterprise Cloud allows member-only access:

# Settings → Pages → Access control
Visibility: Private
Access: Members of [organization] only

3. Authenticated Pages (Alternative Methods)

Standard GitHub Pages doesn't have authentication, consider these alternatives:

// Simple JavaScript authentication (NOT recommended)
const password = prompt("Enter password");
if (password !== "secret123") {
    window.location.href = "https://github.com";
}

More secure methods: - Use Netlify or Vercel (with authentication) - GitHub Actions + AWS S3 combination - Cloudflare Access for access control

📝 Practical Configuration Examples

1. Private Site with Jekyll

# _config.yml
title: My Private Documentation
description: Internal documentation site
baseurl: "/my-private-site"
url: "https://username.github.io"

# Build settings
markdown: kramdown
theme: minima

# Private settings
github: [metadata]
repository: username/my-private-site

2. Automated Deployment with GitHub Actions

# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/configure-pages@v4
      - uses: actions/jekyll-build-pages@v1
        with:
          source: ./
          destination: ./_site
      - uses: actions/upload-pages-artifact@v3

  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@v4

3. Private Repository Dependencies

# package.json configuration
{
  "dependencies": {
    "private-package": "git+https://${GITHUB_TOKEN}@github.com/org/private-repo.git"
  }
}

# Environment variable in GitHub Actions
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

🔧 Troubleshooting

Common Issues and Solutions

1. "GitHub Pages is not available for private repositories"

Cause: Using free plan Solution:

# Upgrade your plan
Settings  Billing  Change plan  Select "Pro"

2. Page shows 404 error

Cause: Branch or folder misconfiguration Solution:

# Verify correct branch
git branch -a

# Create gh-pages branch
git checkout -b gh-pages
git push origin gh-pages

3. Build errors occur

Cause: Jekyll configuration or Gemfile issues Solution:

# Gemfile
source "https://rubygems.org"
gem "github-pages", group: :jekyll_plugins
gem "webrick" # Required for Ruby 3.0+

# Test locally
bundle install
bundle exec jekyll serve

💡 Best Practices

1. Security Measures

# .gitignore
# Exclude sensitive files
.env
secrets/
*.key
config/production.yml

# Build artifacts
_site/
.sass-cache/
.jekyll-cache/

2. Efficient Workflow

# Branch strategy
main         Source code (private)
gh-pages     Built site (for Pages)
develop      Development work

3. Cost Optimization

# Utilize free tiers
- Public repositories: Documentation and demos
- Private repositories: Production code and sensitive data
- GitHub Actions: Use 2,000 free minutes efficiently

📊 Plan Selection Criteria

When GitHub Pro is Suitable

  • Individual developers
  • Private project portfolios
  • Small commercial sites

When GitHub Team is Suitable

  • Team development
  • Internal documentation sites
  • Client demo sites

When Enterprise is Necessary

  • Large organizations
  • Strict security requirements
  • Audit log requirements
  • SAML SSO mandatory

🌟 Alternative Solutions

Alternative methods to bypass GitHub Pages limitations:

# netlify.toml
[build]
  command = "npm run build"
  publish = "dist"

# Authentication settings
[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200
  conditions = {Role = ["admin", "member"]}

2. Vercel

// vercel.json
{
  "builds": [
    { "src": "package.json", "use": "@vercel/static-build" }
  ],
  "routes": [
    { "src": "/(.*)", "dest": "/$1" }
  ]
}

3. AWS Amplify

# amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: dist
    files:
      - '**/*'