---
title: "Deploy Errsole"
description: "Logger For Node.js With Dashboard To View, Filter, And Search Your App Logs"
category: "Other"
url: https://railway.com/deploy/errsole
---

# Deploy Errsole

Logger For Node.js With Dashboard To View, Filter, And Search Your App Logs

**[Deploy Errsole on Railway](https://railway.com/template/errsole)**

- **Creator:** OpenSource Templates
- **Category:** Other
- **Total deploys:** 2

## Template content

### postgres https://devicons.railway.com/i/postgresql.svg

- **Source:** OpenSource-Templates/Errsole

### errsole https://www.errsole.com/assets/images/favicon.png

- **Source:** OpenSource-Templates/Errsole
- **Public domain:** Yes

## Documentation

# 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.

[![Deploy on Railway](https://railway.app/button.svg)](https://railway.com/new/template/errsole)

## 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/` from `node:22-bookworm-slim` + `errsole@2.18.2` + `errsole-postgres@3.0.0` (there is no published `errsole/errsole:latest` image)
- **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-postgres` with `enableDashboard: false` and the same `DATABASE_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](https://www.errsole.com/) · [docs.errsole.com](https://docs.errsole.com) · [errsole.js](https://github.com/errsole/errsole.js) · [PostgreSQL storage](https://github.com/errsole/errsole.js/blob/master/docs/postgresql-storage.md) · [standalone dashboard](https://github.com/errsole/errsole.js/discussions/113)

### Implementation Details

Clone the template to see how it works:

```text
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:latest` image.** Errsole is an npm module. This kit builds the standalone dashboard from `errsole` + `errsole-postgres`. Do not replace the Dockerfile with `FROM 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=verbatim` and probes AAAA in `wait-for.cjs`. Do not switch Node to `ipv4first`. Do not use `localhost` or `127.0.0.1` for `DATABASE_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 `postgres` service owns `POSTGRES_PASSWORD` via `${{ secret(32) }}`. A plugin database will not match `POSTGRES_USER=errsole` / `POSTGRES_DB=errsole` unless you rewrite `DATABASE_URL` by 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 on `0.0.0.0`.
- **First admin is a one-shot register.** If `ADMIN_EMAIL` / `ADMIN_PASSWORD` are unset, the first visitor to `/` creates the admin. After that, `/api/users/register` returns 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: false` and the same `DATABASE_URL` + `ERRSOLE_TABLE_PREFIX`. Two dashboards on the same tables will fight over port/process; the Railway `errsole` service 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.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/errsole
