Skip to content

This docs platform

How this site itself is built and operated. Adding a page, translating it and deploying it — it is all here.

Technology

Component Choice
Engine MkDocs
Theme Material for MkDocs
Multilingual mkdocs-static-i18n
Diagrams Mermaid (built into Material)
Output Static HTML — no runtime

The same stack as the documentation in the ecosystem's other repositories — which makes it easy to move a page or copy a configuration from one repo to another.

Repository layout

docs-gerege-mn/
├── mkdocs.yml              # Site configuration, nav, i18n
├── requirements.txt        # mkdocs-material, mkdocs-static-i18n
├── docs/                   # ← The published content
│   ├── index.md
│   ├── assets/logo.webp
│   ├── stylesheets/brand.css
│   ├── ecosystem/
│   ├── platforms/
│   ├── standards/
│   └── operations/
├── deploy/                 # Deployment tooling (NOT part of the site)
│   ├── README.md           # The host runbook
│   ├── deploy.sh
│   ├── docker-compose.yml
│   ├── nginx-site.conf
│   └── edge/
│       └── docs.gerege.mn.conf
└── .github/workflows/
    ├── ci.yml
    └── deploy.yml

Anything inside docs/ becomes public

The site is open to the internet. Server addresses, credentials and internal risk registers must never live inside docs/. Such material belongs in deploy/ (inside the private repository, and not part of the site).

Running it locally

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

# Development server — changes appear immediately
.venv/bin/mkdocs serve

# Production build (strict — warnings become errors)
.venv/bin/mkdocs build --clean --strict

mkdocs serve starts on http://127.0.0.1:8000.

Adding a page

  1. Create the file — a .md file in the appropriate directory (for example docs/platforms/new.md).
  2. Register it in nav — add it to the nav list in mkdocs.yml.
  3. Nav translations — if you added a new menu label, add it to nav_translations for all six locales (en · ar · zh · fr · ru · es).
  4. Check with a strict buildmkdocs build --strict.

Why strict mode matters

--strict turns warnings into errors: broken internal links, files listed in nav that do not exist, and files that exist but are missing from nav. CI runs in the same mode, so checking locally saves the PR from failing.

Adding a translation

The site is served in Mongolian plus the six official UN languages. It uses the suffix layout — page.md (Mongolian) alongside versions carrying a language code:

docs/platforms/sso.md      ← Монгол (source)
docs/platforms/sso.ar.md   ← العربية
docs/platforms/sso.zh.md   ← 中文
docs/platforms/sso.en.md   ← English
docs/platforms/sso.fr.md   ← Français
docs/platforms/sso.ru.md   ← Русский
docs/platforms/sso.es.md   ← Español

When adding a page:

  1. Write the Mongolian original and stabilise it with a strict build.
  2. Add the six translations together — doing it piecemeal lets the content drift apart.
  3. Add the menu label to nav_translations in mkdocs.yml for all six locales.

Because fallback_to_default: true, the site stays whole even with translations missing — the page shows the Mongolian original rather than a 404.

See Internationalisation for the detail.

Theme and brand

The colours are concentrated in a single block inside docs/stylesheets/brand.css:

:root {
  --grg-blue:       #004eb6;  /* header / deep cobalt */
  --grg-blue-2:     #0064e1;  /* brand */
  --grg-blue-deep:  #003a8a;
  --grg-blue-light: #3990ff;  /* links in dark mode */
  --grg-gold:       #e4b24a;  /* ONLY for emphasis / marks of trust */
}

Do not add new hex values outside this block. Gold is not a brand colour — it is only for emphasis and marks of trust.

Status badges

<span class="grg-badge grg-badge--live">Production</span>
<span class="grg-badge grg-badge--wip">Partial</span>
<span class="grg-badge grg-badge--plan">Planned</span>

Deployment architecture

Internet → edge nginx (gerege-nginx)
              │  docs.gerege.mn vhost
       docs-gerege-web  (nginx:alpine container)
              │  shared `gerege` Docker network
       <deploy path>/site  (the built static HTML)

The site is updated in place with rsync — replacing the directory wholesale would leave the container still looking at the old inode, so the new content would never appear.

Why a separate container? Adding a new mount to the edge nginx container requires recreating it — and that briefly takes every domain down. Serving the static site from its own small container means the edge only needs a configuration addition and a reload.

Configuration ownership

This site owns its own edge vhostdeploy/edge/docs.gerege.mn.conf. On every deploy that file is installed into the edge nginx conf.d, validated with nginx -t and applied with a reload. The Developer Portal and the Template Platform have moved to the same pattern; sso · dan · gsign · xyp are for now still served from the central file.

The effect is that any change to docs.gerege.mn is finished inside this repository — no PR to another repo, no waiting on another team's deploy.

To be fully independent, the vhost has its own rate-limit zone and its own port-80 block (ACME + redirect) — it depends on no zone or default server defined in another file.

The general principle

Configuration that concerns only one service belongs in that service's repository. Putting it in a central file means every change has to be coordinated with another team's deploy, and ownership becomes blurred.

For how this pattern was arrived at, and why each decision was made, see Work log.

Deploy

Deployment happens automatically through CI — on a push to main:

  1. MkDocs --strict build,
  2. copy the site/ archive to the server,
  3. update it in place with rsync,
  4. refresh the container,
  5. install the edge vhostnginx -t → reload,
  6. check the live site.

If nginx -t fails, the previous configuration is restored and no reload happens — the running nginx carries on with its last good configuration.

If a manual deploy is needed there is a deploy/deploy.sh script — for host-specific detail see the closed runbook in deploy/README.md.

Contributing

  1. Create a branch (docs/<topic> or feat/<topic>).
  2. Make your change and run mkdocs build --strict locally.
  3. Open a PR — CI runs the strict build.
  4. After merging it is published automatically.

House style

  • Write the source text in Mongolian.
  • Make the heading say what the page is about — more specific beats "Overview" or "Introduction".
  • Write down the reason for a decision, not only what was done. "Why" is the information that goes stale most slowly.
  • Put risks and cautions in a !!! warning block.
  • A table beats a long list.