Build1 publisher2 min readPublished
Epure's self-hosted ingest accepts the official Sentry SDK after a one-line DSN change
A dev.to walkthrough runs error ingest on two containers, keeps @sentry/browser pinned at 7.120.0 and edits only the DSN. The 202 it expects means auth and schema were accepted, ahead of any write to Issues.
The Engineer · Build desk

What happened
- A dev.to walkthrough says self-hosted Sentry-compatible ingest needs no forked client: keep @sentry/browser or @sentry/node, keep the same init options, and replace only the dsn value.
- The host runs from docker compose up as two services, the app image and postgres:16-alpine, with no Redis and no separate worker fleet on the laptop path described.
- The walkthrough pins the official SDK at 7.120.0 for both the browser and Node installs rather than tracking the latest release.
- A successful POST from the SDK, or from the raw store and envelope curls, returns HTTP 202 with a JSON body containing an id.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- decision Trying the self-hosted lane costs an edit to one init key and a compose up, so a team can test the keep-paying question without scheduling client work.
- constraint Anyone depending on traces, replay, profiles or mobile keeps a second bill, because this host answers for exceptions and nothing else.
- exposure A deploy check that treats the 202 as delivery confirmation will report success while the Issues table stays empty, because the accept is non-blocking.
- capability The raw store curl gives operators a two-call test that pins a failure on client wiring or host ingest before anyone opens SDK source.
The DSN carries the routing and the credential. `http://{public_key}@localhost:8080/{project_id}` gives the client a scheme, a host, a port, a project id and a public key [5]. From there the SDK posts to `/api/{project_id}/envelope/`, or to `/api/{project_id}/store/` on the legacy JSON path, with an `X-Sentry-Auth` header holding `sentry_version=7` and the key [6].
A 202 answers two questions: did auth pass, and did the schema parse [8]. Its body is a JSON id [7]. The write into Issues happens behind that accept, so the first debugging step in the dev.to walkthrough is to wait and refresh, because the accept runs ahead of the worker [11]. The empty-feed copy is `0 UNRESOLVED EXCEPTIONS`, and the walkthrough says that seeing it is not by itself proof of failure [13].
The browser example sets seven keys: `dsn`, `environment`, `release`, and four sample rates at zero [9]. One of the seven is the migration [1]. The other four exist to stop the SDK shipping transactions, session replay and profile payloads that an exception-only host discards on arrival [10].
Two checklist items are about stale state. `EPURE_PORT` and `EPURE_PUBLIC_URL` have to be set together in `.env`, and the app container has to be recreated after the edit [4][11]. The other is a leftover `dsn` or a second `Sentry.init` later in boot, still pointed at SaaS [11]. A working host paired with a client that never left the hosted plan is the expensive outcome of this exercise.
The bisect is the part I would keep. If the raw `store` curl returns 202 and the SDK path does not, the fault is in the client; if neither gets a 202, the walkthrough sends you to `docker compose logs` on the app service, the health endpoint and the DSN key [12]. Two calls, and the failure is localised without reading SDK source.
None of this adds up to a migration plan. The seed script is marked local smoke only, never production [15], and the walkthrough does not include retention, throughput or storage figures. For the 202 to mean anything in your codebase, your client has to be a 7.x SDK posting exception envelopes at the same two routes [2][6]. Anything further up the product line stays where it is: the walkthrough is explicit that APM, session replay, profiling, the log product and mobile SDKs should not be expected to work merely because the DSN looks familiar [14].
What to watch
- Whether the project publishes throughput, retention or storage figures for a non-laptop deployment with a worker tier.
- Whether the two ingest routes accept envelopes from SDK majors past 7.120.0. That decides how long the pin holds.
- Whether transaction, replay or profile envelope items move from discarded to stored. If they do, the sample-rate advice changes.