How Clockwork Control works
Architecture, Modules & Contracts
A unified agency command center with zero per-site rent, modular flexibility, and no unnecessary repositories. Here is exactly how the platform, modules, and client sites connect.
Do modules need their own GitHub repository?
No! Modules live directly inside your Clockwork Control codebase. Clockwork Control uses Composer path repositories. Every built-in module (SpinupWP, Pressable, WP Engine, Kinsta, Cloudways, DigitalOcean, Hetzner, etc.) lives in the modules/ directory of the main repo.
You only ever need a separate GitHub repository if you want to publish a community package on Packagist to share with other agencies. For your own agency's workflow, modules require zero external repos, zero submodules, and zero versioning overhead.
Clockwork Control Modules vs. The WordPress Plugin
In WordPress development, the word "plugin" gets used everywhere. Here is the clean separation between backend control panel modules and the WordPress Companion.
Clockwork Control Modules
PHP packages that run exclusively on your self-hosted Clockwork Control server. They implement contracts to talk to hosting provider APIs, query cloud hypervisors, trigger team chat notifications, and sync billing invoices.
clockwork-control/modules/[ModuleName]/src/The Clockwork Companion (mu-plugin)
A single, lightweight Must-Use WordPress plugin deployed to your clients' WordPress installations. It does not run background cron jobs or poll external APIs. It simply provides cryptographic endpoints for your control panel.
wp-content/mu-plugins/clockwork-companion.phpHow Composer Path Repositories Work
In a traditional micro-package architecture, every module requires its own Git repository, its own GitHub releases, its own tag management, and endless composer update cycles just to test a one-line bugfix.
Clockwork Control solves this with Composer path repositories. All modules are independent packages with their own composer.json, but they sit right in the same folder as your control panel:
{
"repositories": [
{
"type": "path",
"url": "modules/*",
"options": { "symlink": true }
}
],
"require": {
"clockwork/spinupwp": "@dev",
"clockwork/pressable": "@dev",
"clockwork/digitalocean": "@dev",
"clockwork/my-custom-host": "@dev"
}
}Running composer update clockwork/my-custom-host symlinks your module directly into vendor/clockwork/my-custom-host. Any file edit takes effect immediately without refreshing dependencies.
The 4 Contracts Powering Every Module
Every module implements one or more minimal PHP interfaces. Nothing in core app code hardcodes provider names — core code only ever speaks to these four contracts.
HostingProvider
Manages WordPress websites, cert synchronization, WP-CLI execution, Companion deployment, and orphan detection.
CloudProvider
Polls IaaS hypervisors every 5 minutes for CPU, memory, disk I/O, load averages, and server IP reconciliation.
ChatNotifier
Broadcasts downtime transitions, SSL renewal warnings, and automated IP ban actions into agency channels.
SmsNotifier
Dispatches urgent SMS text alerts to on-call engineers when VIP care plan client sites suffer unexpected downtime.
What's inside a Clockwork Control module folder?
A module is remarkably small. Most modules consist of just 3 to 4 PHP files:
Defines the package name (e.g. clockwork/vultr) and registers its PSR-4 namespace.
Declares the module manifest, API credential fields, diagnostic check, and scheduled tasks.
Contains the business logic: queries the API endpoint, maps server specs, or runs commands over SSH.
modules/MyProvider/
├── composer.json # Minimal Composer package metadata
└── src/
├── MyProviderServiceProvider.php # Auto-registers credentials & jobs
├── MyProvider.php # Implements HostingProvider / CloudProvider
└── MyProviderClient.php # Lightweight HTTP / SSH runner clientWhen you add a module, you never edit core Laravel controllers, routes, or database migrations. The module self-declares its credential form fields, and they appear automatically on /settings/integrations.
Build any custom module in ~30 minutes with AI
Because Clockwork Control's module contracts are so small and strictly defined, AI tools (Claude Code, Antigravity, or Cursor) can generate a complete, working module in a single prompt.
"I want to add a new module for [Hosting Or Cloud Provider Name] to Clockwork Control.
1. Look at modules/DigitalOcean/ and modules/Pressable/ as reference implementations.
2. Read modules/Core/src/Contracts/HostingProvider.php (or CloudProvider.php) to see the exact contract methods required.
3. Create a new directory modules/[ProviderName]/ with composer.json, [ProviderName]ServiceProvider, and [ProviderName]Provider.
4. Declare the necessary API token fields in manifest() so they appear on /settings/integrations.
5. Wire the module into root composer.json and write Pest test fixtures."
How updates & versions work
Will modules have their own version numbers, or is it one unified release? Here is the exact lifecycle of how Clockwork Control, bundled modules, and client sites stay up to date.
Clockwork Control & Bundled Modules
For all built-in features (SpinupWP, Pressable, WP Engine, Kinsta, Cloudways, Vultr, Linode, Slack, Twilio), it is one single, unified release.
When you upgrade Clockwork Control (e.g. v1.0 → v1.1), core and all bundled modules update in lockstep. You never suffer dependency mismatches, broken API bridges, or plugin version hell.
git pull or release tag upgrade3rd-Party Community Modules
Community modules published to GitHub or Packagist carry their own independent semantic version numbers (e.g. v1.2.0).
Third-party authors define their own release cadences and specify their minimum Clockwork Core version constraint (e.g. "clockwork/core": "^1.0"). You can upgrade community modules individually via Composer.
The WordPress Companion
The single Must-Use plugin deployed to client WordPress sites is versioned independently (e.g. v1.32.1).
Because it runs on external client servers across different hosting environments, you can roll out Companion updates fleet-wide with one click, run canary deployments against non-critical staging sites first, or roll back safely.
Module Architecture FAQ
Can I keep our agency's custom module private?
Yes! Because modules sit in modules/ inside your private Clockwork Control git repository, your custom code, proprietary API clients, or internal billing integrations never leave your own servers.
Do I need to publish to Packagist?
No. Composer path repositories require zero external registry. Packagist is only relevant if you want to publish an open-source package for other agencies to download.
Can a module implement both Cloud and Hosting contracts?
Yes. modules/Cloudways is the canonical example: it provisions raw compute droplets (so it needs CloudProvider for CPU/RAM metrics) that host multiple WordPress applications (so it implements HostingProvider too).
Can I turn a module off without deleting code?
Yes. Leaving a module's API credentials blank safely disables all of its scheduled polling, diagnostics, and background workers. You can also toggle modules on or off directly in /settings/modules.
Will updating Clockwork Control break our custom modules?
No. Clockwork Control adheres to strict Semantic Versioning. The 4 foundation contracts (HostingProvider, CloudProvider, etc.) remain backwards-compatible across minor and patch releases. Your custom modules in modules/ continue working cleanly across core updates.
How do I update our self-hosted Clockwork Control instance?
Simply run git pull origin main (or checkout the latest release tag) and run composer install --no-dev and php artisan migrate --force. All bundled modules update simultaneously.
Explore the existing module catalog
Inspect the 14+ built-in modules for SpinupWP, Pressable, WP Engine, Kinsta, Cloudways, DigitalOcean, Hetzner, Vultr, Linode, and Azure.
