openCBT

Webmaster

How openCBT is deployed, and what runs where.

For whoever runs the servers. The school-facing guide is at /docs; this section assumes Linux, Docker and DNS are familiar.

What exists

DeploymentDEPLOYMENT_TARGETSits examsOwns the structureSyncs
A school's own serveronsiteyesyesstarts every transfer
A school's cloud companioncloudnono, copied upanswers the school
A school entirely onlinefull-cloudyesyesnothing to sync

One image serves all three; the environment decides which it is. Papers, results and marks move only when somebody presses a button on the school's Cloud Sync page — the cloud never initiates anything, because it cannot reach inside a school's network.

The pieces

  • The image: ghcr.io/reelmza/opencbt, built by GitHub Actions on every push to main, tagged with the commit and latest. Private, so every server needs a read-only token to pull it.
  • deploy/ in the repository: one compose file per deployment, the Caddy configuration for the cloud, and the backup and restore scripts.
  • One database per school. Never shared, on any deployment.
  • /data on each server: uploaded pictures, exports, session archives and backups.

Pages here

Conventions worth keeping

One token per box. A read-only read:packages token each, so losing a school's server means revoking one token, not all of them.

Pin the image on a school's server. OPENCBT_IMAGE in its .env, set to a commit or a version tag, so an exam morning is never the first time that box runs a new build.

The clocks matter. Signed transfers are rejected if the two servers' clocks are more than five minutes apart. systemd-timesyncd is enough.

On this page