GitHub pages allows you to publish a website/documentation by just pushing some markdown files on a git repository. It means that you can focus on content and not on the underlying tool, infrastructure and deployment process.
GitHub pages are based on Jekyll which allow a total control on how is rendered the content. This is great but how about private content? GitHub pages are public and no access control is possible.
To bypass this limitation, the idea is to deploy the website on Heroku (it’s free and fully managed too). For the writer it doesn’t change anything, each time new content is pushed on the branch the website will automatically be redeployed. For the readers, it will require them to be in the authorized github organization to access to the content.
Here are the steps in order to make your github pages private for free.
1. Create your Jekyll site
That goes without saying but you will need to generate at least a Jekyll
website skeleton using
jekyll new. Checkout the
documentation for more details.
All the files need to be pushed a repository from the github organization that will have access to the pages.
2. Register Jekyll Auth plugin
Jekyll Auth is a jekyll plugin that provide a simple way to add a OAuth authentication layer on top of your website.
Just add this in your
Gemfile (at the root of your repository):
Then install it with a
We are now able to generate the necessary files
bundle exec jekyll-auth new.
This commands generated three files
They will be used by Heroku to know how to deploy the app.
As these files are in the jekill folder they will be treated as a “normal” content: files will be copied to the generated website and publicly available.
As the lock file takes a snapshot of your installed ruby dependencies it may leak valuable informations to attackers.
To exclude those files, add the following line in your
You may have notice that I’ve also excluded
vendor, I will speak about this later.
3. Create an Heroku app
Now you have to create a Heroku app that will host the pages.
If you want to automatically deploy the app when new content is pushed just sync a repository to the app (Deploy pane in the app dashboard).
4. Create a GitHub OAuth app
To let only the user from the organization access to the pages an OAuth layer is added on top of the jekyll website deployed on Heroku.
In order to do that you must register a new application in your GitHub application settings.
The homepage URL is the Heroku app one (endings with
The authorization callback URL is your homepage URL +
You now have an a client ID and a client secret ID for your application.
5. Setup your Heroku app
Your pages are nearly up, just add variables to tell to the OAuth layer where to check user.
GITHUB_CLIENT_SECRET with the keys provided by
GitHub in your application page and finally set
GITHUB_ORG_ID to the name of
Those variables can be set either from the settings pane of your application or
heroku config:set command from the Heroku
6. Monitor the app doing all the job for you
Your pages will now be deployed each time you push something on the sync branch
(if defined one), else it will be each time you push on the Heroku remote
git push heroku master).
In both case you can monitor whats going on in the activity tab of you application.
You should not worry much about your app since the pushed content render
locally with a
To get back on the reason why we excluded
vendor at the beginning, it is
because when the website is generated on Heroku, Jekyll will try to find all
the possible markdown file in his path. On Heroku the installed libraries are in
the same directory as the website that cause Jekyll to fail with an error like
The described solution works without much effort and for free, but you have to be aware that the resources allocated to your website by Heroku is limited (which is totally understandable). As it is a static website it does not require many resources but Heroku dynos are paused after one our of inactivity which means that the first user that access to the website after a period of inactivity may experience a few second delay. Not terrible in this case as you are building a restricted website so your user may be sympathetic but need to be considered.