cPanel / aaPanel deployment
DynoStatic has one runtime layout: the complete managed release lives directly in the installation root or subfolder. Fresh installs may use direct extraction or a reviewed Softaculous package. Stable upgrades use either DynoStatic's signed protected inbox/manual-overlay workflow or the recorded Softaculous provider; there is no private release tree, active pointer, public HTTP activation endpoint, scheduled updater, or unsigned in-place FTP upgrade.
Runtime requirements
- PHP 8.4 or newer
- MySQL 8.0+ or MariaDB 10.6+
- PDO MySQL, cURL, DOM, Fileinfo, JSON, mbstring, Sodium, XMLReader, and ZIP
- HTTPS for the installation and production embedding origins
- PHP write access to the application directory during setup and to
dynostatic-content/afterward - outbound HTTPS only for enabled remote features
Node, npm, Playwright, Python, Composer, Git, and shell access are not customer-host runtime requirements. They are used on development/release workstations and in GitHub Actions. The uploaded archive already contains optimized production Composer dependencies.
Direct extraction
- Create an empty MySQL/MariaDB database and database user.
- Choose an empty web directory. Do not point the domain at a nested
public/directory. - Extract the single top-level
dynostatic-<version>/directory's contents into that web directory. - Use the hosting panel's ordinary PHP handler. No rewrite rule, alternate document root, or Nginx location rule is required. The shipped
.htaccessanddeploy/nginx.conf.exampleare optional defense in depth when the host supports them. - Visit
/install/(or the corresponding subfolder path).
Before showing the owner form, DynoStatic writes a random executable PHP guard container below dynostatic-content/ and requests it plus the guarded configuration through the detected public URL. Setup is refused unless the guards return 403, 404, or 410. This verifies that the site executes PHP without requiring Nginx to interpret .htaccess.
Setup then creates dynostatic-content/setup-authorization.php with mode 0600. Open it through File Manager, FTP, or SSH and copy its one-time token into the installer. The token is absent from HTTP output and logs, is rate-limited before database access, and is deleted only after the owner and first website commit successfully.
After installation, dynostatic-config.php must be mode 0640 or stricter. Confirm that /dynostatic-config.php and guarded files below dynostatic-content/ return an empty 403/404/410. PHP source and dependency files contain distributable application code rather than instance secrets; optional Apache/Nginx rules can deny those paths as defense in depth.
Subfolder installs are first-class. If extracted at https://tools.example.com/widgets, generated asset, administration, API, and installation links stay below /widgets.
Signed updates and recovery
DynoStatic does not download releases or contact an update server. Obtain the exact signed stable carrier through the release channel, then upload that single guarded PHP carrier with File Manager or FTP to dynostatic-content/updates/inbox/. Do not rename it after discovery and do not extract it yourself.
Under Tools → Updates, the owner can advance inspection/staging one bounded request at a time, review the dry run, and explicitly initialize Apply. Apply does not replace code in the same request. Continue the active operation until it reports completion; closing the browser does not cancel it. The equivalent PHP-only commands are:
php bin/dynostatic update:status
php bin/dynostatic update:candidates
php bin/dynostatic update:inspect CANDIDATE_ID
php bin/dynostatic update:dry-run CANDIDATE_ID
php bin/dynostatic update:apply CANDIDATE_ID --yes
php bin/dynostatic update:resume
The updater authenticates the carrier and exact installed source, stages a separate content-addressed tree, drains requests, establishes maintenance, creates and independently verifies a protected encrypted BK2 backup, switches only managed files, and then runs the registered configuration/schema/data/health authorities in freshly bootstrapped target code. Instance data, configuration, .user.ini, .well-known, unknown files, and other host-owned paths are not target payload. Code rollback is available only before migration begins; after that boundary, recovery is forward-only unless the operator deliberately restores the full verified BK2 backup.
If the host will not permit the guarded direct replacement, initialize Manual overlay for the inspected candidate. DynoStatic creates a server-selected filtered copy tree plus an exact deletion list. Copy only those instructed files with File Manager/FTP, delete only the listed retired managed paths, then use the same screen (or the update:manual-overlay:* CLI commands) to reconcile from freshly loaded target code. Partial copies, stale instructions, extra managed bytes, and skipped deletions are rejected.
The compiled production catalog contains the owner-selected dynostatic-20261012 public signing key. Its private key is kept outside the runtime and release archive. A checkout or unsigned archive cannot be treated as an applicable update. The first supported upgrade source is the reviewed stable updater-capable baseline; disposable development installations require a fresh installation.
Softaculous ownership
A DynoStatic Softaculous package contains the documented metadata/hooks plus a direct-extraction dynostatic.zip. Fresh provider setup requests the database, panel URL/path, owner, and first-website facts, then calls the same installation service as /install/. It does not import a separate SQL file or maintain a second schema implementation.
Softaculous initially owns updates for a Softaculous installation. Its upgrade copies the package's managed runtime while preserving dynostatic-config.php, dynostatic-content/, .user.ini, .well-known, and panel scaffolding. The guarded target gateway then proves the provider archive, signed root carrier, complete live target runtime, exact supported source, provider manager custody, and request quiescence before running DynoStatic's existing configuration/schema/data/health authorities under maintenance. A failed hook remains a provider failure; use Softaculous's own backup/rollback result together with DynoStatic's displayed recovery message rather than mixing update methods.
The installation owner may take update management over under Tools → Updates with exact confirmation and the current password. That enables the signed inbox and makes later Softaculous hooks fail before DynoStatic mutation. Returning management to the recorded Softaculous provider again requires the current password plus explicit reconciliation confirmation; neither screen accepts a caller-selected provider key.
OPcache recovery requires access to opcache_get_status(), opcache_invalidate() and opcache_reset(), with opcache.file_cache disabled. Recovery invalidates cached scripts before loading target Composer code, then requests a cache reset. A reset alone takes effect too late for the current request. Unsupported cache settings stop recovery before target code loads; ask the host to enable the required APIs and disable the file cache before resuming. PHP/hosting permission, quota, interruption, and supported MySQL/MariaDB combinations receive their exhaustive matrix at the first stable updater-capable baseline; the development tree does not claim that release matrix early.
The shipped php bin/dynostatic-update entry point accepts the same update:*
commands as bin/dynostatic. Use this dedicated recovery entry point when
resuming an interrupted update; it belongs to the byte-identical recovery ABI.
Cache and Redis password
Filesystem caching is enabled by default. APCu, Redis, and Memcached are optional accelerators with automatic filesystem fallback. Copy the cache section from dynostatic-config-sample.php into the private configuration and select a driver. Redis accepts host, port, database, username, password, timeout, and tls; credentials are never returned by diagnostics.
The cache key includes widget publication revision, content version, and discussion page key. Comment, poll, reaction, and counter mutations advance content versions. Atomic filesystem writes, stale-while-refresh, and single-flight regeneration remain available without Redis.
Capabilities and activation
These workflows have recorded local acceptance. Final-source release certification and qualification of the distributed archive remain separate; a configured feature does not activate an external provider automatically.
| Capability | Setup and operating boundary |
|---|---|
| Widgets, CMS and website publishing | Register the website and its allowed addresses, configure content and explicitly publish it. Native static releases and offline/Astro projects use the same publication authority. |
| Contributor publishing and commerce | Configure the website's submission workflow, access, review rule, offer and payment connection. Accounts, management links/codes, teams, reviewed listing claims, posting credits, renewals, subscriptions and featured benefits are supported. Payment, ownership, editorial approval and publication are separate decisions. |
| Analytics, privacy and site information | Choose the website's privacy/analytics policy and business information. Privacy & Legal documents and workflows require explicit activation and review. Software support does not certify legal compliance. |
| Agent management | Create explicit website/actor grants for permitted Automation/MCP actions. A read or proposal grant does not authorize payment, publication or deployment. |
| AI search, assistance and drafting | Enable the selected website capabilities, configure and approve a provider account and current corpus, choose funding and allowance, then build the search index. Answers cite retrieved publications; generated CMS drafts require human review before publication. |
| Agent purchases | Configure eligible offers and a payment provider. Human-approved checkout and bounded owner-issued delegation share the existing orders and receipts. UCP/ACP manual checkout and the default-off AP2 closed merchant profile require the corresponding configuration; external partner onboarding remains separate. |
| Cloudflare management | Connect the owner's Cloudflare account and zone, review the configuration preview, and apply only the explicitly managed rules. Check drift before changes or rollback. Origin diagnostics cannot certify the live edge configuration. |
| Paid agent access | Configure and activate an eligible tariff as described below. Access entitlements remain distinct from purchases, posting credits and AI service credits. |
For AI setup, website settings select capabilities; the provider page contains OpenAI account and corpus approval, AI funding choice and AI search workflow. Saving a key or setting makes no provider call. Compatible endpoint probes send fixed test text and may incur cost. A current website owner must deliberately choose the provider/funding authority before funded use.
Choose either a UTC calendar-month allowance or a non-resetting allowance. Check the displayed payer, allowance, usage, reset date or lack of reset, and exhaustion state. Monthly resets do not replenish purchased credits. AI service credits (/admin/ai-credits?site=<website-id>) configures prepaid credit terms; opt-in metering uses /admin/ai-metering?site=<website-id> and requires verified provider state. Prices and financial limits have no automatic defaults. Exhaustion stops use until an authorized change or the configured reset; it cannot silently switch funding or increase spending. Technical request/token ceilings are advanced limits, and token counts are not exact monetary spending caps.
See integration, CMS, Automation, Cloudflare and security for the related setup boundaries.
Optional paid agent access
Paid access starts disabled. A website owner uses Paid agent access (/admin/ai-access?site=<website-id>) to save an inactive tariff with an exact amount, asset, recipient, access duration and one payment method, then reviews its eligibility and activates it. MPP supports the pinned Stripe charge method and requires an already configured Stripe connection and selected test/live mode. x402 supports the v2 exact EVM method and requires an explicitly trusted HTTPS facilitator, CAIP-2 network, token and recipient configuration. Local fixture acceptance does not activate a live processor or wallet.
CMS pricing is limited to eligible unpublished Markdown collection drafts with no prior public exposure. An active paid entry blocks new static releases/exports and CMS token creation for that website; turning it off revokes bearers and a published entry cannot be priced again. Paid public search also requires ready, funded AI3 search, while paid read tools retain their exact AI2 connection grants. Owners can turn a tariff off from the same page. Verify the installation's trusted HTTPS address and payment provider configuration before enabling a live tariff.
Release construction
deploy/release.sh is the source-checkout stable/candidate orchestrator. After the clean final source completes a resumable composer verify:release campaign, pass its ID as --verification=<campaign-id>. The wrapper certifies that every required check has a current passing receipt, including the supported-environment bundle, before it invokes the low-level builder. Dry-run and labelled test builds follow their separate non-deployable paths. The wrapper, builder, Composer, tests, Node, and browsers are development/release-runner tools and are deliberately absent from the customer archive.
bin/build-release.sh reads release/runtime-files.txt, a bytewise-sorted list of literal runtime source files. It does not discover files using “all tracked except …” rules. It installs locked production dependencies without platform-requirement bypasses, reads the canonical schema identity from staged application code, writes release-metadata.json, then hashes every final regular payload file into release-manifest.sha256.
For a fresh development installation, --candidate --zip also accepts a -dev.N version such as 0.7.0-dev.2, retaining the clean-source and production-dependency requirements. Other candidate archives require -rc.N; stable archives require a plain version.
The separate bin/build-softaculous-package.php build tool consumes one already signed stable carrier plus its public verification key and explicit version/build-time/support metadata. It emits one deterministic no-clobber vendor ZIP; signing keys, fixtures, Composer development dependencies, Node artifacts, and package outputs are never runtime files. This command is release-workstation tooling and is not needed on customer hosting.
Test builds are conspicuously named TEST-NOT-DEPLOYABLE and carry build_mode=test; the FTP client rejects them. Candidate/stable builds require an exact clean Git HEAD and the corresponding SemVer form. There is no test-skip environment variable.
Fresh-target FTP helper
The FTP helper is optional workstation tooling. It accepts only a locally extracted, deployable candidate/stable archive that matches the exact checkout running the helper. It validates metadata, every manifest entry/hash, the complete local file set, version, commit, and canonical schema identity before connecting.
tar -xzf dynostatic-0.6.0-rc.2.tar.gz -C /tmp
export DYNOSTATIC_FTP_HOST=ftp.example.com
export DYNOSTATIC_FTP_PORT=21
export DYNOSTATIC_FTP_USER=deploy
export DYNOSTATIC_FTP_PASSWORD='…'
# Optional workstation/client settings:
export DYNOSTATIC_FTP_TLS=1
export DYNOSTATIC_FTP_DIRECTORY=path-below-login-root
./deploy/staging-deploy.sh --dry-run /tmp/dynostatic-0.6.0-rc.2
./deploy/staging-deploy.sh /tmp/dynostatic-0.6.0-rc.2
Dry-run validates locally and never opens FTP. A real run requires MLSD so the entire remote target can be inventoried safely. The target may contain only server scaffolding .well-known/, .ftpquota, or .user.ini; anything else causes refusal before the first upload. A pre-existing .user.ini is preserved because panels often own it.
Files upload through unique temporary siblings and atomic rename. Ordinary payload goes first, metadata/bootstrap controls next, protection rules next, and public PHP gateways last. The helper never deletes or replaces an existing application. It re-downloads every uploaded file to verify SHA-256 and requires the final remote set to equal the manifest plus allowed scaffolding. On interruption it reports the exact owned temporary name for manual inspection; it performs no glob cleanup.
Python 3 is required only on the workstation running this optional helper. Without Python, extract/upload the verified archive through the hosting panel or another FTP client to a fresh directory.
After upload
- Verify the guarded-PHP preflight passes; optional Apache/Nginx deny rules may be added later as defense in depth.
- Complete
/install/with the empty database. - Open
health.phpand confirmok: true. - Sign in, register the exact production/staging origins, create and publish a Button widget, and confirm it renders from an allowed origin but not an unregistered one.
- Publish a Contact Form, submit it once, and confirm the encrypted record appears in the administration inbox.
- Configure optional cron as
php /absolute/path/to/dynostatic/bin/dynostatic cron. Without cron, the bounded opportunistic web runner still processes work.
Do not extract an ordinary fresh-install archive over an existing instance. Use the signed protected-inbox/manual-overlay path or the installation's recorded Softaculous manager. Retain the exact signed carrier, provider result, and verified BK2 backup until the updated installation is healthy.
Signing the first stable fresh-install archive
Stable packaging now requires an authenticated baseline even for browser setup. Th