Create and deploy API documentation to Kubernetes
Tags: api, kubernetes, tutorial, documentation
Published: 2022-03-31 14:15:16

A lot of ‘no code’ and ‘low code’ tools enable not just programmers but almost any other professionals to use APIs. A Swagger (Open API) definition is essential when a user wants to touch your API. But it isn’t enough, especially when a user trying to understand it and how it could be used. So this means when releasing an API for public nice clear documentation is absolutely vital. Let’s create one in just four steps:

1. Generate Markdown from Swagger specification. We will use Widdershins for this.
2. Edit your markdown to add some details. You can do this on your own.
3. Generate a static site from this Markdown. We will use Slate for this. And then we will put the site to a docker container along with Nginx web server.
4. Build a Helm chart to make Kubernetes easy to deploy.

There is the option for the last two steps of not to building the custom docker image, but using a standard Nginx image and mount volumes with the site data and configuration files. I prefer to have a complete docker image in the registry to be sure that all things are in place and to have an ability to deploy with a single command.

Now let’s start building our site with an API documentation.


## From Swagger to Markdown

First you need to install [node.js](https://nodejs.org/), [npm](https://docs.npmjs.com/cli/v8/commands/npm) and [Widdershins](https://github.com/Mermade/widdershins). To install Widdershins run:
```shell
npm install -g widdershins
```
Download you swagger specification (i.e. swagger.json) and generate Markdown file from it:
```shell
mkdir docs
cd docs
wget https://petstore.swagger.io/v2/swagger.json
widdershins --language_tabs 'shell:Shell' 'python:Python' 'javascript:JavaScript' -o apidocs.md swagger.json
cd ..
```
You can specify languages to generate examples using the `--language_tabs` command line argument. In the example above we have chosen Shell (for `curl` example), Python and JavaScript. 

Now feel free to edit this intermediate documentation file and fill it with additional information about your API. Don’t forget to commit the file to Git or another version control system you use. 

## Building a static site
If you are going to use Slate from the console you need to install it, along with all its prerequisites, as described [here](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively). In Ubuntu you can execute the commands:
```shell
sudo apt install ruby ruby-dev build-essential libffi-dev zlib1g-dev liblzma-dev nodejs patch
sudo gem install bundler
```
Fork the official Slate repository to your Github or Gitlab. 

To run Slate clone a previously forked repository and execute:
```shell
git clone https://gitlab.com/YOURUSERNAME/slate.git
cd slate
bundle install
```
Now we are ready to build a static site. First you need to copy your intermediate Markdown documentation to the Slate directory and run Slate for build:
```shell
cp -rf ../docs/apidocs.md source/index.html.md
bundle exec middleman build --clean
cd ..
```
Here we have a static site in `slate/source` directory. You may serve it with your favourite web server. But if you are using Kubernetes for running your web services it is very convenient to deploy this site to your Kubernetes cluster. To prepare for this we will create a Docker image with Nginx web server and our site inside:
###### Dockerfile
```Dockerfile
FROM nginx:1.17.10-alpine
EXPOSE 80
COPY nginx.conf /etc/nginx/nginx.conf
COPY slate/build /usr/share/nginx/html
```
###### nginx.conf
```
events {}
http {
    include /etc/nginx/mime.types;
    server {
        listen 80;
        server_name localhost;
        root /usr/share/nginx/html;
        index index.html;
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}
```
```shell
docker build -f ./Dockerfile -t petstore-api-docs:1.0.0 .
docker push petstore-api-docs:1.0.0
```
> Please note that you should be logged in to your Docker repository to push the image.

If you start it with the command:
```shell
docker run -p 3000:80 petstore-api-docs:1.0.0
```
And open in your browser http://127.0.0.1:3000, you should see something like this:
![API documantation homepage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kiu75ybe1h2cardvnnv9.png)

This means you have done everything right and the docker container is ready to use.

## Creating Helm chart and deploying
You should have access to the Kubernetes cluster and you should install Helm if you have not:
```shell
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt-get install apt-transport-https --yes
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
```
Next create our chart for the site:
```shell
helm create petstore-api-docs
```
Out-of-the-box helm chart template is fine for such a simple application. You should only set appropriate values in `Chart.yaml`, for example:
```yaml
apiVersion: v2
name: petstore-api-docs
description: A Helm chart for petstore-api-docs service
type: application
version: 1.0.1
appVersion: "1.0.1"
```
You should also go to `petstore-api-docs/values.yaml` and change the image section:
```yaml
image:
  repository: your-repository/petstore-api-docs
  pullPolicy: IfNotPresent
  tag: "1.0.0"
```
You can also change whatever you want there to adapt this chart to your environment. For example, you might want to add some ingress annotations, hostname and TLS data. Don’t forget to test it with `helm lint` and `helm template --debug`

And after all you can deploy it to your Kubernetes cluster by executing just one command like this:
```shell
helm update -i docs-release petstore-api-docs -n docs-namespace
```
Based on this approach you may create a CI pipeline covering all build and deploy stages using your favorite tools. In the next article I will show how to do it with Gitlab CI.