Docs as code - Sphinx + Gitlab + Heroku

In a another post I talk about Documentation as Code, showing a list of tools for this purpose. In this post I’m going to talk about a concrete example to implement a Docs as Code workflow.

This example uses Sphinx for the site generation, GitLab for version control, and Heroku to serve the site. The process may seem scary, especially if you are not familiar with some of the tools, but with a little of patience and commitment you can make it through. Keep in mind that you only have to do this once and it will simplify your work in the long term.

Generate your website

The default Sphinx setup generates a nice HTML output, but you can further customize it and set a site theme. For my site I’m going to use the Read the Docs Theme, so I have to install it on my system.

pip install sphinx_rtd_theme

To use the theme I also need to edit the conf.py file accordingly and change the value of the html_theme variable as follows:

html_theme = 'sphinx_rtd_theme'

Now I can build my site.

make html

During the getting started phase I picked the source and the output to be in separate folders. The HTML files for my site are inside build/html. This directory is the one I need to upload to Heroku and serve it to the world, and somehow I need this to happen automatically.

For everything to work smoothly, I added a file called requirements.txt to the root folder of my project with the following content:

sphinx
sphinx_rtd_theme
pygments-style-solarized

These are the requirements for this Sphinx site to work. Of course you can change this file according to your project needs.

Set up your Heroku app

To deploy your website you need a Heroku account. If you don’t have one go to their website and sign up, then create an app. My app is called sphinx-clitest.

Later on you will also need your Heroku API key. Go to your Account settings and scroll down to the API Key section, and keep that at hand.

Create a GitLab pipeline

My version control system of choice is GitLab. It offers built-in tools for Continuous Integration and Continuous Delivery (CI/CD) Pipelines. This section explains the basic setup to create a pipeline to deploy Sphix docs.

To create the Continuous Integration pipeline we have to add a file called .gitlab-ci.yml to the repository root folder. This is the content of the file I’m using for this project:

stages:
   - build
   - deploy

build:
   stage: build
   script:
      - echo "Building static site..."
      - apt-get update -qy
      - apt-get install -y python3-dev python3-pip libxml2-dev libxslt-dev zlib1g-dev git
      - pip3 install -r requirements.txt
      - make html
   artifacts:
      paths:
         - build/html
   only:
      - master

deploy:
   stage: deploy
   script:
      - echo "Deploying site..."
      - cd build/html
      - >
         echo "<?php header( 'Location: /index.html'  ) ;  ?>" > index.php
      - echo '{}' > composer.json
      - git init
      - git config --global user.email "geri@somefakemail.com"
      - git config --global user.name "Geri Ochoa"
      - git remote add heroku https://heroku:$HEROKU_API_KEY@git.heroku.com/sphinx-citest.git
      - git add .
      - git commit -m "deploying commit"
      - git push heroku master --force
      - echo "Deployed to Production Server https://sphinx-citest.herokuapp.com"
   only:
      - master

GitLab’s CI/CD uses this yaml file to automatically deploy the site. I will explain overall the content of the file, without going too deep into details.

See also

The GitLab CI/CD getting started guide is a good starting point to learn about GitLab pipelines.

We define two stages for the CI/CD pipeline: build and deploy, each stage runs in a separate container.

Build

The build stage runs a few steps.

  1. First it updates the list of available packages

  2. Installs the required dependencies (the container is based on Ubuntu 18.04).

  3. Installs the required python packages using pip3.

  4. Finally, it builds the site.

The artifacts section tells GitLab which files to pass on to the next stage. The only section tells GitLab to run this pipeline for the master branch only.

Deploy

The deploy stage takes care of uploading the output of the previous stage to Heroku. There is a caveat, Heroku only hosts Web Apps, not static sites.

  1. The first step is to change directory to the html folder.

  2. Then, to turn the static HTML into a Web App we use a index.php PHP script that simply redirects the content to the actual index.html.

  3. We also create a composer.json file with an empty object, because that’s a requirement for PHP apps on Heroku.

  4. We initialize a git repo in the html directory, set up a username and an email.

  5. Add the remote git repository on Heroku.

  6. Add and commit the contents of the folder.

  7. Finally, push the files.

There’s a final step before this works, we need to add the Heroku API Key (mentioned in Set up your Heroku app) to Gtilab.

  1. Open your GitLab project on your browser.

  2. Go to settings > CI/CD and click Expand under the Variables section.

  3. Add a new variable, in this case I called it HEROKU_API_KEY, and set the corresponding value.

  4. Click Save variables.

That’s it, you are ready to test your CI/CD pipeline.

Testing your pipeline

That took some effort, but luckily it’s a one-time-only kind of thing. From now on we don’t have to worry about that.

Open your local Sphinx site and write something, then build it to make sure everything is fine. Are you happy with the result? Cool, now do the usual add, commit, push.

After you push your files into master (we configured the pipeline to only work on that branch), open GitLab and open your project, you will see the status of the pipelines for your last commit. Once a stage is done, either successfully or failed, you can see the build logs. Click the icon next to the commit hash, the Pipelines page shows up, there click the icon corresponding to the stage whose logs you wan to see (in my case there are two check marks because both stages were successful).

../../../_images/successbuild.png

The build was successful, yei! Go to https://sphinx-citest.herokuapp.com to see the deployed site.