Skip to main content
Version: 4.1

Editions and modules

Community and Enterprise are the same product. What separates them is what a server installs: Community installs the lean set and leaves the rest of the disk, the RAM and the units untouched, and Enterprise installs the whole stack. Entering a valid licence upgrades a running server in place, without touching a single byte of customer data.

Until now the split was only a display rule — every service was installed on every server and the panel hid the features Community was not entitled to. A Community server therefore paid for Dovecot, Postfix, rspamd, ClamAV, BIND, PostgreSQL, Varnish and the search engines in memory while being unable to use any of them.

The module registry​

One file describes every module: configuration/modules.json. It is the single source of truth for the CLI, both panels and the installer.

{
"name": "mail",
"title": "Email hosting",
"edition": "enterprise",
"components": ["mail", "rspamd", "clamav"],
"units": ["postfix", "dovecot", "rspamd", "opendkim"],
"features": ["emails", "email_aliases", "email_filters", "webmail"],
"data": ["/etc/hitechcloud/mail", "/home/*/mail"],
"ram_mb": 420,
"requires": [],
"removable": true
}
  • edition — community when a Community server installs it, enterprise when only a licensed server does.
  • components — the names install already understands, so the registry adds a dimension rather than a second installer.
  • units — what install, uninstall and repair start, stop and check.
  • features — the names in features.json; a module that is not installed reports its features as unavailable, which is what the panel draws from.
  • data — paths that hold customer data. Nothing under data is ever removed by uninstall. --purge removes them only when the module has no data in use, and it refuses rather than guesses.
  • ram_mb — the resident memory the module's units typically hold, so the admin can see what a removal buys back.
  • requires — modules that must be installed first (webmail requires mail).

The compiled list in internal/core/licence/features.go keeps deciding which features Enterprise unlocks; the registry decides which services exist. A test compares both against features.json so the three cannot drift.

The command​

hitechcloudcli module list [--json]
hitechcloudcli module status <name> [--json]
hitechcloudcli module install <name>... | --edition enterprise
hitechcloudcli module uninstall <name>... [--purge]
hitechcloudcli module repair <name>...

list prints every module with its edition, whether it is installed, whether this server is licensed for it, its units' state and its memory. install is idempotent — a module already installed is re-checked, not reinstalled. uninstall stops and disables the units, removes the packages the module owns alone, leaves every path in data, and says what it left behind. repair re-renders the module's configuration from the templates, re-enables its units and fixes ownership — the "something is wrong, put it back" button for both editions.

Every subcommand answers --json for the panels.

What Community installs​

Installed on CommunityEnterprise only
a WebEngine (nginx, Apache or OpenLiteSpeed), PHP, MariaDB, Redis, cron, the firewall, ACME/SSL, GoAccess, the jail and the resource engine; FTP; the malware scanner and its weekly sweep; email hosting — Postfix, Dovecot, OpenDKIM and rspamd, with Roundcube as the webmail, and aliases and forwardersthe advanced mail features and our own webmail (Sieve filter editors, autoresponders, catch-all, deliverability, spam quarantine, greylisting, blocklist, email disk usage, import/export, DAV); BIND and everything DNS-cluster, DNSSEC and dynamic DNS; PostgreSQL, MongoDB, MSSQL, pgAdmin, Percona; Varnish; OpenSearch/Elasticsearch; LiteSpeed Enterprise; the Node/Python/Ruby/Java runtimes and n8n; the disk-usage and inode explorers; download-from-URL; temporary domains; suspend and capitalize domains; VirtualHost editing; resellers; multiple administrators; account transfer between servers; cPanel import; passkeys; the REST API and MCP; and the billing integrations

Email is the one module that exists in both editions and differs inside. Community gets a working mail server and Roundcube. Enterprise adds our own webmail beside it and the features that go with it — and the upgrade leaves Roundcube installed, because a customer who bookmarked it must keep it.

A Community install is therefore a web server, PHP, a database and the panel — the things a single-site server actually runs.

Entering a licence​

hitechcloudcli license --set <key> validates the key, and when the server becomes Enterprise it runs module install --edition enterprise itself: the modules arrive, their units start, the panel's feature list widens on the next request. Nothing is migrated, because nothing that existed changes — the upgrade only adds.

A licence that lapses does not uninstall anything. The features close, the services keep running, and the operator decides whether to reclaim the memory with module uninstall. Removing services from a running server without being asked is how data goes missing.

The upgrade guarantee​

A Community → Enterprise upgrade must not lose a single byte, and this is not only a rule in this document — the module engine (module, hitechcloudcli/native/module.rs) and the licence command (hitechcloudcli/license.rs) are written so that it cannot be broken by accident, and both carry tests that fail the moment it is:

  1. install never removes anything. Reading the function is the proof — it calls a component's installer, enables and starts units, and writes a marker; there is no code path in it that stops a unit, removes a package or touches a path in data. uninstall and repair are separate functions, and only an operator naming a module to uninstall reaches the code that can remove it.
  2. module install --edition enterprise on a server that already has every Community module leaves every one of them installed, with every byte of their data untouched, whatever else it adds. Proved by upgrading_to_enterprise_leaves_every_already_installed_community_module_installed in native/module.rs, run against the shipped modules.json itself, with every component, unit and package name swapped for a synthetic one so the test exercises the engine's own promises rather than any one installer.
  3. A licence that lapses uninstalls nothing. license.rs's a_lapsed_licence_uninstalls_nothing reads the exact command list the delete path runs and fails if it ever contains a removal; module.rs's a_module_stays_installed_after_its_licence_lapses proves the companion fact that is_installed never consults the licence, so a module a server installed while licensed keeps reporting installed after the licence closes its features.
  4. Every path listed in any module's data survives an ordinary uninstall. every_modules_data_survives_an_ordinary_uninstall_of_everything_removable uninstalls every removable module in the shipped registry at once — the widest a single operator command can reach — and asserts every data path is still there afterwards, byte for byte. --purge is the only door to removing data, and only when the module reports nothing in use.

Webmail specifically: both webmails coexist​

Community installs Postfix, Dovecot, OpenDKIM and rspamd (module mail) and offers Roundcube (module webmail-roundcube) as the webmail. Enterprise adds our own webmail, HiTechCloud Webmail (module webmail), beside it. Upgrading a server that has webmail-roundcube installs webmail without touching Roundcube: Roundcube stays installed, enabled, reachable on its own vhost, with its database and every user's settings exactly as they were — a customer who bookmarked it keeps it working. Both modules carry the webmail feature, and a feature is available when any module carrying it is installed, so a Community server offers webmail through Roundcube alone and a licensed server offers it through both.

The two webmails are not two mail servers: webmail-roundcube and webmail both require: ["mail"] rather than bundling their own Postfix/Dovecot, so they read the same mailboxes by construction. Neither module's data overlaps the other's, and neither owns a units entry the other also owns, so an uninstall of one can never stop or remove the other — webmail_and_roundcube_cannot_collide_on_units_or_data in native/module.rs holds the registry to this. Dovecot's shared configuration (the drop-in that turns off system authentication in favour of the virtual mailbox database) is written by mail's own install, before either webmail is added, and again by every update in the configuration language of the Dovecot installed (2.3 or 2.4) — neither webmail's installer rewrites it, and neither may start claiming a vhost port the other already serves on.

webmail-roundcube has no components yet — its installer (native/roundcube.rs) is still to be written. Until it exists, module correctly reports it pending rather than claiming an installation that did not happen, and the tests above skip the Roundcube-specific assertions with an explicit message rather than passing vacuously; they start asserting on it the moment it has a component to install.

The pages​

  • Admin (2087) gets Modules & Services: every module with its state, memory, units and the three actions, plus what a removal would free. This is the page an operator uses to trim a server.
  • User (2083) shows the services an account can see on Community only. On Enterprise the services belong to the administrator, and the account's panel does not offer them.

Rules this design keeps​

  1. An uninstall never touches customer data.
  2. An upgrade never migrates; it installs.
  3. A module that is not installed reports its features unavailable rather than failing at the moment a customer clicks.
  4. The registry, features.json and the compiled split are compared by a test.
  5. Every action is one CLI command the panel calls — the panels never install packages themselves.
Was this helpful?