Skip to content

Jobs, monitoring, and upgrades ​

Run scheduled work ​

The complete JSON configuration accepts separate jobs.schedules and jobs.webhooks modes:

ModeBehavior
automaticDefault; backend polls for work with a five-second idle interval
externalWork runs only when the job endpoint is triggered
disabledNeither timers nor HTTP triggers execute that subsystem

The backend must remain running in every mode. No open dashboard is required. Disable both modes in isolated recovery copies to prevent real publication and duplicate notifications.

External cron ​

Set an independent JOB_TRIGGER_TOKEN with at least 32 random characters. Send POST /api/v1/jobs/run with Authorization: Bearer <token> over HTTPS. Sessions and delivery API keys do not authorize this endpoint.

For example, save curl settings in a protected operator-owned file /etc/tinycms/jobs.curl with mode 0600:

text
url = "https://cms.example.com/api/v1/jobs/run"
request = "POST"
header = "Authorization: Bearer REPLACE_WITH_JOB_TRIGGER_TOKEN"
fail-with-body
silent
show-error
max-time = 30

Install this in that operator's crontab when using external mode:

text
* * * * * /usr/bin/curl --config /etc/tinycms/jobs.curl

Inspect response counts and dueWorkRemaining. HTTP 200 does not mean every job succeeded. Trigger again or allow subsequent ticks to drain a backlog. Keep the token out of query strings, logs, and source control.

Monitor production ​

  • Check /health, service state, and journalctl -u tinycms; health alone does not exercise email, uploads, or publication.
  • Monitor disk space for data, cache, backups, and temporary validation/restoration files.
  • Inspect failed/expired schedules, failed release execution, webhook attempts, and backlog.
  • Verify certificate renewal, email delivery, clock synchronization, and independent backup copies.
  • Record backup age, recovery-drill duration, and verification results.

For graceful maintenance, use sudo systemctl stop tinycms and wait for exit. Stop external cron and any other writer. A manual systemd stop does not invoke Restart=on-failure; also suspend external deployment/restart automation during maintenance.

Upgrade safely ​

  1. Download and extract the candidate release separately. Install its locked dependencies and inspect its shipped migrations. Keep the previous complete release.
  2. Arrange a maintenance window and suspend public writes, external cron, and restart/deployment automation.
  3. Stop the service and every other writer.
  4. Create and validate a fresh backup using the current matching build; copy it to independent storage.
  5. Install the new release at the configured application path, keeping persistent data and secrets intact.
  6. Apply that release's reviewed migrations with the production database URL through pnpm --filter backend run db.migrate.
  7. Start privately, verify health, login, media, permissions, locale-specific delivery, and job configuration, then restore routing and writes.
  8. Retain the previous release, validated pre-upgrade bundle, configuration, and secure secrets for rollback.

Do not apply migrations against a running deployment. Use only the reviewed migration set supplied with the release; obtain a complete matching release if it is missing.

Roll back ​

If verification fails, stop the candidate before changing paths or files. Reverting application files alone may be incompatible after a database migration. Restore the pre-upgrade bundle into an empty destination using its matching build, recover the matching configuration/secrets, and follow production recovery.

Once new writes have been accepted, restoring an older snapshot loses those writes. Make an explicit reconciliation decision before rollback; do not merge database or media files from different recovery points.