Running the platform

For whoever operates the server rather than uses the product.

Deployment

A deploy pulls the code, builds, migrates and restarts. It takes a backup first.

The deploy script updates itself

A change to the deploy script takes effect on the next deploy, not the one running it. Expect exactly one run of the old behaviour after you change it.

After a declaration change

Changing an entity declaration needs a registry refresh after the deploy. Without it the code runs and the type does not know about the change — a failure that looks like a caching problem and is not.

Backups

Taken before every deploy: the whole database, each customer schema separately so one can be restored alone, and the file store.

Retention differs by kind on purpose. Database dumps are small and change constantly, so many generations are kept. The file archive is large and changes slowly, so a few are enough — the rest was only disk.

A backup on the same machine is not a backup

Configure an off-site copy. Everything above protects you from a mistake, not from the machine.

Deleting an organization

An operator can remove a firm — whole, in one step:

python manage.py tenant_command organization_delete <machine_name> --schema=<schema>
python manage.py tenant_command organization_delete <machine_name> --yes --schema=<schema>

The first form only PRINTS the inventory: everything the firm owns, per kind, with counts — nothing is touched. The second executes inside one database transaction and prints what actually went.

What the deletion means:

  • Everything the firm OWNS goes: contents, contacts, documents, menus, files (their binaries leave the disk too), sites, portal accesses.
  • Audit rows survive, unlinked. Change records, mail logs and GDPR consent evidence deliberately outlive the firm — they are evidence, they render on no firm's surface, and the report names them as kept.
  • User accounts survive. Accounts are platform-wide; a person who was also another firm's customer keeps that other access untouched.
  • The operator organization — the default site's owner — refuses to be deleted: that firm IS the installation.

WHY a plain database delete was never an option: several kinds of data protect the firm row (the delete would crash half-way), and background synchronization creates rows for the firm even while it is being removed — the operation sweeps until the world is genuinely clean, or refuses rather than commit a broken one. The deploy-time backup is the recovery story; the deletion itself is final.

Disk

Two things fill a disk quietly:

Cause Sign
Docker build cache Tens of gigabytes accumulated over many deploys, nothing removing it
Backup retention Many nearly identical copies of a large file archive

The deploy reports disk use and warns above 85 %. Both causes have bitten this platform in production, and neither looked like the problem it was.

The reverse proxy

The proxy decides which requests reach the application and which are served by the front end.

A new root-level URL must be added to the proxy

Every time, in both variants. A URL the application serves but the proxy does not route returns the front end's not-found page — the symptom is a feature that works locally and is missing in production. This has already happened once, to the admin menu icons.

Two more traps worth knowing: a bind-mounted config file plus a git pull can leave the old file in place, so force-recreate rather than reload; and recreating a container pulls its dependencies with it, which can restart the application and take every site down for a couple of minutes.

The proxy config in the repository can fall BEHIND the server

A route added by hand on the server and not written back to the repository is a route the next deployment removes. On 2026-09-10 the live proxy carried /update.txt, /download and /download/*.exe while the repository's copy did not — a redeploy would have sent the update manifest to the front end, and every installed copy of the program in the field would have read a web page where it expected a signed manifest.

That failure is invisible from a browser. A person meets a wrong page and reports it; a program meets a wrong page and simply stops updating, with nothing anywhere saying so. After any hand edit on the server, diff the live file against the repository's before you deploy.

Allowed hosts

A customer's own domain must be accepted by the application, or every route returns an empty not-found. When the proxy is the only way in, trusting it is the correct configuration; a hand-maintained list is a domain outage waiting for the next customer.

Next

Tags
administrationoperations