This page documents the initialization sequence of the Certimate application, focusing on how the Go backend integrates with PocketBase to provide a unified identity, database, and API layer. It covers the singleton pattern used for the application instance, the command-line interface, and the lifecycle hooks that wire together the scheduler, workflow engine, and the embedded React UI.
The application entry point is located in main.go. It initializes the PocketBase instance and configures the execution environment. Certimate extends the standard PocketBase distribution by adding custom commands and binding logic to the server's lifecycle events.
Certimate uses a singleton pattern to manage the application state and ensure that only one instance of the PocketBase app is active. This is managed via the internal/app package.
app.GetApp(): Returns the global application instance, cast to *pocketbase.PocketBase in main.go main.go28AppName and AppVersion (currently 0.4.29) are defined here to be used across the system internal/app/app.go3-7Certimate configures PocketBase to provide a streamlined experience:
serve command is missing main.go29-33NewInternalCommand: Provides internal utility functions, including the intercmd/certapply subprocess used for ACME isolation main.go39NewVersionCommand: Prints version, Go runtime, and build metadata main.go40 cmd/version.go13-24NewWinscCommand: Handles Windows service installation and management main.go41migratecmd plugin is registered to handle database schema changes, with auto-migration enabled during development based on the binary path main.go35-37Diagram: Bootstrap Flow "Main Entry to PocketBase Initialization"
Sources: main.go27-94 main.go39-41 internal/app/app.go3-7 cmd/version.go13-24
Certimate heavily utilizes PocketBase's OnServe, OnBootstrap, and OnTerminate hooks to initialize and clean up background services.
When the server starts (via the serve command), the following subsystems are initialized:
apis.Static from the ui.DistDirFS with a high priority (999) and Gzip compression main.go55-63scheduler.Setup(): Starts the cron-based certificate renewal checks main.go66 internal/scheduler/scheduler.go12-28workflow.Setup(): Initializes the workflow dispatcher and processing queues main.go67routes.BindRouter(e.Router) registers custom REST endpoints main.go68 This function wires together the repository layer and service layer for Certificates, Workflows, Statistics, and Notifications internal/rest/routes/routes.go23-42This hook is used to ensure system settings are present upon run. It specifically calls settings.Setup() to initialize application-level configurations after the default bootstrap sequence main.go46-53
To ensure graceful shutdowns, the OnTerminate hook is used:
workflow.Teardown() is called to stop the dispatcher and ensure no orphaned processes are left running, provided the app was successfully bootstrapped main.go78-84Table: Lifecycle Hook Responsibilities
| Hook | Function Called | Responsibility |
|---|---|---|
OnBootstrap | settings.Setup() | Configures system settings and defaults main.go51 |
OnServe | scheduler.Setup() | Starts the cron runner for automated tasks main.go66 |
OnServe | workflow.Setup() | Initializes the WorkflowDispatcher and pending queues main.go67 |
OnServe | routes.BindRouter() | Mounts custom REST handlers (Certificates, Workflows, etc.) main.go68 |
OnTerminate | workflow.Teardown() | Stops active workflow executions and cleans up resources main.go80 |
Sources: main.go45-85 internal/scheduler/scheduler.go12-28 internal/rest/routes/routes.go23-42
For ACME certificate issuance, Certimate uses a multi-process isolation pattern. This prevents potential memory leaks or crashes in the ACME client (lego) from affecting the main application.
The intercmd/certapply command is a dedicated internal command that handles the actual ACME challenge and issuance cmd/intercmd.go20-29
NewInternalCommand and executed as certapply cmd/intercmd.go26-31mproc.NewReceiver to handle IPC. It reads an InData struct containing ACMEAccount and ObtainCertificateRequest cmd/intercmd.go69-80certacme.NewACMEClientWithAccount and calls ObtainCertificate cmd/intercmd.go93-104lego logs to a wrapped JSON handler (hookStdLog) so they can be parsed correctly by the main process cmd/intercmd.go37-62 cmd/intercmd.go91Diagram: Multi-Process Isolation Flow "ACME Isolation via intercmd Subprocess"
Sources: cmd/intercmd.go20-125 cmd/intercmd.go80-112
Certimate includes native support for running as a Windows service via the winsc command group main.go41
NewWinscCommand provides subcommands to manage the service lifecycle (install, uninstall, start, stop) main.go41golang.org/x/sys/windows/svc package to interface with the Service Control Manager.cmd.Serve(pb) function handles the actual startup logic, distinguishing between standard serve and Windows service contexts main.go87-93Sources: main.go39-41 main.go87-93 cmd/winsc_nonwindows.go13-24
Certimate is distributed as a single binary. This is achieved by embedding the compiled React frontend into the Go binary using Go's embed package.
The server binds the root path and sub-paths to the static file server using apis.Static(ui.DistDirFS, false) main.go57-59
ui.DistDirFS: This variable (exported from the ui package) contains the production build of the React application main.go22apis.Gzip() to optimize asset delivery main.go59Diagram: Code Entity Mapping (UI to Backend) "Static Asset Embedding & Serving"
Sources: main.go55-63 main.go22
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.