Deployment

June 7, 2026 · View on GitHub

Deploy a pinglet server once. All your npm packages can send analytics to the same server.

Quickstart (30 seconds)

npm install -g @black-knight.dev/pinglet
PORT=3456 PINGLET_ADMIN_USER=admin PINGLET_ADMIN_PASSWORD=<password> pinglet-server

Done. POST /ping is ready, GET /stats works with the admin password.

But this server dies when your terminal closes. For production, use one of the options below.


Idiot-proof, one-click, persistent. Full guide: deploy-railway.md

What you need:

  • Push the repo to GitHub
  • Create a Railway project from the repo
  • One Railway volume, three env vars
  • That's it

What Railway gives you automatically:

  • HTTPS
  • Public URL
  • Auto-restart on crash
  • Logs
  • Zero-config (reads railway.json)

Docker

Use the included Dockerfile:

# Build
docker build -t pinglet .

# Run with persistent volume
docker run -d \
  --name pinglet \
  -p 3456:3456 \
  -v pinglet-data:/data \
  -e PINGLET_DATA_DIR=/data \
  -e PINGLET_ADMIN_USER=admin \
  -e PINGLET_ADMIN_PASSWORD=$(openssl rand -base64 32) \
  --restart unless-stopped \
  pinglet

Works on any host: Fly.io, Render, DigitalOcean, AWS, your own VPS.


Fly.io

fly launch --dockerfile Dockerfile
fly volumes create pinglet_data --size 1
fly secrets set PINGLET_DATA_DIR=/data PINGLET_ADMIN_USER=admin PINGLET_ADMIN_PASSWORD=<password>
fly deploy

After deploying

1. Login from your machine

Install the CLI:

npm install -g @black-knight.dev/pinglet
# or via npx: npx -p @black-knight.dev/pinglet pinglet login ...

Then login:

pinglet login --url https://your-app.example.com --user admin

Enter the admin password once. A 30-day token is saved locally.

2. Check health

pinglet health

3. Add to your npm packages

npm install @black-knight.dev/pinglet

Then 5 lines of code. See maintainer-guide.md for the full integration checklist.

4. Read analytics

pinglet                        # status overview
pinglet ls                     # list packages
pinglet my-cli                 # show stats

All env vars

VarDefaultDescription
PORT3456HTTP port
PINGLET_DATA_DIR./dataWhere NDJSON files and sessions are stored
PINGLET_ADMIN_USERadminAdmin username for Basic Auth
PINGLET_ADMIN_PASSWORDSet this to protect /stats and /packages
PINGLET_INGEST_TOKENOptional: protect POST /ping

Important: persistent data

The NDJSON files are your only data. Without a persistent volume/directory:

  • Railway restarts → all analytics lost
  • Docker container removed → all analytics lost

Always mount a volume at PINGLET_DATA_DIR. On Railway, set PINGLET_DATA_DIR=/data and mount a volume at /data. On Docker, use -v.