Skip to main content
This guide is for installations of an earlier public release: the 1.0.0 release candidates (1.0.0-rc1 to rc7), the latest images (0.19.0), or builds of the main or tip images. You upgrade directly to 2.0. Installations created with 2.0 or later follow the usual update steps of Docker Compose or Kubernetes instead. The 2.0 processes migrate PostgreSQL and ClickHouse when they start: do not run diesel migration run yourself. They check the database first, and when they refuse, they have changed nothing (see If the upgrade fails).

Breaking changes

  • PostgreSQL 18 is required.
  • Webhooks are delivered by Meteroid itself, no longer by Svix. Your endpoints live in Svix: until you import them, they receive nothing. New endpoints are signed with the Standard Webhooks headers (webhook-*); imported ones also keep the svix-* headers.
  • Coming from 0.19, the webhook payload is no longer wrapped in data (1.0.0-rc7 already sends the 2.0 format). A customer.created event was {"type": "customer.created", "id": "evt_…", "data": {"id": "cus_…", "name": "Acme", …}} and is now {"type": "customer.created", "id": "evt_…", "customer_id": "cus_…", "name": "Acme", …}. Update the receivers that read data.
  • The official images refuse to deliver webhooks and alerts to private or loopback addresses, and over plain http. If your endpoints are inside your network, set WEBHOOK_ALLOW_PRIVATE_DESTINATIONS=true.
  • MAILER_FROM is required once MAILER_SMTP_HOST is set. Every SVIX_* setting and ANALYTICS_API_KEY are removed.
  • The scheduler is now the worker: image meteroid-worker, Compose service meteroid-worker, Helm values worker.
  • The official images run the Enterprise edition, free. The -ee image names are deprecated.
  • The Helm chart deploys only Meteroid, no longer PostgreSQL, Kafka or ClickHouse, and its version is the Meteroid version.
  • Telemetry: the Segment tracking is replaced by an anonymous daily report. ANALYTICS_ENABLED=false and DO_NOT_TRACK still turn it off.
  • Without a license, an installation runs one organization, one Production tenant and one invoicing entity per tenant. Existing ones beyond that keep working; only creating more is refused. The branding=false options of the portal and embeds are ignored.
  • Usage events stored by 0.19 or 1.0.0-rc1 to rc3 are copied to the 2.0 tables by the metering API. Events it cannot convert are kept in raw_events_unconverted, for you to review and drop.

Before you upgrade

1

Update pgmq if it is older than 1.6.0

Before 1.6.0, pg_dump silently leaves out the queues and their messages, so a backup or a move to PostgreSQL 18 loses them. The meteroid-postgres:17.4 image ships 1.5.0. Update to 1.11.0 before taking any dump: your current version of Meteroid keeps working with it. With Docker Compose, from docker/deploy:
Elsewhere, copy the same pgmq--1.*--*.sql files into the extension folder of pg_config --sharedir, then run the same ALTER EXTENSION.
2

Check the PostgreSQL version

SHOW server_version; must return 18 or later. With Docker Compose, the upgrade below moves you from 17. Elsewhere, upgrade the server first, with pg_upgrade or a dump restored into PostgreSQL 18 with pgmq (ghcr.io/meteroid-oss/meteroid-postgres:18.3-standard, or 18.3-cnpg for CloudNativePG).
3

Run the preflight query

One migration moves customer balances onto a new credit ledger, and aborts on data it cannot carry over. This read-only query lists it. It is in a clone of the repository at v2.0.0; with Docker Compose, from docker/deploy:
Resolve the blocking rows first; contact hey@meteroid.com with the output if you are unsure how. The second result gives the per-currency totals that become customer credit, to check after the upgrade.
4

Back up

Keep a copy of your configuration too, above all SECRETS_CRYPT_KEY. Rolling back means restoring this backup and running your previous images: the migrations are not reverted. On a large installation, rehearse the upgrade on a restored copy first.

Upgrade

On a large database the migrations take several minutes, and writes to entity_activity wait while one of its indexes is built.
1

Let the queues drain, then stop Meteroid

2.0 removes two queues and refuses to migrate while they hold messages. Stop the traffic that writes to Meteroid (API clients, usage events), wait a minute, and run this until every queue_length is 0:
Then stop everything but the database:
2

On PostgreSQL 17, dump the server

Skip this step on PostgreSQL 18. The 2.0 Compose file runs PostgreSQL 18 on the same volume name, which must start empty, so dump the server, archive the old volume and remove it:
3

Take the 2.0 deployment files

Run docker compose down with your current files, then replace them with docker/deploy from the v2.0.0 tag, including the ClickHouse configuration under volume/. Reapply your changes to docker-compose.yml. In .env:
  • set METEROID_VERSION to 2.0.0, if you set it;
  • keep JWT_SECRET, INTERNAL_API_SECRET, DATABASE_* and, above all, SECRETS_CRYPT_KEY;
  • set MAILER_FROM if you use SMTP;
  • remove SVIX_SERVER_URL and SVIX_JWT_TOKEN, but keep their values for the import.
4

On PostgreSQL 17, restore the dump

psql reports that the role and the database already exist: that is expected. Any other error means the restore is incomplete. Keep the dump and the volume archive until 2.0 runs as expected.
5

Start 2.0

Once 2.0 runs, sign in, check your customers, subscriptions and invoices, and compare customer balances with the totals of the preflight query.

Import your webhook endpoints from Svix

If you used outgoing webhooks, copy your endpoints from Svix with meteroid-svix-import, in the API image, once 2.0 has started. It reads the API’s configuration plus SVIX_SERVER_URL and SVIX_JWT_TOKEN, and the Svix server must be reachable from where it runs.
Without --apply, the command only prints its plan. Run it again with --apply to import. It is safe to run twice: endpoints already present are left as they are. Each endpoint keeps its URL, filters, rate limit, headers, state and signing secret, so your receivers keep verifying signatures without change. Some are imported disabled, marked TO DO in the output: Once you have checked the endpoints, shut Svix down and remove its settings.

If the upgrade fails