Skip to content

Starting and driving automathd

automathd starts the HTTP daemon, which listens on the port defined in automathd.yaml (default: 9998).

Requests are rate-limited per client IP (a sliding window, bucketed by endpoint family and configurable under rate_limit in automathd.yaml); exceeding a bucket is rejected with 429 Too Many Requests. The client IP is taken from the reverse proxy — see the HTTP API for the X-Real-IP requirement behind nginx.

On Linux

automathd understands a small set of lifecycle subcommands. Running automathd with no subcommand is equivalent to automathd start.

automathd start     # start the daemon (default; same as `automathd`)
automathd stop      # stop the running daemon
automathd restart   # stop then start
automathd status    # report whether the daemon is running (and its host:port)
automathd reload    # reload in place, preserving the listening socket

By default start detaches and runs as a background daemon, writing its PID to /var/run/automathd.pid (as root) or ~/.local/run/automathd.pid otherwise. Add --foreground to keep it attached to the terminal.

reload sends SIGHUP: the daemon re-execs itself (same PID, same listening socket), so configuration and code changes are picked up without dropping in-flight connections.

When running, status also prints the host:port the instance is configured to listen on (read from the instance-aware config), e.g. automathd is running (pid 8187, listening on 127.0.0.1:9998). — handy for connectivity debugging.

Exit codes. status returns 0 (running), 1 (stale pidfile) or 3 (not running); stop and reload return 1 when there is nothing to act on. When a systemd-supervised instance is detected, the commands point you to the matching systemctl invocation instead.

Named instances

--instance NAME runs a second, independent daemon alongside the default one — useful to serve more than one deployment from the same machine. It is a global flag: pass it to every command that should act on that instance (automathd --instance other_app start, … status, … stop, … reload, etc.), since each command resolves the instance from its own argument.

A named instance namespaces three things so the two never collide:

  • the pidfileautomathd-NAME.pid (instead of automathd.pid);
  • the log directory<log_dir>-NAME (e.g. /var/log/automathd-other_app);
  • the configuration, via an extra overlay file automathd.NAME.yaml (looked up in /etc/automathics/ then ~/.config/automathics/), layered on top of the shared automathd.yaml. This overlay is where a named instance sets its own port — otherwise both instances would try to bind the same one.

NAME may contain only letters, digits, - and _. The default (unnamed) instance keeps the paths described above.

Named instances are driven through the automathd CLI shown above. The bundled service supervision targets the default instance only — both the FreeBSD rc.d script and a systemd unit are bound to automathd without --instance. To supervise a named instance, invoke automathd --instance NAME … directly, or install a second, adapted service definition.

Socket activation (inetd / systemd)

Under a socket-activation supervisor, start the daemon with --inetd: the listening socket is handed over on file descriptor 0 (BSD inetd wait mode convention) rather than bound by the daemon itself. --inetd implies foreground (the supervisor owns the process lifecycle).

This pairs with idle_timeout_s in automathd.yaml (0/null = always-on): set it to e.g. 900 and the daemon exits after that many seconds without a request, freeing memory until the supervisor re-spawns it on the next connection.

On FreeBSD

The rc.d script is installed automatically during post-install (when run as root). Standard service commands apply:

service automathd start
service automathd stop
service automathd restart
service automathd status
service automathd reload   # SIGHUP — in-place reload, keeps the socket

reload sends SIGHUP (declared via extra_commands in the rc.d script); restart is the usual stop-then-start provided by rc.subr.

How rc.subr finds the daemon

service automathd stop/reload locate the running daemon through rc.subr, which matches argv[0] against $command_interpreter and the $command path within argv. So on FreeBSD the daemon deliberately keeps its native <python> <script> argv across a SIGHUP re-exec (it does not rename itself with setproctitle, which would overwrite argv and make the reloaded process invisible to service … reload/stop). One consequence: pgrep automathd matches by executable name and won't find it — use pgrep -f automathd (full-argv match) instead.