The CAL Documentation Server provides a central index for project documentation with automatic indexing and support for versioned documentation. It operates in one of two modes: GitLab Pages mode or filesystem mode.
In this mode the server indexes documentation from GitLab Pages sites within one or more GitLab groups. Each project in the group is expected to publish its docs to GitLab Pages with the following layout:
public/
index.html (redirects to latest/)
latest/ (copy of the newest version)
{version}/ (e.g. 1.2.3/)
index.html
docinfo.yaml (optional: name, description, logo)
The index is refreshed automatically in the background by polling GitLab at a configurable interval. The latest stable version (excluding beta/alpha/rc) is shown as "Latest".
By default, version links on the index page point directly to the GitLab Pages URLs. The
gitlab_proxy config option (a string) controls how documentation is served:
"off" (default) — index links point to GitLab Pages; proxy URLs still work if accessed
directly (e.g. /my-project/1.2.3/)"always" — all index links are proxied through this server. Use when Pages require
authentication or you want all traffic to flow through a single server"toggle" — adds a toggle switch in the top-right of the index page so each user can
choose between direct and proxied links. The preference is saved in the browser
(localStorage). Defaults to direct links"toggle-on" — same as "toggle" but defaults to proxied links"disabled" — proxy is completely turned off; proxy URLs return 404The --gitlab-proxy CLI flag is shorthand for "always".
In proxy/toggle mode the server fetches documentation content via the GitLab repository API on each request and serves it through itself.
You can download any project version as a zip. The server fetches the files directly from the GitLab repository and packages them for you:
# Convenient URL (use -J to save with the resolved version name)
curl -OJ http://example.com/my-project-latest-docs.zip
curl -OJ http://example.com/my-project-1.2.3-docs.zip
# REST API
curl -OJ http://example.com/api/download/my-project/latest
curl -OJ http://example.com/api/download/my-project/1.2.3
Using -J tells curl to use the server's suggested filename from the Content-Disposition
header, so latest resolves to the actual version number (e.g. my-project-2.0.0-docs.zip).
Publish documentation automatically as part of your CI/CD pipeline using GitLab Pages:
pages:
stage: deploy
only:
- tags
script:
- mkdir -p public/${CI_COMMIT_TAG}
- cp -r ./html/. public/${CI_COMMIT_TAG}/
- cp -r ./html/. public/latest/
- echo '<meta http-equiv="refresh" content="0;url=latest/">' > public/index.html
artifacts:
paths:
- public
Use semantic versioning for version directories (e.g., 1.2.3, not v1.2.3).
Beta/alpha/rc versions should include the suffix (e.g., 2.0.0b1, 3.0.0-alpha) — they
will still appear in the version list but won't be shown as "Latest".
In this mode the server serves documentation directly from a local directory. Each project is a subdirectory with optional versioned subdirectories.
my-project/ (optional if versioned dirs exist)my-project-1.2.3/, my-project-2.0.0/, etc.docs/
├── my-project-1.0.0/
├── my-project-2.0.0/
├── my-project-2.1.0/
└── my-project-3.0.0b1/ (excluded from "Latest")
The server redirects /my-project/ to the latest non-beta version automatically.
.md files rendered on-the-fly with syntax highlightingDocumentation must have either index.html or index.md at its root.
Upload a zip file via the REST API:
curl -X POST -H "X-Token: your-token" \
-F "file=@my-project-1.0.0-docs.zip" \
http://example.com/api/upload
Name the zip file {project}-{version}.zip or {project}-{version}-docs.zip. The server
extracts the project name and version from the filename automatically.
Download any version as a zip:
# Convenient URL
curl -o docs.zip http://example.com/my-project-1.2.3-docs.zip
curl -o docs.zip http://example.com/my-project-latest-docs.zip
# REST API
curl -o docs.zip http://example.com/api/download/my-project/1.2.3
curl -o docs.zip http://example.com/api/download/my-project/latest
Add a docinfo file to your documentation root (or version directory) to customise how
it appears in the index.
Supported formats: docinfo.json, docinfo.json5, docinfo.yaml, docinfo.yml
Available fields:
name — Display name shown in index (defaults to project/directory name)description — Description text shown under the project namenoindex — Set to true to hide from the index (still accessible via direct URL)Logo support:
Place docinfo.png, docinfo.jpg, or docinfo.svg alongside the docinfo file to
display a logo on the index page.
Example docinfo.yaml:
name: My Project
description: A comprehensive guide to using My Project
| Method | Endpoint | Available in | Description |
|---|---|---|---|
| GET | /api/version |
Both | Returns product name and version |
| GET | /api/spec |
Both | Returns OpenAPI 3.0 specification |
| GET | /api/projects |
Both | Lists all projects and versions |
| GET | /api/projects?search=term |
Both | Filter projects by name |
| GET | /api/download/{project}/{version} |
Both | Download project as zip |
| POST | /api/upload |
Filesystem | Upload documentation (requires auth) |
| DELETE | /api/delete/{project}/{version} |
Filesystem | Delete a version (requires auth) |
Upload and delete require a token via the X-Token header. Contact your administrator to
obtain a token.
X-Token: your-secret-token
# List all projects
curl http://example.com/api/projects
# Search projects
curl "http://example.com/api/projects?search=my-project"