Self-hosting

Install PHP Ledger on shared hosting or cPanel

A compatible shared-hosting account needs more than a PHP selector. Verify its database, shell access, file boundary and recovery process.

What should you ask the provider first?

Ask about the exact account’s controls, because panel software availability does not establish plan compatibility.

Before buying or changing a hosting plan, send a short requirement list: PHP 8.3 for both web and command-line use; the package extensions; MySQL 8.4 with InnoDB; permission to create tables, triggers and views; a document root ending in www/phpledger/public; and a private writable session directory. Ask whether terminal or SSH access is enabled for your account. A salesperson saying PHP applications are supported has not answered those questions.

Keep the provider’s response with the installation record. If a control needs administrator help, establish who performs that change and how long it normally takes. For example, a customer may select only PHP versions already installed by the server administrator. The panel product supporting a version does not mean your plan exposes it. A separate database service may also differ from the software running on the web server.

How do cPanel and Plesk differ from a complete hosting promise?

Both panels expose server controls, but the operator decides which versions and permissions your account receives.

Questions to resolve in the actual hosting account
ControlcPanel route to investigatePlesk route to investigate
Web PHPDomain PHP selection and installed EasyApache packagesDomain PHP settings and installed handlers
CLI PHPTerminal access and the chosen executableSSH access and the chosen executable
DatabaseServer version and user privilegesServer version and user privileges
Public rootDomain/subdomain document-root settingDomain hosting document-root setting
RecoveryBackup contents, retention and restoration accessBackup contents, retention and restoration access

The official documentation reviewed on 16 September 2026 describes panel capabilities, not a completed installation on every host. Use the dated availability table for the original research and its limits. This guide does not endorse a provider or claim that a plan bearing either panel brand has passed PHP Ledger acceptance.

Step 1: keep the release outside the public directory

Unpack the verified package into a private application directory, then point the domain only at its public subdirectory.

Download the release ZIP and its checksum from the download page. Use the packaged archive with dependencies, not a repository source snapshot that lacks vendor files. Verify the checksum before unpacking. Create a new directory rather than overwriting an older installation, and retain the earlier package for recovery. A directory such as /home/account/apps/phpledger-0.4.0-preview is illustrative; use the actual private path supported by your host.

Set the domain’s document root to that directory’s www/phpledger/public. If the panel only allows a fixed root, ask the host for an approved configuration rather than moving internal files into public and hoping deny rules cover them. Changing the package layout can break resource paths. Confirm that includes, install, tools and vendor cannot be fetched directly, while public CSS, fonts and the front controller remain reachable.

Step 2: select and verify the runtime

Select a supported web handler and use its matching command-line binary for installation.

php -v
php -m
php www/phpledger/install/preflight.php

Run these commands from the package root after configuring the database. If bare php resolves to an older version, ask the provider for the correct executable path and substitute that path consistently. Do not guess a cPanel or Plesk filesystem path from another server. The host may install multiple handlers, use a different operating system or restrict shell commands. Record the verified binary and avoid depending on a default that can change without notice.

Compare the CLI output with the PHP handler configured for the domain. Sessions, extensions and limits can differ between them. A successful CLI migration followed by a web fatal error often points to that mismatch. Investigate the actual error privately; do not publish a full configuration dump or disable the package’s platform checks to make the error disappear.

Step 3: provision the database and private settings

Use a dedicated database and account, and verify view/trigger rights before applying the schema.

Create an empty application database on the supported MySQL server. Assign a dedicated account rather than reusing credentials shared with unrelated websites. Installation requires schema-changing privileges scoped to this database. A host may withhold those privileges on low-cost plans; if so, arrange an operator-assisted installation or select another plan. Do not change the migration statements to fit a restricted account. Their checks and triggers protect posted history.

Copy the package’s config.local.example.php to config.local.php inside includes and edit the private copy. Supply the actual host, port, database, user and unique nonempty password. Configuration values in that file override environment values, so an old file can silently target an unintended database. Check the effective destination privately. Restrict file access to the operator and PHP process; neither configuration nor OAuth keys belong in the public directory.

Which environment should the hosted installation use?

Set PL_ENV=production for both web and CLI PHP, and leave hosted-demo mode disabled.

Apply the environment through the server or hosting provider’s private configuration mechanism. Do not copy development credentials or the public demo’s reset scheduler into customer hosting. Confirm the effective setting before running installation commands. The optional read integrations need their separately documented public URL and private OAuth-key setup; ordinary browser installation does not configure those automatically.

Step 4: install with explicit success checks

Run each setup command only after the preceding command succeeds, then create the initial user through private input.

php www/phpledger/install/preflight.php
php www/phpledger/install/migrate.php
php www/phpledger/install/preflight.php

The first check should identify a recognized empty or pending schema. The migration command applies the supplied chain. The final check should report current schema. Stop on a nonzero status, unknown receipt, checksum mismatch or interrupted migration. Repeating a normal successful installation skips matching receipts; deleting a failed receipt is not a supported recovery procedure. Keep the command outcome and package identity without recording secrets.

Create the initial owner using the package’s stdin password procedure. Do not place a password in a command argument, support ticket or screenshot. Creating the sign-in account and configuring a company are separate steps. For a fresh fictional company, select dates and functional currency deliberately. Existing businesses require the opening-balance process; do not label an established business as new merely to get past a readiness gate.

Step 5: verify the restricted runtime and recovery

Test normal use after privileges are restricted and preserve the account that defines the effective-source views.

The two source views added in 0.3.0 use the account that ran migration 016 as their definer. A provider who removes a temporary installer account can leave those views unable to execute. Agree on a stable dedicated migration account and verify view reads using the actual web account. The same issue matters when a backup is restored under a different database name. Test the restored view definitions, dependencies and results, not just the presence of their names.

Sign in over HTTPS, record synthetic receipt and expense entries, follow their journals and compare the trial balance. Check session retention, direct navigation and unavailable private paths. Then rehearse a database/configuration/application restore separately. A panel’s backup-completed label does not establish that its archive includes triggers, views and a compatible package, or that the person on call can restore them.

When is shared hosting the wrong choice?

Choose a managed VPS or another service if required database, terminal or recovery controls are unavailable.

What should you do next?

Shared hosting can be a sensible operational arrangement when the provider supplies the required controls and you understand the restrictions. It is a poor fit when support cannot identify the database version, explain restore behavior or permit the public-root boundary. It is also the wrong application choice when you need working invoice/bill screens, inventory or a regional filing connector immediately. Those gaps are independent of the hosting platform.

Questions before you continue

Check these boundaries before applying the procedure to a business installation.

Can I upload everything into public_html?

Only if the configured document root still exposes solely www/phpledger/public. Do not publish the complete package tree.

What if my hosting plan has no terminal?

Ask whether the host provides operator-assisted CLI installation. The package does not supply a browser-based schema installer.

Sources and next steps

Technical references and project behavior were checked on 16 September 2026; hosting access remains plan-specific.

The linked project files describe the current preview. Follow the instructions inside your exact downloaded package if a later release changes a command. Technical testing does not establish statutory compliance or independent accounting acceptance. See the project and preview limits.

Product screen

Development preview with synthetic sample data

Scroll the image to explore it. With a keyboard, focus the image area and use the arrow keys.