Hello everyone,
Raytha 2.0.0 is the first release of the 2.0 line. The admin is a React application, PostgreSQL is the only database, and the host runs on .NET 10.
Docker: raythahq/raytha:2.0.0 (also latest).
What's changed
- The admin is a React SPA served at
/raytha, from a bundle in the host. It uses the same cookie session and calls/raytha/api/adminand/raytha/api/auth. Old 1.5 admin URLs redirect to the new pages. Sign-in screens are part of the SPA. Error pages, logout, the SAML and JWT sign-in handoffs, theme export, and the function test runner are still Razor pages. - PostgreSQL only: one provider and one set of migrations. Postgres-specific features (
jsonb,ILIKE) are used directly. - .NET 10.
VERSIONat the repo root is the product version (2.0.0), and/healthzreports it. - Outbound webhooks with HMAC-signed deliveries. The signature covers the timestamp and the body, so a receiver can reject a replay.
- An email log.
/healthzfor liveness and/healthz/readyfor Postgres and file storage.- Schema export and import.
- Raytha Functions can be managed in the admin, including public function routes.
- Liquid errors include a line and column, and a web template can be previewed before it is published.
- REST API v1 additions: batch content item create, duplicate theme, background task status, and the remaining theme and content endpoints. API keys have an admin screen.
- Content list filters are a typed model with bound values. Relationship fields are stored as full Guids. Date fields are stored as ISO dates.
- Color and repeater fields, and field-driven widget templates.
- Admin impersonation. Media URLs are stored relative to the site.
- Manage System Settings and Manage Administrators are full trust: either one grants every system permission.
- Manage Media is its own permission.
- Magic-link sign-in uses a one-time code instead of a link.
- Audit log entries are newest first, and credentials are redacted from log payloads.
- The Docker image listens on port 8080 and does not start the admin dev server.
Breaking changes
Back up the database before upgrading. The v2_0_0 migration rewrites data, not only the schema. Rolling the migration back does not undo those rewrites, and 1.5 cannot read the converted dates. To go back to 1.5, restore the backup.
Apply it by starting with APPLY_PENDING_MIGRATIONS=true, or by running db/Postgres/v1_5_0_to_v2_0_0.sql yourself and leaving that flag false. Both end on the same schema.
- SQL Server is gone. There is no upgrade path from SQL Server. Move the data to Postgres on 1.5.0 first, then upgrade.
- Date fields become ISO dates. 1.x stored them as
m/d/yyyyor in the server's culture. Each date field's day/month order is inferred from its own values, and values are rewritten asYYYY-MM-DD, orYYYY-MM-DDTHH:MM:SSwhen they carried a time. This covers published content, drafts, revisions, and trash. A value that could be either order, or is not a recognizable date, is left unchanged and reported as aNOTICE(onlypsqlshows those). 2.0 reads a leftover value in the server's culture. One it cannot parse reads as an empty date, and the editor shows the stored text. The README has a query for leftovers. - Media links in content become root-relative. Absolute URLs to media items in this database lose the scheme and host (a path base is kept) in content, drafts, revisions, trash, and site pages. Links to other sites, and all templates, are left alone.
- Magic-link sign-in uses a one-time code. The magic-link email template and the "magic link sent" page are replaced if they do not already use the code. The previous content is kept as a revision. Links emailed before the upgrade stop working.
- Manage Media is a separate permission. Roles that could reach media before — Manage Content Types, Manage System Settings, or Edit on any content type — are granted it, so existing admins keep access.
- Built-in widget templates gain field definitions for the 2.0 page builder. Templates that already have fields are not touched.
- Emailed links and API media URLs come from the Website URL in organization settings, not from the request host. A stale Website URL breaks images. Set it before upgrading.
- The session cookie is
SameSite=Laxin every environment. - Proxy trust is configured with
TRUSTED_PROXIES. Unset means any peer is trusted. If clients can reach Raytha without going through your proxy, setnoneor list the proxies.
Full upgrade notes are in the README, under "Upgrading from 1.5.0".