Deploying Sphinx Generated Documentation to Github Pages

Github Pages, a hosting service for static webpages, is free and easy, although run by Microsoft 1. Times are changing.

It took me a while to figure out how to use the service properly, although, retrospectively, it hasn’t been so hard. The main points were,

Create “Site Publication Repo”


No, we do not pollute our source repo (I refer to the local clone as jfasch-home) with binary content, as Github suggests. Rather, we distinguish content (which is handwritten) from artifacts that are created during the build.

This reminds me of a company I worked for many years ago:

  • They had a huge pile of incomprehensible C/C++ code.

  • They built all that in the source tree (no, not with CMake, or Meson, or Automake or anything else that can do out-of-source builds - but with another huge pile of incomprehensible Doze cmd code.).

  • They committed the build output. Yes: every build they made was a record in their version control system. The same repo that contained the source.

  • Effect: developers did not develop most of their time, but wait for VC operations. Rational Clearcase can be blamed for many things, but not for that.

  • The company does not exist anymore.

So, in parallel to the jfasch-home local copy of the upstream Github repo, I create another Github repo (cloned locally as jfasch-home-pages). The intent is to use the jfasch-home-pages/docs/ subdirectory as a deployment location for the Sphinx-generated output from jfasch-home - one commit/push per deployment.

Test that, by populating jfasch-home-pages with dummy HTML content. Ah, Jekyll: we provide static files which are not source code, technically, so we do not want Github to build our site with Jekyll. This is what the .nojekyll file tells them to - suppress build.

$ mkdir docs/
$ cat <<EOF > docs/index.html
<!DOCTYPE html>

  <p>Hmm. Appears to work.</p>
$ touch docs/.nojekyll
$ git add docs/index.html docs/.nojekyll
$ git commit -am test
$ git push

Maybe check on the Github page that the upstream content matches what we just created.

Configure Github Pages for jfasch-home-pages

Go to the upstream deployment repo on Github, Make sure you are logged in (I made that mistake and did not find the “Settings” tab :-) ). Go to the “Settings” tab.

We intend to serve content from docs/ - the Publishing Source in Github terminology -, so select “master branch / docs folder”. Scroll to the “Github Pages” section, and select that constellation.



  • You will not see the “Your site is published at …” message immediately; the Github deployment machinery takes a while.

  • If the message appears, eventually, an innocent click on the link may lead to a 404 error. Edit the URL in the bar to explicitly add .../index.html, or wait another few minutes for things to come in order (I do not have to understand why).

Time for Deployment

Everything is in place now,

  • We have a local $HOME/jfasch-home (say) clone (and its upstream repository that we work from)

  • We have an upstream repository; new revisions that are pushed are automatically deployed to pages.

  • We have its local $HOME/jfasch-home-pages clone.

Lets perform the deployment dance for the first time; this will be repeated for all further deployments. (This cries for scripting, but that’s another story.)

  1. Build homepage, locally, with Sphinx

    $ cd $HOME/jfasch-home
    $ make html
  2. (Optional) In the deployment repo, backup the docs/CNAME file

    If you don’t know what this is then you probably haven’t configured a custom subdomain for your Github Pages project. See here for how that works. This step can be added as an afterthough so lets omit it for now, remembering that we have to preserve the docs/CNAME file once we add a custom domain.

    $ cd $HOME/jfasch-home-pages
    $ cp docs/CNAME /tmp/
  3. Remove existing site, and copy new site

    $ cd $HOME/jfasch-home-pages
    $ git rm -r docs/
    $ cp -r $HOME/jfasch-home/_build/html/ docs/
    $ touch docs/.nojekyll
  4. (Optional) Restore docs/CNAME

    $ cp /tmp/CNAME docs/
  5. Deploy (i.e. commit and push)

    $ git add --all docs/
    $ git commit -am 'shiny new homepage version'
    $ git push

Wait a while. You may nervously poll the “Settings” tab of the upstream deployment repo if you want, until machinery is done.



Well ok, if you view their entry page, all that Marketingese sounds familiar.