Skip to main content
View as Markdown

Lifecycle Commands

Four commands run and control a server. stop, restart and reload all find the running process through a lock file the server writes at boot, recording its PID, port and config path — which is why none of them need you to name the config again.

sovrium start

Start the server. This is the default command, so the start word is optional when a config path is present.

>_ terminal
sovrium start app.yaml          # explicit
sovrium app.yaml                # implicit — identical
sovrium start app.yaml --watch  # reload on config change

PORT=8080 sovrium start app.yaml

The port comes from PORT and defaults to 3000. If that port is already taken, Sovrium does not fail — it binds an OS-assigned free port and prints the real URL in the startup banner:

code
[SERVER] Port 3000 in use; using an OS-assigned port (see URL below).

Starting while another instance holds the lock is refused:

code
Error: Server already running (PID: 12345, port: 3000)

A lock left behind by a crashed process is detected (its PID no longer exists) and removed automatically, so this only blocks you when an instance really is running.

sovrium stop

Send SIGTERM to the process named in the lock file, then wait up to 5 seconds for that process to exit. The lock is removed only once the process is really gone — so a lock file that survives a stop is telling you the truth: the server is still up.

>_ terminal
sovrium stop

On success it prints Server stopped. and exits 0.

If the recorded PID no longer exists, the stale lock is cleared and the output says so, instead of claiming a stop that never happened:

code
Server was not running — removed a stale lock file for PID 12345.

A server still alive 5 seconds after SIGTERM exits 1 and keeps the lock:

code
Error: Server (PID 12345) did not exit within 5s after SIGTERM.

Force it with 'kill -9 12345', then run 'sovrium stop' again to clear the lock.

With no lock file at all it also exits 1:

code
Error: No server is running.

Start one with 'sovrium start <config>'.

On SIGTERM — or Ctrl-C in the foreground — the server finishes the requests already in flight, force-closes long-lived connections such as SSE streams, and exits, normally in well under a second. docker stop and systemd therefore complete without falling back to SIGKILL. A second Ctrl-C skips the drain and exits immediately.

sovrium restart

Stop the running server, then relaunch it detached in the background. The config path is optional — without one, the path recorded in the lock file is reused.

>_ terminal
sovrium restart          # same config as the running instance
sovrium restart app.yaml # swap in a different config

Restart waits for the old process exactly as stop does, and refuses to launch a replacement if it is still alive after 5 seconds — you never end up with two servers running side by side. The refusal is the same did not exit within 5s message, and the old server keeps running and keeps its lock.

Restart is a full process replacement: the port is reassigned and connections are dropped. Prefer reload when the only thing that changed is the configuration.

sovrium reload

Re-read the configuration of a running server without downtime. Sovrium validates the file first and only signals the process once it decodes cleanly, so an invalid edit is rejected before it can reach the live server.

>_ terminal
sovrium reload
sovrium reload --message "Add the invoices table"

--message records an operator note against the new configuration version, which then shows up in the app's migration history.

Because configuration is code-only, there is no runtime-edited schema for a reload to conflict with — the file on disk is always the truth. An invalid file stops the reload with:

code
Error: Invalid configuration - <the failing path and reason>

Last updated September 1, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium