Bonnie Robinson, The OpenNMS Group
November 1, 2021
The OpenNMS Group, a wholly-owned subsidiary of NantHealth, is an open-source company that maintains the OpenNMS project, an open-source network monitoring platform. With an agile development environment, we take a “docs as code” approach, where, among other things, documentation builds integrate with those of the software.
Continuous improvement is at the heart of Agile methodology: always striving to make changes that advance a project or team towards better results. In that spirit, we went through a four-month exercise to migrate our documentation build environment from AsciiDoctor to Antora. Limitations with the AsciiDoctor environment meant our docs had no search functionality and presented as single-page HTML. In addition, each guide appeared as its own separate file: we wanted to have all the project documentation under one docs website (docs.opennms.com).
As an open-source project, anyone can contribute to our source code and documentation, so it is important that we use accessible build tools that do not prevent community contribution.
Migrating the documentation was a huge undertaking that required a new repository structure in GitHub, syntax updates to almost every file, changes to our build environment, and a lot of tweaks along the way.
Technical implementation: how we got here
Since 2002, OpenNMS has treated docs like source code. Initially, we used DocBook as the format for content creation, moving to AsciiDoc in 2015. AsciiDoc was extremely feature-rich, and it was easy to integrate into our Java Maven pipeline, generated simple static single page HTML, and came with cascading style sheets (CSS). To generate the output, we ran a simple mvn install command in the docs directory.
This strategy grew challenging when we added Helm (our data visualization project) to the mix. Single-page HTML was cumbersome, especially in large docs. We split the docs into Developers, Admin, and Users sections then gathered them under a single page. One of our developers wrote a UI and integrated it into our CircleCI pipeline and release process.
As we added even more projects, we needed a solution that would allow for versioned docs, integrated into the release process, pulled from different GitHub repositories to a single location, all with the same format. Antora, made by the group behind AsciiDoc, addressed a lot of the issues we faced. Antora does not use a single page, handles docs from multiple individual versioned projects, uses AsciiDoc, and has a clear separation between the UI content assembly and content.
In a single-page HTML document, you can easily use your browser search, but with Antora-built docs we don’t have this feature anymore. We started with the Antora Lunr integration. We create a search index at build time and ship it along with the page, and all the search is done in the browser.
Challenge 1: Syntax updates
Unfortunately, the heading syntax required for Antora generation was slightly different from what we had been using. Because we also updated some of the content while we migrated to Antora, we couldn’t do a simple search and replace for the headings. Doing this manually (for the most part) on such a big documentation set was time-consuming.
Challenge 2: Build integration
We had to refactor our CI/CD pipeline in CircleCI a bit. For all docs, we now build from a single docs repository. At this point, CircleCI had no webhooks to trigger a build and publish the docs to our website. We had to find a workaround with nightly scheduled build jobs. As the content grows, we can still build everything in under 10 minutes. However, we did notice that build jobs started to fail infrequently and ran out of memory. We gradually increased our build machines from a medium size (2CPU 4GB) to a larger machine (4CPU 8GB) over time to keep the jobs reliably running.
And of course, we needed to decide what to do with the old (pre-Antora) documentation set. We created an archive of the old documentation that users can access from the “Archived Docs” menu on the new documentation site.
Challenge 3: Search functionality
Unfortunately, by design, the Lunr search creates one large index file during the build process. This takes up a lot of memory and may cause the build to time out. It also causes storage problems, since the project bundle is significantly larger than we would like. We are exploring other options to address this issue.
We might face some challenges here with the size of the index we need to ship. Going forward, we may investigate external search index providers like Algolia, which has a lot of adoption in the Antora community.
Challenge 4: Search Engine Optimization (SEO)
Changing our docs website to docs.opennms.com would affect our SEO. To avoid delivering too many 404s, we set up redirects to the docs.opennms.com entry page, but in the end, you have to break eggs to make an omelet.
Now that we have migrated to Antora, not only will we continue to update the docs to describe new features, we also plan to update existing documentation correct errors, restructure/reorganize content to make it even easier for users to find the answers they need and improve search functionality. What we are missing right now is also a “latest” or “current” floating tag. We have to reference docs in external links with a specific version number, which is addressed in the roadmap in Antora 3.0.
Thanks to the community
Kudos to the AsciiDoc and Antora community for developing these great tools, and for the excellent documentation, support, and forums. Our implementation was much easier because of this support.
Sidebar: Under the Hood
The content on docs.opennms.com is driven by an Antora playbook in a GitHub repository named for the website: “docs.opennms.com”. The playbook describes how to assemble, style, and publish the content. It runs in CircleCI and updates the docs nightly.
We pull in a UI bundle that defines the layout and how you use the docs. Each OpenNMS project has its own repository, and within that repo there is a docs directory where the documentation for that project lives. The Antora playbook has a reference to the docs git repository for each of the projects and pulls that source content in during build time.
When we make a release, we tag it with a version number in the content’s repository (for example, “1.0.2”). The docs/antora.yml file drives the version numbering in the docs, similar to the version number in a pom.xml.
With the next release, we get another version number, set it in the antora.yml, and on a CircleCI docs build Antora fetches only tags starting with `v` and generates the content from those tags.
Bonnie Robinson is lead communications professional at The OpenNMS Group, with over 25 years’ experience as a technical writer and editor. She oversees production of the group’s technical documentation and marketing content.