Epure
Guide

Deploy Epure error tracking on Coolify with Docker Compose

Import the template from the Epure repository, set the domain and four variables, verify ingest, then schedule backups and pin upgrades.

An application module lifts above its fitted slot while a database remains on the deployment base.
Editorial illustration
On this pageShow
  1. What do you need before deploying Epure on Coolify?
  2. How do you create the Epure resource in Coolify?
  3. Which environment variables does Epure need on Coolify?
  4. How do you check that Epure on Coolify receives errors?
  5. How do you back up and upgrade Epure on Coolify?
  6. Why does Epure on Coolify fail to start or keep me signed out?
  7. Questions

Deploying Epure on Coolify takes one Git import and a short list of variables. The template in deploy/templates/coolify/docker-compose.yml runs the Epure image and postgres:16-alpine, turns on Secure session cookies, refuses the example database passwords, and leaves the MCP server off. The table is the whole procedure; each step has its own section below.

Epure on Coolify: step, check, fix

1. Import

Do
Public Git repo, Docker Compose build pack, base directory /deploy/templates/coolify
Confirm
Coolify lists two services: epure and postgres
If it fails
Check the base directory has a leading slash and the file is docker-compose.yml

2. Domain

Do
On epure, set Domains to https://errors.example.com:8080
Confirm
Certificate issued; the URL loads the login page
If it fails
Point DNS at the Coolify server; keep the :8080 suffix

3. Variables

Do
Set EPURE_IMAGE, EPURE_CORS_ORIGINS; leave generated passwords alone
Confirm
Both containers run and the epure log shows no error
If it fails
Read the exact error in the epure logs (see troubleshooting)

4. Health

Do
curl https://errors.example.com/health
Confirm
{"status":"ok"}
If it fails
Postgres not healthy yet, or the domain points elsewhere

5. First event

Do
Register, create a project, send one error with its DSN
Confirm
Ingest answers 202 and the issue appears
If it fails
Follow the ingest checklist

6. Lock and back up

Do
EPURE_REGISTRATION=false; schedule pg_dump
Confirm
Register returns 403 for new workspaces; a dump file exists off the server
If it fails
Redeploy after changing variables
DimensionDoConfirmIf it fails
1. ImportPublic Git repo, Docker Compose build pack, base directory /deploy/templates/coolifyCoolify lists two services: epure and postgresCheck the base directory has a leading slash and the file is docker-compose.yml
2. DomainOn epure, set Domains to https://errors.example.com:8080Certificate issued; the URL loads the login pagePoint DNS at the Coolify server; keep the :8080 suffix
3. VariablesSet EPURE_IMAGE, EPURE_CORS_ORIGINS; leave generated passwords aloneBoth containers run and the epure log shows no errorRead the exact error in the epure logs (see troubleshooting)
4. Healthcurl https://errors.example.com/health{"status":"ok"}Postgres not healthy yet, or the domain points elsewhere
5. First eventRegister, create a project, send one error with its DSNIngest answers 202 and the issue appearsFollow the ingest checklist
6. Lock and back upEPURE_REGISTRATION=false; schedule pg_dumpRegister returns 403 for new workspaces; a dump file exists off the serverRedeploy after changing variables

Checked against the epure-sh/epure repository (deploy/templates/coolify, v0.2.0, 5 Nov 2026) and Coolify's Docker Compose docs (coolify.io/docs/knowledge-base/docker/compose, read 6 Nov 2026).

What do you need before deploying Epure on Coolify?

Epure on Coolify needs a Coolify server with its proxy running on ports 80 and 443, and a DNS name such as errors.example.com pointing at it. HTTPS is not optional: the template sets EPURE_SESSION_SECURE=1, so a browser on plain HTTP drops the session cookie and sends you back to the login form. The two containers idled at about 5 MiB and 48 MiB on a 769 MiB VPS in our September measurement; your traffic, retention and source maps add to that.

Coolify fills three kinds of value from the compose file. SERVICE_PASSWORD_64_POSTGRES, SERVICE_PASSWORD_64_EPURE_INGEST and SERVICE_PASSWORD_64_EPURE_APP become 64-character passwords, and SERVICE_URL_EPURE_8080 becomes the public URL routed to port 8080 (Coolify compose docs). On every boot, after migrations, Epure sets the epure, epure_ingest and epure_app role passwords in Postgres from those URLs.

How do you create the Epure resource in Coolify?

Epure is imported into Coolify as a Docker Compose resource from the public repository, not from a marketplace entry. The six steps below match the template's own header comment. The :8080 suffix on the domain tells the Coolify proxy which container port receives requests; without it, the proxy cannot reach Epure.

  • In your project, choose + New, then a public Git repository, and paste https://github.com/epure-sh/epure.
  • Pick the Docker Compose build pack.
  • Set Base Directory to /deploy/templates/coolify and Docker Compose Location to docker-compose.yml.
  • Open the epure service and set Domains to https://errors.example.com:8080.
  • Set the variables in the next section.
  • Deploy, then open https://errors.example.com/login.

Which environment variables does Epure need on Coolify?

Epure on Coolify needs two variables from you before the first real event, and two more once you are signed in. The template defaults EPURE_IMAGE to ghcr.io/epure-sh/epure:latest with pull_policy: always, so every redeploy can change the version under you. Pin a release tag instead; the current one is v0.2.0. Everything else in the table has a working default in the template.

Variables to set in Coolify's Environment Variables tab

EPURE_IMAGE

Value
ghcr.io/epure-sh/epure:v0.2.0
Why
Upgrade when you choose, not on every redeploy

EPURE_CORS_ORIGINS

Value
https://errors.example.com,https://app.example.com
Why
Default is the Epure URL only; browser SDKs on your app's origin need it listed

EPURE_REGISTRATION

Value
Unset until your account exists, then false
Why
Stops strangers creating workspaces; sign-in and invitations keep working

EPURE_TRUSTED_PROXIES

Value
IP or CIDR of the proxy network, comma-separated
Why
Login rate limits read X-Forwarded-For only from listed proxies

EPURE_MCP_ENABLED

Value
true, only if you want /mcp
Why
Off by default; serves the hosted MCP endpoint for coding agents

SERVICE_PASSWORD_64_*

Value
Generated by Coolify
Why
Changing them after first boot breaks the superuser login; see troubleshooting
DimensionValueWhy
EPURE_IMAGEghcr.io/epure-sh/epure:v0.2.0Upgrade when you choose, not on every redeploy
EPURE_CORS_ORIGINShttps://errors.example.com,https://app.example.comDefault is the Epure URL only; browser SDKs on your app's origin need it listed
EPURE_REGISTRATIONUnset until your account exists, then falseStops strangers creating workspaces; sign-in and invitations keep working
EPURE_TRUSTED_PROXIESIP or CIDR of the proxy network, comma-separatedLogin rate limits read X-Forwarded-For only from listed proxies
EPURE_MCP_ENABLEDtrue, only if you want /mcpOff by default; serves the hosted MCP endpoint for coding agents
SERVICE_PASSWORD_64_*Generated by CoolifyChanging them after first boot breaks the superuser login; see troubleshooting

Coolify does not name its proxy network in its docs, so find the subnet on the host with docker network inspect on the network that both the proxy and the epure container join, and put that CIDR in EPURE_TRUSTED_PROXIES. The full list of variables is in self-hosting configuration.

How do you check that Epure on Coolify receives errors?

Epure answers GET /health with {"status":"ok"} as soon as the server runs. GET /health/ready goes further: it queries both database pools and returns 503 if the ingest queue has dead letters or its oldest item is more than 5 minutes old. Neither proves your SDK reaches the right project, so finish with one real error from a staging app.

curl -sS https://errors.example.com/health
# {"status":"ok"}
curl -sS https://errors.example.com/health/ready
# {"status":"ok","database":"ok",...}

Register at /login; the first account owns a new workspace. Create a project, copy its DSN, and send one error from any official Sentry SDK with tracing off. Ingest answers 202, and the issue appears on the Issues page within seconds. If the request succeeds and no issue shows, work through the ingest checklist before touching Coolify.

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

Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 0 });
Sentry.captureException(new Error("Epure on Coolify test"));
await Sentry.flush(2000);

How do you back up and upgrade Epure on Coolify?

Epure keeps everything that matters in two named volumes: postgres_data for issues, events and settings, and artifacts_data for uploaded JS/TS source maps. Coolify's Docker Compose docs do not describe backups for a database defined inside a compose resource, so plan your own. A nightly pg_dump in custom format, copied off the server, covers the database.

# on the Coolify host
PG=$(docker ps --filter name=postgres --format '{{.Names}}' | grep -v coolify | head -n1)
docker exec "$PG" pg_dump -U epure -d epure -Fc > "epure-$(date +%Y%m%d).dump"

Check that $PG names the Epure Postgres container before you schedule it; a server with several databases needs a stricter filter. To upgrade, take a dump, change EPURE_IMAGE to the new tag and redeploy; migrations run on boot. Read the release notes first, because schema changes move forward only. Rollback means restoring the dump with pg_restore --clean --if-exists and redeploying the previous tag, as in Epure upgrades.

Why does Epure on Coolify fail to start or keep me signed out?

Epure on Coolify fails in four common ways, and each one prints a specific message in the browser or in the epure container log. Open the service's logs in Coolify first, then match the line to a heading below. Most fixes are one variable and a redeploy; none requires deleting the postgres_data volume. Other options for running a tracker yourself are in self-hosted error tracking compared.

Login succeeds, then the login form comes back

The session cookie is Secure, so the browser drops it on plain HTTP. Open the https:// URL, not the server IP or port 8080, and check that Coolify issued a certificate for the domain.

example database passwords are not allowed unless EPURE_PUBLIC_URL is localhost

A database URL still carries epure, epure_ingest or epure_app as its password. This happens when the SERVICE_PASSWORD_64_* variables are empty or were replaced by hand. Restore the generated values and redeploy.

password authentication failed for user "epure"

Postgres sets its superuser password only when the postgres_data volume is first created. If SERVICE_PASSWORD_64_POSTGRES changed after that, put the original value back, or change the password inside Postgres to match. The ingest and app roles are reset from the URLs on every boot.

Browser errors are blocked by CORS

The template allows only the Epure URL by default. Add your app's origins to EPURE_CORS_ORIGINS, comma-separated, and redeploy. Server-side SDKs are not affected. More cases are in self-hosting troubleshooting.

Questions

Is the Coolify template the same Epure as the Docker Compose install?
Yes. It runs the same image and postgres:16-alpine as the installation guide, with production settings: Secure cookies, no example passwords, and generated role passwords. The difference is that Coolify's proxy terminates HTTPS instead of the Caddy profile in deploy/docker-compose.prod.yml.
Does self-hosted Epure on Coolify have an event limit?
No. Self-hosted Epure under AGPL-3.0 has no event quota and no seat limit; your server's disk and CPU are the only bounds. Quotas and the over-quota rule apply only to Epure Cloud plans. Retention on your instance follows your own policy.
Can I deploy Epure on Dokploy, Railway or Render instead?
Yes. The repository also carries a Dokploy compose file in deploy/templates/dokploy, a Railway compose file in deploy/railway and a render.yaml Blueprint at the root. Each runs the same two containers. The table in the installation guide lists the entry point for each platform.