Your API documentation locally with SwaggerUI and docker-compose

TL; DR:

git clone git@gist.github.com:79f6f33b6907af59fb496365cd7a5054.git swagger_compose
cd swagger_compose
NGINX_API_URL=https://api.example.com API_PATH=/v0/openAPI docker-compose up
    

Back-end developers often gets their own SwaggerUI instance while developing their own APIs. Accessing the API documentation is not a problem for them.

I often had to build APIs but there is still a moment when you don't want to put API docs online but you neither want to require your teammates to fork your project and run the whole project just for docs.

I encountered that situation at DiagRAMS since data scientists needed to get access to the docs but it was a bit overkill for them to clone and setup the project locally.

OpenAPI goodness

I made a back-end framework (called Whook) that leverage a nice standard for documenting APIs: OpenAPI.

You cannot create a new route without documenting it. It not only ties documenting and coding. It ensures that documentation and code cannot drift overtime thanks to TypeScript and the schema2dts project.

We plan to put our documentation online but we are currently moving fast on features and our API is not public at the moment. I also didn't want to create a new website for 3 visits a month, it wouldn't be green at all. So we needed a B plan.

Docker to the rescue

As usual, Docker can be a great tool to give access to nice features locally. That way, you only run the server when you need it.

My first approach was to use docker run with a local copy of the OpenAPI declaration:

docker run -e "SWAGGER_JSON_URL=openapi.json" -v "$PWD/openapi.json:/usr/share/nginx/html/openapi.json" --rm -p 16640:8080 swaggerapi/swagger-ui

But I then evolved to something more live since our API serves its own OpenAPI file, let's just use it.

Using docker-compose

I couldn't simply fill up the SWAGGER_JSON_URL with our documentation URL. Indeed, for security reasons, the CORS are enabled on our API and it simply doesn't work.

This is why I finally used 2 Docker images. One for SwaggerUI and another for proxying the API and change the Access-Control-Allow-Origin header.

I made it generic and write this blog post since I think it can benefit to you or my future self. So here is the code:

The same approach can be taken for allowing frontend devs to build the app without cloning the API.