Deploy Errsole
Logger For Node.js With Dashboard To View, Filter, And Search Your App Logs
postgres
Just deployed
/var/lib/postgresql
errsole
Just deployed
Deploy and Host Errsole on Railway
Errsole is an open-source Node.js logger with a built-in web dashboard. It collects console logs, stores them in PostgreSQL, and lets you view, filter, and search them with authentication and team management. This template self-hosts a standalone Errsole dashboard on Railway — the dashboard process plus Postgres — so every app in the project can write logs to the same database while one public service serves the UI.
About Hosting Errsole
Hosting Errsole on Railway means two containers on the private network: a public dashboard (errsole) and a private PostgreSQL 17 database (postgres). Railway terminates TLS at the edge, so the dashboard listens on HTTP 0.0.0.0:${PORT} (default 8080). The entrypoint waits for Postgres over IPv6 private DNS, Errsole creates its tables (errsole_logs_v3, errsole_users, errsole_config, errsole_notifications) on first boot, then optionally seeds ADMIN_EMAIL / ADMIN_PASSWORD. Attach one volume on Postgres at /var/lib/postgresql before the first successful start. After deploy, open the public URL, sign in, and point your Node apps at the same DATABASE_URL with enableDashboard: false.
Common Use Cases
- Central log viewer for a Railway project — every Node service writes to the same Postgres, one dashboard to search them
- Replace CloudWatch / Elasticsearch for application logs when you want a small, self-hosted UI and SQL you can query
- Production error inbox — Slack or SMTP alerts on
errsole.alert()and uncaught exceptions, with a link back to the log line - Multi-app / multi-environment debugging — filter by
appName, hostname, level, and full-text search on the message - Keep logs inside your account — no third-party log vendor, 30-day TTL by default (change it in the dashboard)
Dependencies for Errsole Hosting
- Errsole dashboard image: built in
errsole/fromnode:22-bookworm-slim+errsole@2.18.2+errsole-postgres@3.0.0(there is no publishederrsole/errsole:latestimage) - PostgreSQL 17.5 (
postgres:17.5) — logs, dashboard users, JWT secret, notification state - Railway private networking —
postgres.railway.internal:5432(IPv6). Node is started with--dns-result-order=verbatim - One persistent volume (drive) — see Implementation Details
- Node.js apps (optional, not part of this stack) —
errsole+errsole-postgreswithenableDashboard: falseand the sameDATABASE_URL
Name the database service postgres and the web service errsole. Set each service Root Directory to its folder (errsole/, postgres/). Keep Postgres private; only Errsole gets a public domain.
Upstream: Errsole · docs.errsole.com · errsole.js · PostgreSQL storage · standalone dashboard
Implementation Details
Clone the template to see how it works:
errsole/ # public web service
Dockerfile # node:22-bookworm-slim + errsole + errsole-postgres
entrypoint.sh # IPv6 wait-for Postgres, then exec node
wait-for.cjs # TCP + SELECT 1 probe (AAAA-first DNS)
server.js # dashboard on 0.0.0.0:${PORT}, table init, admin seed
railway.toml # healthcheck /api/users/total-users, 300s timeout
postgres/
Dockerfile # postgres:17.5, listen_addresses=*
railway.toml # ON_FAILURE restart
examples/
logger.cjs # copy into your Node app (dashboard disabled)
logger.mjs
Topology
Name the services exactly as written. Private DNS is .railway.internal. If you rename them, update DATABASE_URL / POSTGRES_HOST to match.
| Service | Role | Root Directory | Volume | Memory | Public |
|---|---|---|---|---|---|
| postgres | Log + user database | postgres | /var/lib/postgresql | 1 GB | No |
| errsole | Web dashboard | errsole | None | 512 MB floor, 1 GB better | Yes |
Volumes (drives)
Attach before the first successful start. Skip this and init lands on ephemeral disk; the next deploy wipes logs and the admin user.
| Service | Mount path | What is stored | Start size |
|---|---|---|---|
| postgres | /var/lib/postgresql | Logs, dashboard users, JWT secret, config, notifications. PGDATA is /var/lib/postgresql/data. | 1 GB (grow with retention) |
| errsole | do not mount anything | Stateless. Railway terminates TLS. Tables live in Postgres. | — |
Do not mount /etc/letsencrypt, TLS certificates, or Errsole config files. Those are VPS/compose paths. Railway already terminates TLS.
Railway: postgres service → Settings → Volumes → Add Volume → paste /var/lib/postgresql exactly.
Environment variables
Generate POSTGRES_PASSWORD once on postgres. Reference it from errsole. Generate ADMIN_PASSWORD once on errsole.
postgres
| Variable | Value | Description |
|---|---|---|
POSTGRES_USER | errsole | Database role |
POSTGRES_DB | errsole | Database name |
POSTGRES_PASSWORD | ${{ secret(32) }} | Generated on this service; referenced by errsole |
PGDATA | /var/lib/postgresql/data | Data directory inside the volume |
errsole (required)
| Variable | Value | Description |
|---|---|---|
DATABASE_URL | postgresql://errsole:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/errsole | Private Postgres URL |
ADMIN_EMAIL | (you set) | First dashboard login |
ADMIN_PASSWORD | ${{ secret(32) }} | Auto-generated admin password. Copy it from Variables after deploy |
ADMIN_NAME | Admin | Display name for the seeded admin |
APP_NAME | errsole | Name shown in the dashboard |
errsole (optional)
| Variable | Default | Description |
|---|---|---|
ERRSOLE_PATH | / | Dashboard base path |
ERRSOLE_TABLE_PREFIX | (unset → errsole) | Must match every app that writes logs |
SMTP_HOST | — | Enable email alerts for alert / crashes |
SMTP_PORT | 587 | SMTP port |
SMTP_USERNAME / SMTP_PASSWORD | — | SMTP credentials |
SMTP_FROM | — | Sender address |
SMTP_RECIPIENTS | — | Comma-separated recipient list |
SLACK_WEBHOOK_URL | — | Slack incoming webhook for the same alerts |
Baked in — leave alone: PORT (Railway injects it), HOST=0.0.0.0, NODE_ENV=production, NODE_OPTIONS=--dns-result-order=verbatim. Do not set PORT=8001. Do not point DATABASE_URL at localhost or 127.0.0.1.
If you rename services: change ${{postgres.RAILWAY_PRIVATE_DOMAIN}} and ${{postgres.POSTGRES_PASSWORD}} to the new service name.
Traps
Ways this still fails:
- There is no
errsole/errsole:latestimage. Errsole is an npm module. This kit builds the standalone dashboard fromerrsole+errsole-postgres. Do not replace the Dockerfile withFROM errsole/errsole:latest. - App waits forever for Postgres: Postgres can be healthy while the dashboard never connects. Railway private DNS is IPv6. This kit sets
--dns-result-order=verbatimand probes AAAA inwait-for.cjs. Do not switch Node toipv4first. Do not uselocalhostor127.0.0.1forDATABASE_URL. - Do not terminate TLS inside the container. Railway already terminates TLS. The dashboard must listen on HTTP
0.0.0.0:${PORT}. There is no Let's Encrypt / certbot path to mount. - Do not use Railway's Postgres plugin for this template. The kit's
postgresservice ownsPOSTGRES_PASSWORDvia${{ secret(32) }}. A plugin database will not matchPOSTGRES_USER=errsole/POSTGRES_DB=errsoleunless you rewriteDATABASE_URLby hand. - Volume after first boot: If Postgres starts once without
/var/lib/postgresql, init is lost on the next deploy. Attach the volume first, then deploy. - Do not hardcode port 8001. Upstream defaults to 8001. Railway injects
PORT. The wrapper binds that port on0.0.0.0. - First admin is a one-shot register. If
ADMIN_EMAIL/ADMIN_PASSWORDare unset, the first visitor to/creates the admin. After that,/api/users/registerreturns 409. Set the env vars before the first boot if you want a known password. - Apps must share the database, not the dashboard process. In application services set
enableDashboard: falseand the sameDATABASE_URL+ERRSOLE_TABLE_PREFIX. Two dashboards on the same tables will fight over port/process; the Railwayerrsoleservice is the only UI. - Log TTL defaults to 30 days. Change it in the dashboard (admin → logs TTL) or rows older than 30 days are deleted by the hourly cron inside
errsole-postgres.
Why Deploy Errsole on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Errsole on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
Template Content
postgres
OpenSource-Templates/Errsoleerrsole
OpenSource-Templates/Errsole