Overview
How FeatherFly loads and runs plugins.
FeatherFly plugins are native shared libraries (.so files) loaded at daemon startup. They extend the daemon without recompiling FeatherFly itself.
A plugin exports one symbol: featherfly_plugin_entry. The daemon loads each .so, checks the plugin API version, calls init, and keeps the library in memory until shutdown.
Plugins register hooks during init. Hook systems:
- Lifecycle events — callbacks fired at fixed points (config loaded, daemon started, etc.).
- Config mutation — rewrite raw YAML before settings are applied.
- Request hooks — run before HTTP handlers (
request.intercept,middleware.inject). - Plugin routes — register new HTTP endpoints on the daemon router.
- JSON mutation hooks — callbacks that receive JSON, may rewrite it, and return modified output for HTTP responses.
- CloudPanel command hooks — rewrite or cancel CloudPanel CLI operations before
clpctlruns.
All hooks for a given target run in plugin load order (alphabetical by filename in the plugins directory).
Startup sequence
- Daemon reads config.yml (raw bytes)
- Each
.soin the plugins directory is loaded - For each plugin:
init(host)runs — register hooks here (including config.mutate) - After each plugin init:
plugin.loadedevent fires (payload = plugin name) - Registered config.mutate hooks rewrite the YAML pipeline
- Final config is parsed and applied (directories, logging, pid file)
config.loadedfires with the post-mutation YAML bytesdaemon.startingfires before HTTP routes are wired- HTTP server starts (core routes + plugin routes; request middleware stack active)
daemon.startedfires (payload = listen address, e.g.127.0.0.1:9090)- On shutdown:
daemon.stoppingfires, then each plugin'sshutdownruns
Logging
Plugin discovery, per-library load, route registration, and HostApi::log_info output use the plugin tracing target at DEBUG. At INFO you get one consolidated FeatherFly ready line with plugin/hook/route counts. Set logging.level: debug (or run with --debug) to see loader detail in latest.log.
Remote management
FeatherPanel can read/edit config.yml, restart the daemon, and trigger plugin reloads over the HTTP API. See remote config, remote restart, and plugin reload. Toggle capabilities with remote.config_edit and remote.restart in config.
Hook systems
All hooks for a target run in plugin load order (alphabetical by .so filename). Register everything inside init.