Self-Hosting

Run your own Pulsync server. Devices speak the same protocol either way — they can’t tell hosted from self-hosted.

The self-hosted server is fully self-contained: SQLite for storage and an in-process MQTT broker, so there’s no external database or broker to set up. It gives you device enrollment, telemetry, commands, remote config, OTA firmware hosting, a local dashboard, and mDNS discovery (pulsync.local).

Requirements

  • Node.js 20+
  • Build tools for the native better-sqlite3 module (Xcode Command Line Tools on macOS, build-essential on Debian/Ubuntu). Prebuilt binaries cover most setups, so you usually won’t need to compile anything.

Run with Node

git clone https://github.com/Pulsync/pulsync-server.git
cd pulsync-server
npm install
npm start

That’s it — SQLite + embedded MQTT, no external services. Open the dashboard at http://localhost:3456/. On the LAN the server also advertises itself as pulsync.local, so devices can find it by name.

Run with Docker (optional)

Docker isn’t required, but a Compose file is included if you prefer a containerized deploy:

git clone https://github.com/Pulsync/pulsync-server.git
cd pulsync-server
docker compose up

Same single self-contained service (SQLite + embedded MQTT), exposing HTTP on 3456 and MQTT on 1883, with volumes for the database and firmware.

Point a device at it

Pulsync.setServer("pulsync.local:3456");        // by mDNS name (recommended)
Pulsync.setServer("http://192.168.1.50:3456");  // by IP

Or set nothing — the library auto-discovers a local server on the LAN. See Connectivity.

Configuration

Everything is optional and set via environment variables (see .env.example):

VariableDefaultPurpose
PORT3456HTTP port (dashboard + device API)
MQTT_PORT1883Embedded MQTT broker port
DATABASE_URL(unset → SQLite)Set a postgresql:// URL to use Postgres instead
ADMIN_PASSWORD(empty → open)Password gate for the dashboard + management routes
JWT_SECRET(random per run)Signs admin sessions; set a stable value to persist them

Security notes

  • ADMIN_PASSWORD gates the dashboard and management routes. It’s open by default, which is fine on a trusted LAN — set it if the dashboard is reachable beyond your network. Device-facing routes stay open; devices authenticate with their own token.
  • JWT_SECRET signs admin session cookies. Leave it unset and a random key is used (sessions reset on restart); set a long random value (openssl rand -hex 32) to keep sessions stable.
  • The dashboard runs over plain HTTP for LAN use. Put it behind a TLS reverse proxy if you expose it publicly.