2.5 KiB
2.5 KiB
Architecture and Runtime Flow
Overview
- The agent is an async HTTP server (axum) listening on a Unix domain socket and exposes a small JSON API to manage nginx configuration fragments.
- Core lifecycle is implemented in
apps/agent/src/main.rs:- parse CLI args and environment variables
- ensure the socket path and directory exist and have permissive but secure defaults
- bind a
tokio::net::UnixListenerto the socket - create an
NginxService(shared state) and an in-process cronJobScheduler - mount axum routes (
/status,/validate,/validate_and_reload,/write_config) and serve HTTP over the Unix socket
Key components
main.rs— Bootstrapping, argument handling, socket setup and permission handling, scheduler start, and axum server startup.routes.rs— axum handlers for the HTTP API. It deserializes JSON payloads and delegates toNginxServicemethods. Handlers return appropriate HTTP status codes and JSON on error or success.commands/— Implementation of lower-level actions (writing fragment files, runningnginx -t, validating, reloads). Thevalidate.rscommand contains sophisticated behavior to handle permission-limited environments by:- creating wrapper nginx configs that include a single fragment
- trying
nginx -tdirectly, attempting a privileged wrapper viasudoif available, and finally passing a writable PID override via-g pid ...;to avoid permission failures
Concurrency and state
- A single shared
NginxServiceinstance is stored in axumStateand cloned into handlers; it holds the scheduler and the configured nginx config directory path. - The JobScheduler is created with
tokio_cron_scheduler::JobSchedulerand started before serving requests.
Error handling and best-effort behavior
- Socket permission changes, GID changes, and directory creations are best-effort and log warnings on failure rather than failing hard.
- Most command failures are converted into JSON errors with appropriate HTTP status codes so callers can inspect command output.
Integration and packaging
- The agent is intended to run as a companion to the API server in
apps/api. The API calls the agent over the unix socket to write fragments, validate them, and trigger reloads. apps/agent/Dockerfilebuilds a runtime image that includesnginxand theyanpm-agentbinary (the Dockerfile uses s6-overlay to run multiple services). This image is suitable for deployments that prefer nginx and the agent colocated in a single container.