DEV Community

Cover image for Migrate Sentry -> Epure in 10 min
Amorizz
Amorizz

Posted on Originally published at epure.sh

Migrate Sentry -> Epure in 10 min

TL;DR

  • Keep the official Sentry SDK. Change only dsn to your Epure project.
  • Set traces, profiles, and replay sample rates to 0. Epure is exception-only.
  • Throw one test error, expect ingest HTTP 202, then an Issues row. Know what you drop.

I already ship @sentry/node (and browser) against SaaS Sentry. This week I pointed the same init at our self-hosted ingest: same SDK, new DSN, one verified event. The bill and the data residency story were enough; I did not want a client rewrite.

About ten minutes of wall clock once the ingest host is healthy. That is DSN copy, init edit, one throw, Issues check. Not a stopwatch claim for compose, TLS, or CORS.

What do you need before the clock starts?

Ingest already up. Official Sentry SDK already in the app.

Prerequisite Done means
Epure host /health returns {"status":"ok"} on the public origin you will put in the DSN
Project + DSN Dashboard → Settings → SDK connection (or Setup). Key created.
App SDK You already call Sentry.init with a SaaS DSN
Scope match You only need exceptions / issues, not APM, replay, profiling, logs, or mobile

Host not up yet? Bring the two-container stack online first (Error monitoring on a $5 VPS), then come back. This post does not retell compose.

Timed steps: DSN swap and one event

Copy the project DSN, replace only dsn, zero unused rates, throw once, confirm Issues.

1. Copy the project DSN

Open the project → Settings → SDK connection (or Setup). Create a DSN key if none exists. Copy the full string. Do not paste a project UUID from the URL bar into the DSN.

Shape looks like:

https://YOUR_PUBLIC_KEY@errors.example.com/YOUR_PROJECT_ID
Enter fullscreen mode Exit fullscreen mode

2. Swap dsn only

CI fixtures pin @sentry/browser / @sentry/node 7.120.0. Match that if you want the same line the docs exercise. On Sentry JS v8+, also set enableTracing: false when the option exists.

import * as Sentry from "@sentry/node"; // or @sentry/browser@7.120.0

Sentry.init({
  dsn: "https://YOUR_PUBLIC_KEY@errors.example.com/YOUR_PROJECT_ID",
  environment: "production", // match the Issues filter chip
  release: "my-app@1.2.3",
  tracesSampleRate: 0,
  profilesSampleRate: 0,
  replaysSessionSampleRate: 0,
  replaysOnErrorSampleRate: 0,
});
Enter fullscreen mode Exit fullscreen mode

Migrating from Sentry SaaS: keep the same init options. Replace only dsn.

3. Send one test error

Sentry.captureException(new Error("Epure migrate test"));
// short workers: await Sentry.flush(2000) before process exit
Enter fullscreen mode Exit fullscreen mode

4. Confirm ingest, then Issues

Expect ingest HTTP 202 with a body like { "id": "..." }. Refresh Issues. Match the environment filter to Sentry.init (production above, or local in docs examples). You should see an unresolved issue for that message.

Empty feed after a 202? Wait a second, check the env chip, confirm you opened the project that owns the DSN.

What do you keep / drop?

Exceptions and issue triage stay. Replay, APM, profiling, logs, and mobile do not.

Keep Drop (out of scope)
Official Sentry SDKs (@sentry/node, @sentry/browser, …) Session replay
Envelope / store error path APM / distributed tracing product
environment, release, issue grouping Continuous profiling
Self-hosted data path Full SaaS suite extras

Never "100% Sentry compatible." Partial wire for error tracking. If GlitchTip is a better fit for a lighter Django-shaped stack, that is fine. This post is that migrate path.

Deeper SDK init, CORS, and compose details live in the earlier how-to: Point the official Sentry SDK at self-hosted ingest (DSN only). Soft-link only. Do not retell every init step here.

Failure checklist

  1. CORS blocks the browser SDK. SPA origin missing from EPURE_CORS_ORIGINS. Fix origins before blaming the package (CORS post).
  2. Short worker exits before flush. Node/Go lambda-style processes drop the last event. Call flush / Flush before exit (flush post).
  3. DSN revoked or wrong key. Secret shown once at create. Rotate in Settings → SDK connection if you pasted a dead key.
  4. Public URL mismatch. /health on localhost is not the host inside the DSN. Align EPURE_PUBLIC_URL / proxy with what the SDK posts to.
  5. Environment chip hides the row. Issues filter is staging while init says production. Match them.
  6. Second Sentry.init still on SaaS. A leftover init in a shared bootstrap still ships to ingest.sentry.io. Grep for every Sentry.init and every dsn:.

When the host is healthy and you want the install map in one place: Epure quickstart.

Discussion

What blocked your last DSN swap: CORS, auth, or a missing flush on short workers?

Top comments (0)