Skip to content

me-shaon/pulsedeck

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

114 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

PulseDeck


A self-hosted dashboard for your AI agents' output.

Agents, scripts, and automations send their reports to PulseDeck. You get one clean, searchable place to read them — instead of digging through Slack, email, and terminal logs.

License: AGPL v3 Self-hosted Node.js PostgreSQL

Quick start · What you get · Connect an agent · Documentation


PulseDeck — click to view full size

Quick start

You need Docker and make (plus openssl, preinstalled on macOS/Linux).

git clone https://github.com/me-shaon/pulsedeck.git pulsedeck && cd pulsedeck
make setup        # creates .env and generates strong secrets (idempotent)
docker compose up # pulls the published images; or `make up` to run detached

make setup is required: the stack refuses to boot without a real AUTH_SECRET/POSTGRES_PASSWORD, so it can never run on a known value.

Open http://localhost:3000, create your account and workspace, and you're running.

The images are pre-built and published to Docker Hub (ahmedshamimhassan/pulsedeck-api, ahmedshamimhassan/pulsedeck-web), so docker compose up never builds locally. Pin a release with PULSEDECK_VERSION=v1.0.0 docker compose up; omit it for :latest. To build from source instead — e.g. after editing a Dockerfile — use make build / make up-build.

Deploy without cloning: because the compose file is self-contained, you only need three files on the host — docker-compose.yml, .env (from .env.example), and a valid AUTH_SECRET/POSTGRES_PASSWORD — then docker compose up -d.

See it with live data

Want to watch it fill up? Run the built-in demo agent — it sends realistic reports every 30 seconds:

  1. In the app, go to Sources → Add source and copy the registration token (reg_…).
  2. Run the demo agent:
pnpm --filter @pulsedeck/demo dev --url http://localhost:3000 --token reg_xxxxx

Charts, streams, and the live feed start populating right away.

Heads up: the demo agent runs with Node 22+ and pnpm on your host — it's a workspace package, not part of the Docker image. If you set up with Docker and don't have Node/pnpm, either install them or skip the demo; PulseDeck itself runs fine without it.

Port already taken? Override it inline, e.g. WEB_PORT=8080 docker compose up. Defaults: web 3000, api 3001, postgres 5432.

Run without Docker

Manual setup for local development and production (no Docker required)

PulseDeck is a standard pnpm monorepo. The only external service it needs is PostgreSQL — Redis is optional (used solely for multi-replica realtime fan-out). The API applies its database migrations automatically on startup, so there is no separate migration step.

Prerequisites

  • Node.js 22+
  • pnpm 9.15+corepack enable && corepack prepare pnpm@9.15.0 --activate
  • PostgreSQL 16+ — running and reachable

1. Install dependencies

git clone https://github.com/me-shaon/pulsedeck.git pulsedeck && cd pulsedeck
pnpm install --frozen-lockfile

2. Create the database

psql -U postgres -c "CREATE USER pulsedeck WITH PASSWORD 'pulsedeck';"
psql -U postgres -c "CREATE DATABASE pulsedeck OWNER pulsedeck;"
# Postgres 15+ locks down the public schema — grant it explicitly:
psql -U postgres -d pulsedeck -c "GRANT ALL ON SCHEMA public TO pulsedeck;"

3. Configure the API

The API reads its config from apps/api/.env (real environment variables always win). Create it with at least the two required values:

cat > apps/api/.env <<'EOF'
DATABASE_URL=postgres://pulsedeck:pulsedeck@localhost:5432/pulsedeck
AUTH_SECRET=replace-with-32+-random-chars   # e.g. `openssl rand -base64 48`
EOF

All other options (retention, OAuth, signup mode, …) are documented in .env.example. Note DATABASE_URL ships commented out there: the Docker stack builds its own URL (DB host postgres) from POSTGRES_PASSWORD, and a localhost value in the root .env would break it. For this non-Docker path you set DATABASE_URL explicitly (host localhost) in apps/api/.env, as above.

4a. Local development (hot reload)

pnpm dev

This starts the API on :3001 and the web dev server on :3000 (Vite proxies /api → the API, keeping cookies first-party). Migrations run on API start. Open http://localhost:3000.

The demo agent works the same as above: pnpm --filter @pulsedeck/demo dev --url http://localhost:3000 --token reg_xxxxx.

4b. Production

Build everything:

pnpm build

This emits the API bundle to apps/api/dist and the static web bundle to apps/web/dist.

Start the API (it applies pending migrations, then listens):

cd apps/api
NODE_ENV=production \
DATABASE_URL=postgres://pulsedeck:pulsedeck@localhost:5432/pulsedeck \
AUTH_SECRET=your-32+-char-secret \
BETTER_AUTH_URL=https://your.domain \
PORT=3001 \
node dist/index.js

Keep it alive with a process manager (systemd, pm2, …). BETTER_AUTH_URL must be the public origin users hit (the web origin below), not the API port.

Serve the web bundle. apps/web/dist is static files. The SPA calls /api on its own origin, so put a reverse proxy in front that serves the static files and forwards /api to the API. Example nginx (mirrors the bundled apps/web/nginx.conf):

server {
  listen 80;
  server_name your.domain;
  root /path/to/pulsedeck/apps/web/dist;
  index index.html;

  location /api/ {
    proxy_pass http://127.0.0.1:3001;        # keeps the /api prefix
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    # Server-Sent Events (live updates): flush immediately, don't time out.
    proxy_set_header Connection '';
    proxy_buffering off;
    proxy_read_timeout 1h;
  }

  location / {
    try_files $uri $uri/ /index.html;        # SPA client-side routing
  }
}

Caddy alternative (Caddyfile):

your.domain {
  root * /path/to/pulsedeck/apps/web/dist
  handle /api/* {
    reverse_proxy 127.0.0.1:3001
  }
  handle {
    try_files {path} /index.html
    file_server
  }
}

Put TLS in front (Caddy does this automatically; for nginx use certbot) and set BETTER_AUTH_URL=https://your.domain to match.


What you get

  • One inbox for every agent — reports land organized into categories and streams, newest first.
  • Rich, structured reports — metrics, charts, tables, timelines, alerts, and status grids, not just walls of text.
  • Search everything — full-text search and filters by source, severity, tags, and date.
  • Custom dashboards — drag-and-drop widgets to build the view you want.
  • Teams — multiple workspaces, roles, and invite links.
  • Live updates — new reports appear instantly, no refresh needed.
  • Yours to host — one command, only needs PostgreSQL. No SaaS lock-in.

Connect an agent

Any agent that can make an HTTP request can send reports — no SDK or special library needed. Register once to get an API key, then POST your reports.

The Add source page in the app gives you a ready-to-paste setup prompt. For the full API, see the documentation.

Want a working example? packages/demo is a complete reference agent you can read and copy.


Email & password reset

Out of the box PulseDeck sends no email — invite links surface in the app, and the Forgot password? flow shows a warning that email isn't configured. To enable password-reset delivery (and emailed invites), point PulseDeck at an SMTP server:

EMAIL_PROVIDER=smtp
EMAIL_FROM="PulseDeck <no-reply@yourdomain.com>"
SMTP_HOST=smtp.yourprovider.com
SMTP_PORT=587            # 587 STARTTLS (default) or 465 with SMTP_SECURE=true
SMTP_USER=...
SMTP_PASS=...

Once EMAIL_PROVIDER=smtp and SMTP_HOST are set, the admin banner in Settings disappears and reset links are delivered by email. Any standard SMTP provider works (Mailgun, Postmark, SES SMTP, Resend SMTP, your own server, etc.). See .env.example for all options.


Documentation

Detailed guides — configuration, deployment, the full agent API, and development setup — live on the docs site:

📖 PulseDeck Documentation

Quick links for now:

  • Configure — all options live in .env.example.
  • Developmake dev runs the whole stack in Docker with hot reload. make help lists every command.
  • Contribute — see CONTRIBUTING.md.

License

PulseDeck is licensed under the GNU AGPL v3 — see LICENSE. Contributions require agreement to the CLA. Running it as a commercial hosted service requires open-sourcing your changes, or a commercial license.


PulseDeck

PulseDeck — a home for your agents' reports.

Self-hosted · Open source · AGPL v3

About

PulseDeck — the reporting inbox for your AI agents.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

20 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors