Meridian handbook
Deploying

Deploying

How a Meridian site runs in production, the parts of a deployment (engine, PostgreSQL, storage, optional search and mail), the deploy sequence, and which page covers each task.

A production Meridian install is the engine binary (or its container image), your project directory, a PostgreSQL database, a place to keep uploaded media, and optionally a search service and a mail provider. Nothing else runs beside the engine: the same process serves the public sites, the admin, the member portal and the APIs, runs the background jobs and runs the scheduled tasks.

The parts of a deployment

PartRequiredWhat it is
The engineYesengine-dmo (which also runs engine-cms projects), from one of the two container images. See Container images and What a release publishes
Your projectYesThe directory with config/, templates/ and public/. It is read only at run time. Mount it, copy it into an image of your own, or put it beside the binary
PostgreSQLYesVersion 14 or later, UTF8 encoding. See Database and migrations
Media storageYesA writable directory (storage.driver: filesystem) or an S3-compatible bucket (storage.driver: s3). See Storage and media
A reverse proxy or load balancerIn practiceTerminates TLS and forwards to the engine’s listener. The engine speaks plain HTTP
A search serviceNoMeilisearch, Elasticsearch or OpenSearch. Without one, the search route serves browse mode
A mail providerIn productionPostmark, Amazon SES, Resend or an SMTP relay. engine-dmo check refuses the development log driver in production

The deploy sequence

Every deploy, first or fiftieth, runs the same steps in the same order. The engine never changes its own tables or your schema as a side effect of starting, unless you configure it to.

flowchart LR
  check["check --no-db<br/>in CI"] --> backup["back up<br/>the database"]
  backup --> migrate["migrate up"]
  migrate --> schema["schema apply"]
  schema -->|"exit 2: destructive"| review["review the plan"]
  review --> schema
  schema -->|"exit 0"| serve["serve"]
  serve --> ready["health --readiness"]
  ready --> warm["warm<br/>(optional)"]

Check the project. engine-dmo check --no-db validates the configuration, schema, routes and templates without a database or the deployment’s secrets. Run it in CI and in your image build. It exits 3 when anything is invalid.

Back up the database. Migrations only move forward; the way back from a bad upgrade is the backup you took before it. See Backups and restore.

Apply migrations. engine-dmo migrate up brings the engine’s own tables up to the binary’s version. It exits 0 when there is nothing to do.

Apply the schema. engine-dmo schema apply makes the database match your configuration (types, fields, sites, locales, roles). It refuses a destructive change unless you approve it.

Start or restart the engine. engine-dmo serve. It refuses to start while a migration is pending or while the configuration differs from the database, and says which command fixes it.

Wait for readiness, then send traffic. engine-dmo health --readiness --wait 60s exits 0 once the engine has started, the database answers and every migration is applied.

Warm the caches (optional). engine-dmo warm repairs the search index, requests the pages the page cache warms and reports each page’s time.

Where to go next

Every engine.yaml key is listed with its type and default in engine.yaml, and every command and flag in the CLI reference.