epure-sh/epure

Exception-only error monitoring. Sentry SDK compatible. 2-container self-host.

TypeScript

2

3 commits

updated Sep 22, 2026

See the code

See what people are saying (1)

README

Epure

License: Apache 2.0 Rust PostgreSQL 16 Docker Compose CI Image GHCR

Epure

Epure is exception-only error monitoring for self-hosters. Keep your official Sentry SDKs. Change the DSN. When production throws, you get a grouped issue and a stack you can read.

  • Official Sentry SDK ingest (envelope + store). Docs
  • Grouped issues, breadcrumbs, JS/TS sourcemaps. Quickstart
  • Spike valve for infinite loops. Concepts
  • Keyboard triage (j / k / e / i) + Markdown export for LLMs
  • Alerts, webhooks, releases, regressions
  • Multi-project orgs, DSN rotate/revoke, RBAC
  • Two containers: Rust binary + PostgreSQL 16 with RLS. Self-host
  • Dashboard

Epure Issues dashboard

2 containers · ~50 MiB idle · ~10 s to first issue · measured 2026-09-20 on Docker Desktop (re-verify on your hardware).

Watch "releases" of this repo to get notified of major updates.

CI and multi-arch image builds run on GitHub Actions (ci.yml, image.yml). Published images: ghcr.io/epure-sh/epure.

Documentation

Full documentation: epure.sh/docs

Website: epure.sh · Self-host landing: epure.sh/selfhost

Community & Support

  • GitHub Discussions. Best for: setup questions and DSN wiring.
  • GitHub Issues. Best for: bugs and SDK / protocol gaps (use a template).
  • SECURITY.md. Best for: vulnerabilities · security@news.epure.sh
  • Email support · support@news.epure.sh. Best for: Cloud / commercial questions.
  • CODE_OF_CONDUCT.md. Conduct · conduct@news.epure.sh

Get started

Docker Compose v2. No .env file. No configure step.

git clone https://github.com/epure-sh/epure.git && cd epure
docker compose up
curl -sS http://localhost:8080/health   # → {"status":"ok"}

Open http://localhost:8080 → register → name a project → copy the DSN → point your SDK.

Port 8080 taken, demo data, or production VPS

Another port — copy .env.example, set EPURE_PORT (public URL follows on localhost), recreate epure:

cp .env.example .env   # edit EPURE_PORT=3000
docker compose up

Or ./configure --quick to auto-pick a free port.

Demo seed + Vite CORS — uncomment EPURE_DEV_SEED=1 and EPURE_CORS_ORIGINS in .env, or ./configure --dev.

Production./configure --prod or .env.production.example + installation guide. Full env reference: Configuration.

import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "http://{public_key}@localhost:8080/{project_id}",
  tracesSampleRate: 0,
  replaysSessionSampleRate: 0,
  replaysOnErrorSampleRate: 0,
  profilesSampleRate: 0,
});

No @epure/* package. Zero the extra product lines so transactions, replay, and profiles are discarded without surprise. Walkthrough: epure.sh/docs/get-started/quickstart. Production: epure.sh/docs/self-hosting/installation.

Dev seed (skip register) — ⚠️ DEV ONLY
./scripts/seed-dev.sh
# login: dev@epure.local / devpassword

How it works

Epure is a small stack for one job: production exceptions → grouped issues → calm triage. It is not a 1-to-1 mapping of Sentry. If the SDK sends transactions, replay, or profiles, the HTTP request is accepted and those items are dropped.

Architecture

Self-host with Docker Compose (two containers). You can also use managed hosting.

graph TD
  SDK[Sentry SDKs] -->|POST envelope or store| EPURE[epure :8080]
  Browser[Browser dashboard] -->|session API| EPURE
  EPURE -->|SQLx async worker| PG[(PostgreSQL 16)]
  EPURE -->|rust-embed SPA| Browser

Plain text: SDKs and the dashboard hit the same Rust process. Host port is EPURE_PORT (default 8080); the process still binds 8080 inside the container. Persistence is PostgreSQL 16 only. No Redis. No Kafka. No separate worker container.

ServicePortRole
epurehost EPURE_PORT (default 8080) → 8080Ingest + APIs + embedded SPA (--mode=all)
postgreshost POSTGRES_HOST_PORT (default 5433) → 5432RLS, monthly event partitions, sessions
  • Ingest gateway — DSN auth, 2 MB body cap, spike valve, Tokio mpsc, returns 202 before persist.
  • Spike valve — per-fingerprint token bucket (~100/min). Over limit: counter bumps, duplicate bodies drop. Separate project cap: 5000 events/hour.
  • Worker — demangle JS/TS sourcemaps, scrub PII, group by fingerprint, micro-batch INSERT.
  • PostgreSQL 16 — issues, events, releases, sessions. Dashboard queries use RLS (app.current_org_id).
  • Dashboard — React SPA embedded via rust-embed. Keyboard-first Issues UI.

Ingest path (plain text): SDK → DSN check → spike valve → enqueue → 202 → worker demangle/scrub/group → Postgres.

SDK clients

Keep the official Sentry clients. Epure is the destination.

LanguageStatusNotes
Browser (@sentry/browser 7.x)E2E in CISourcemaps demangle
Python (store)E2E in CIRaw frames
Node (@sentry/node 7.x)Parse + fixtureSourcemaps demangle
Go, Ruby, PHP, Java, .NETFixture capturedRaw frames

Full matrix and init snippets: epure.sh/docs/platforms. Wire contract in-repo: docs/ingest.openapi.yaml.

Out of scope (Phase 1)

Distributed tracing · session replay · continuous profiling · generic log ingest · iOS/Android symbolication · Redis / Kafka / ClickHouse on the path.

How Epure compares

Measured Epure figures from this repo (2026-09-20). Competitor figures from their documentation as of 2026-09. Re-verify before you rely on them.

EpureSentry self-hostGlitchTip
Containers220+ (docs)4+ (install)
RAM~50 MiB idle (measured)16 GB + swap (guide)512 MB rec / 256 MB min
SDK pathChange DSNChange DSNChange DSN
LicenseApache 2.0BSL / SaaSMIT

If GlitchTip is already quiet for you, stay there.


Apache 2.0 · no ee/ split · CHANGELOG · CONTRIBUTING

Managed hosting: Epure Cloud — Pro $24/mo · Plus $79/mo. Flat pricing, no per-event overage. epure.sh

developer-tools
docker
error-tracking
monitoring
observability
open-source
postgresql
rust
self-hosted
sentry

Contributors

Amorizz

3 commits

epure-sh/epure

Exception-only error monitoring. Sentry SDK compatible. 2-container self-host.

TypeScript

2

3 commits

updated Sep 22, 2026

See the code

See what people are saying (1)

README

Epure

License: Apache 2.0 Rust PostgreSQL 16 Docker Compose CI Image GHCR

Epure

Epure is exception-only error monitoring for self-hosters. Keep your official Sentry SDKs. Change the DSN. When production throws, you get a grouped issue and a stack you can read.

  • Official Sentry SDK ingest (envelope + store). Docs
  • Grouped issues, breadcrumbs, JS/TS sourcemaps. Quickstart
  • Spike valve for infinite loops. Concepts
  • Keyboard triage (j / k / e / i) + Markdown export for LLMs
  • Alerts, webhooks, releases, regressions
  • Multi-project orgs, DSN rotate/revoke, RBAC
  • Two containers: Rust binary + PostgreSQL 16 with RLS. Self-host
  • Dashboard

Epure Issues dashboard

2 containers · ~50 MiB idle · ~10 s to first issue · measured 2026-09-20 on Docker Desktop (re-verify on your hardware).

Watch "releases" of this repo to get notified of major updates.

CI and multi-arch image builds run on GitHub Actions (ci.yml, image.yml). Published images: ghcr.io/epure-sh/epure.

Documentation

Full documentation: epure.sh/docs

Website: epure.sh · Self-host landing: epure.sh/selfhost

Community & Support

  • GitHub Discussions. Best for: setup questions and DSN wiring.
  • GitHub Issues. Best for: bugs and SDK / protocol gaps (use a template).
  • SECURITY.md. Best for: vulnerabilities · security@news.epure.sh
  • Email support · support@news.epure.sh. Best for: Cloud / commercial questions.
  • CODE_OF_CONDUCT.md. Conduct · conduct@news.epure.sh

Get started

Docker Compose v2. No .env file. No configure step.

git clone https://github.com/epure-sh/epure.git && cd epure
docker compose up
curl -sS http://localhost:8080/health   # → {"status":"ok"}

Open http://localhost:8080 → register → name a project → copy the DSN → point your SDK.

Port 8080 taken, demo data, or production VPS

Another port — copy .env.example, set EPURE_PORT (public URL follows on localhost), recreate epure:

cp .env.example .env   # edit EPURE_PORT=3000
docker compose up

Or ./configure --quick to auto-pick a free port.

Demo seed + Vite CORS — uncomment EPURE_DEV_SEED=1 and EPURE_CORS_ORIGINS in .env, or ./configure --dev.

Production./configure --prod or .env.production.example + installation guide. Full env reference: Configuration.

import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "http://{public_key}@localhost:8080/{project_id}",
  tracesSampleRate: 0,
  replaysSessionSampleRate: 0,
  replaysOnErrorSampleRate: 0,
  profilesSampleRate: 0,
});

No @epure/* package. Zero the extra product lines so transactions, replay, and profiles are discarded without surprise. Walkthrough: epure.sh/docs/get-started/quickstart. Production: epure.sh/docs/self-hosting/installation.

Dev seed (skip register) — ⚠️ DEV ONLY
./scripts/seed-dev.sh
# login: dev@epure.local / devpassword

How it works

Epure is a small stack for one job: production exceptions → grouped issues → calm triage. It is not a 1-to-1 mapping of Sentry. If the SDK sends transactions, replay, or profiles, the HTTP request is accepted and those items are dropped.

Architecture

Self-host with Docker Compose (two containers). You can also use managed hosting.

graph TD
  SDK[Sentry SDKs] -->|POST envelope or store| EPURE[epure :8080]
  Browser[Browser dashboard] -->|session API| EPURE
  EPURE -->|SQLx async worker| PG[(PostgreSQL 16)]
  EPURE -->|rust-embed SPA| Browser

Plain text: SDKs and the dashboard hit the same Rust process. Host port is EPURE_PORT (default 8080); the process still binds 8080 inside the container. Persistence is PostgreSQL 16 only. No Redis. No Kafka. No separate worker container.

ServicePortRole
epurehost EPURE_PORT (default 8080) → 8080Ingest + APIs + embedded SPA (--mode=all)
postgreshost POSTGRES_HOST_PORT (default 5433) → 5432RLS, monthly event partitions, sessions
  • Ingest gateway — DSN auth, 2 MB body cap, spike valve, Tokio mpsc, returns 202 before persist.
  • Spike valve — per-fingerprint token bucket (~100/min). Over limit: counter bumps, duplicate bodies drop. Separate project cap: 5000 events/hour.
  • Worker — demangle JS/TS sourcemaps, scrub PII, group by fingerprint, micro-batch INSERT.
  • PostgreSQL 16 — issues, events, releases, sessions. Dashboard queries use RLS (app.current_org_id).
  • Dashboard — React SPA embedded via rust-embed. Keyboard-first Issues UI.

Ingest path (plain text): SDK → DSN check → spike valve → enqueue → 202 → worker demangle/scrub/group → Postgres.

SDK clients

Keep the official Sentry clients. Epure is the destination.

LanguageStatusNotes
Browser (@sentry/browser 7.x)E2E in CISourcemaps demangle
Python (store)E2E in CIRaw frames
Node (@sentry/node 7.x)Parse + fixtureSourcemaps demangle
Go, Ruby, PHP, Java, .NETFixture capturedRaw frames

Full matrix and init snippets: epure.sh/docs/platforms. Wire contract in-repo: docs/ingest.openapi.yaml.

Out of scope (Phase 1)

Distributed tracing · session replay · continuous profiling · generic log ingest · iOS/Android symbolication · Redis / Kafka / ClickHouse on the path.

How Epure compares

Measured Epure figures from this repo (2026-09-20). Competitor figures from their documentation as of 2026-09. Re-verify before you rely on them.

EpureSentry self-hostGlitchTip
Containers220+ (docs)4+ (install)
RAM~50 MiB idle (measured)16 GB + swap (guide)512 MB rec / 256 MB min
SDK pathChange DSNChange DSNChange DSN
LicenseApache 2.0BSL / SaaSMIT

If GlitchTip is already quiet for you, stay there.


Apache 2.0 · no ee/ split · CHANGELOG · CONTRIBUTING

Managed hosting: Epure Cloud — Pro $24/mo · Plus $79/mo. Flat pricing, no per-event overage. epure.sh

developer-tools
docker
error-tracking
monitoring
observability
open-source
postgresql
rust
self-hosted
sentry

Contributors

Amorizz

3 commits

Languages

TypeScript

53.3%

Rust

31.7%

Shell

6.3%

Python

3.9%

CSS

2.3%

PLpgSQL

2.1%