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—communitywhen a Community server installs it,enterprisewhen only a licensed server does.components— the namesinstallalready understands, so the registry adds a dimension rather than a second installer.units— whatinstall,uninstallandrepairstart, stop and check.features— the names infeatures.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 underdatais ever removed byuninstall.--purgeremoves 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 (webmailrequiresmail).
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 Community | Enterprise 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 forwarders | the 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:
installnever 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 indata.uninstallandrepairare separate functions, and only an operator naming a module touninstallreaches the code that can remove it.module install --edition enterpriseon a server that already has every Community module leaves every one of them installed, with every byte of theirdatauntouched, whatever else it adds. Proved byupgrading_to_enterprise_leaves_every_already_installed_community_module_installedinnative/module.rs, run against the shippedmodules.jsonitself, 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.- A licence that lapses uninstalls nothing.
license.rs'sa_lapsed_licence_uninstalls_nothingreads the exact command list the delete path runs and fails if it ever contains a removal;module.rs'sa_module_stays_installed_after_its_licence_lapsesproves the companion fact thatis_installednever consults the licence, so a module a server installed while licensed keeps reporting installed after the licence closes its features. - Every path listed in any module's
datasurvives an ordinaryuninstall.every_modules_data_survives_an_ordinary_uninstall_of_everything_removableuninstalls every removable module in the shipped registry at once — the widest a single operator command can reach — and asserts everydatapath is still there afterwards, byte for byte.--purgeis the only door to removingdata, 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
- An uninstall never touches customer data.
- An upgrade never migrates; it installs.
- A module that is not installed reports its features unavailable rather than failing at the moment a customer clicks.
- The registry,
features.jsonand the compiled split are compared by a test. - Every action is one CLI command the panel calls — the panels never install packages themselves.