Layer 1Navigate back to the homepage

Hosting private repo on github pages

Andras Helyes
March 5th, 2017 · 2 min read

The why

I personally not a fan of having a let’s say blog site completely public. Reason being is that there is always some posts work in progress that should not be published yet.

Github does not allow to host pages of a private repository without having pro account. To overcome this, one can setup a private repository for the site source and a public one just for hosting.

1GitHub Pages is available in public repositories with GitHub Free,
2and in public and private repositories with GitHub Pro,
3GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server

This post is about one of the many workarounds that allows to have a public, hosted version of a private repository without pro account.


Let’s assume that there are two github repos:

  • public - the gh-pages branch will be hosted by github
  • private - contains all final and draft source for the blog

For the sake of simplicity - in this exercise - the private repo will have a simple index.html in it’s src folder.
In a real site, files in /public most likely will be generated by a framework, let it be Gatsby, Jekyll etc. During this exercise we’ll use a simple cp to copy files from src to public.

Private repository

This is the repo where all the work is done.

Folder structure

2│ .gitignore
4 index.html


1<!DOCTYPE html>
3 <body>
5 <h1>My awesome blog page</h1>
7 <p>My first paragraph.</p>
9 </body>


CNAME is required by github to link custom domain to repository. In the public repo, it must be sitting in the root folder, along with index.html



Files in public folder are generated, therefore should be ignored in private repository. Run echo 'public' >> .gitignore to generate it.

Linking public repository

Add a new remote to private repository. We’ll call it public.

1git remote add public<github-handle>/<remote-repo-name>.git

Run the commands below to create a gh-pages branch in public repo. This needs to be done once.

1git checkout --orphan gh-pages
2git reset --hard
3git commit --allow-empty -m "Init gh-pages branch"
4git remote -v
5git push public gh-pages
6git checkout master

Public repository

This is the repo that will be hosted github.
Do not edit files in this repository directly. Files in this repo’s gh-pages branch will be coming from the private repository.

Enabling hosting

Go to repo settings. Link will be\<gh-user>/\<repo name>/settings

Settings - Github Pages

Setting up Apex domain

Github has a detailed walkthrough to setup a domain.
However, here I just cut to the case and do the absolute minimum config necessary.

In order to point domain name to gh-pages, we need to configure an A record - some dns providers calls it ALIAS or ANAMAE - on the registars website that points to below ip addresses:


Note: everything will work fine using only one A record. The rest 3 are just redundancy, hence I’ll configure only one below.


Login to godaddy then go to domains.

Select the desired domain

Godaddy add A record

Click on manage button. On the next page scroll down and click to Manage DNS link. It’ll bring up DNS management page

Godaddy add A record

Click on ADD button on the bottom of the widget and fill out form as below

Godaddy add A record

Note: Optionally repeate it 4 times to add all 4 ip addresses.

Once it’s done, added A records show up on domain settings.

Godaddy add A record

Hallelujahh, public repo is done. From this point onward, whatever files sit in the public repo’s gh-pages branch will be available on

Check if apex domain propagated

According to my experience, the above changes apply almost immediatelly. However propagating A records might take a while.

To double check if records went live, run the below dig command.

1$ dig +noall +answer 3600 IN A

Note that the returning IP address is, the one configured during above steps.
Dig may return more records, depending how many A records have been configured.

Publishing files

Recapping what we have so far

  • a private repo with index.html and CNAME files sitting in /public folder
  • a public repo configured to host files in gh-pages branch under

Now what needs to be done is copying files from private repo /public to public repo gh-pages branch. Let’s call it deploy.

Go to private repo root folder. Branch is irrevelant.

1# cleanup
2rm -rf public
3mkdir public
4git worktree prune
5# cleanup worktree
6rm -rf .git/worktrees/public/
7# checkout public remote repo gh-pages branch into public folder
8git worktree add -B gh-pages public public/gh-pages
9# cleanup - everythign will be re-generated
10rm -rf public/*
11# copy files from src to public. In a rela project this would be `jekyll build` or `gatsby build` etc
12cp src/* public/
13cd public
14git add --all
15git commit -m "Added this and that"
16git push public gh-pages

src/index.html sitting in a private repository is now hosted on github under

Hence this post is long enough already, I’ll script the above up in a following post.

Thank you for reading.

More articles from CultOfNet

There has to be a first...

This is going to be a beggining of a beautiful friendship

October 29th, 2016 · 1 min read

Understanding npm-link. How to develop npm modules

Let's understand npm-link by working on a module

June 18th, 2018 · 2 min read
© 2019 CultOfNet
Link to $ to $