Skip to content

Hosted architecture: push to publish

A push to the docs repository becomes live, filtered docs through four parts: a web service, a build worker, Postgres and a blob store.

Web, worker, Postgres and a blob store
Diagram: the docs repository sends a push webhook to the web service, which queues a job in Postgres. The worker fetches the commit, builds and validates it, stores assets in the blob store and publishes the release to Postgres. Readers and host apps are served by the web service through the reader filter.

The parts

web (opend-server serve)
Receives GitHub webhooks, signs readers in, serves pages, the help panel, PDFs and the admin API. Stateless: run as many replicas as you like.
worker (opend-server worker)
Claims build jobs, fetches the exact pushed commit, builds and validates it, uploads images and the theme, indexes it for search, and publishes. Several workers can share the queue.
Postgres
The job queue, release snapshots and their search indexes, which release is live for each release line, organizations, entitlements, readers, webhook deliveries and the audit log.
Blob store
Images and themes for each commit, and cached PDFs. A local folder when web and worker share a disk, otherwise any S3-compatible bucket.

An optional fifth part, the web editor (opend-server editor serve), runs on its own host. It lets authors who do not use Git save to their own branch and publish through a pull request, committing through the GitHub App, so content still reaches readers only by a push. See Run the web editor.

One image runs every role: serve, worker, migrate, seed, reconcile, reindex and editor. It is configured only with environment variables; see the environment variable reference.

From push to live

  1. GitHub sends a push webhook to /webhooks/github. The web service checks its signature, ignores deliveries it has already seen, and queues a build if the pushed branch or tag is one of the repository's release refs. It answers 202 only once the job is safely stored.
  2. A worker claims the job (it wakes on a notification, and also polls every five seconds), fetches that one commit, and runs the same build and validation as opend validate.
  3. If validation finds an error, the build fails: the diagnostics are stored with the job, the commit gets a failed opend/build status, and the previous release stays live.
  4. Otherwise the worker stores the images and theme, saves the release snapshot, and makes it live for its release line, unless a newer build already went live.
  5. Infrastructure problems, such as a failed fetch, are retried with growing delays, up to five attempts.

Serving readers

  • A signed-in reader's organization gives their products, features and version. The version's major number picks the live release; the reader filter does the rest.
  • Filtered views and pages are cached per entitlement set, not per user, and cleared at once when an admin changes entitlements or a new release goes live.
  • Pages are sent with Cache-Control: private, no-store and a strict Content Security Policy, and run no scripts.
  • The site serves one docs repository. If several are registered, OPEND_SITE_REPO says which.

Multi-tenancy, with many sites in one deployment, is planned for a later release.