Skip to content

Running it as a service

Nobody should have to stay logged in for the service desk to keep running. Register Plugboard with the platform so it starts at boot with nobody logged in.

From the install directory:

Terminal window
# Linux
sudo ./plugboard install-service
# macOS
sudo ./plugboard install-service
Terminal window
# Windows, from an elevated Command Prompt or PowerShell
plugboard.cmd install-service

It starts immediately and comes back after a reboot.

PlatformWhat
LinuxA systemd unit running as an unprivileged plugboard account, with Restart=always and the filesystem locked down to its own directory. Pass --user someone to choose the account
macOSA LaunchDaemon under /Library/LaunchDaemons, with KeepAlive
WindowsA Scheduled Task at system startup, running as LocalSystem. See below
Terminal window
./plugboard service-status # ask the platform how it is doing
./plugboard uninstall-service # remove it; your data is left alone

Uninstalling the service does not remove the application or its database. It removes the registration.

A Windows Service has to talk to the Service Control Manager, and a plain Node process cannot. Pointing sc create at node.exe produces the well-known “error 1053: the service did not respond to the start request in time”.

So by default Plugboard registers a Scheduled Task that runs at system startup as LocalSystem. It genuinely survives reboots and runs with nobody logged in, which is what actually matters. It appears in Task Scheduler rather than in services.msc, which is the part people notice.

If you want a real service entry, drop a service wrapper next to the program:

  1. Download WinSW and rename it plugboard-service.exe.

  2. Put it in the Plugboard directory.

  3. Re-register:

    Terminal window
    plugboard.cmd uninstall-service
    plugboard.cmd install-service

The matching plugboard-service.xml is written for you either way, so adopting this later costs one command.

If you would rather manage the definition, here is a systemd unit for a source install:

[Unit]
Description=Plugboard
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/plugboard
ExecStart=/usr/bin/node scripts/plugboard.mjs start --no-build
EnvironmentFile=/opt/plugboard/.env
Restart=always
RestartSec=5
User=plugboard
Group=plugboard
# Reasonable hardening for something that only needs its own directory.
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/plugboard
[Install]
WantedBy=multi-user.target
Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now plugboard
sudo journalctl -u plugboard -f

--no-build matters in a unit file. A restart should not be able to fail on a compilation error at three in the morning.

If you are not putting a reverse proxy in front and want the application itself on 443, Linux needs the capability. The generated unit already grants it. If you changed the account the service runs as, reinstall the service so the capability is re-applied.

On Windows, check nothing else already has 443. IIS is the usual culprit, and it binds by default on a fresh Windows Server.

PlatformWhere
Linuxjournald: journalctl -u plugboard -f
macOSlogs/ inside the install directory
Windowslogs/ inside the install directory
SymptomCause
“Administrator rights are required”Run the elevated shell, or use sudo
Service starts then stopsCheck the logs. Usually a port already in use, or a certificate path that does not exist
“HTTPS not started”The certificate path is wrong, or the PFX password is. The log says which file it tried
Cannot bind port 443On Linux, reinstall the service so the capability is granted to the right account. On Windows, something else has the port
Task Scheduler shows it running but nothing answersThe process started and exited. Check logs/ for the reason
It works when I run it by hand but not as a serviceAlmost always a path. The service runs from the install directory as a different account, so relative paths and per-user certificate stores behave differently