Unattended installs, winget and Chocolatey, and configuration from the environment
-
Written for 6.3.4. hMailServer 6.3.6 (6 October 2026) publishes the first container image,
registry.gitlab.com/hmailserver/hmailserver:6.3.6; its installer exits 10 or 11 when a step after its files did not complete (it exited 0), and it makes the data, log, temp, database and event folders private to the administrators and the service. See the 6.3.6 announcement. hMailServer 6.3.7 (17 October 2026), a security release, publishesregistry.gitlab.com/hmailserver/hmailserver:6.3.7(also tagged6.3andlatest); its Windows installers carry the .NET Desktop Runtime 10.0.13, installed only where no .NET 10 Desktop Runtime is installed at all, so an upgraded server keeps the one it had; at every installation and upgrade/ProtectFoldershardens the program folder,BinandControlPanel, since an installation in a folder that took its permissions from the root of a drive let any account that could sign in to the computer replace the programs (CVE-2026-107571): before upgrading one, followServiceAccount.md's steps, and where other accounts could sign in while it was so installed, reinstall into a new folder only the administrators may change, given to setup with/DIR=, since over an installation setup installs into the folder it finds; and setup waitsShutdownDrainSecondsplus 90 seconds for the service's stop, where it waited plus 30. Chocolatey and the apt and dnf repositories still publish nothing: no channel is live as 6.3.7 is made, and 6.3.7 is not on the Snap Store. See the 6.3.7 announcement. hMailServer 6.3.8 (2 November 2026), a security release, publishesregistry.gitlab.com/hmailserver/hmailserver:6.3.8, now the image tagged6.3andlatest, which reaches a MariaDB database, where the images of 6.3.7 and earlier carried PostgreSQL's client alone, and whose entrypoint takes the database and administrator passwords out of the environment before it runs any program; and its Helm chart starts a server, where the charts of 6.3.6 and 6.3.7 never started a pod. Its Windows setup ends with exit code 7 where another account than SYSTEM, the Administrators and TrustedInstaller controls the program folder,BinorControlPanel, or a folder or a link on the way to them, naming theicaclsthat deals with it; with exit code 12, and the service set not to start until setup runs again, where something is not as setup left it after the files; and with exit code 1 for an installation of the original hMailServer's 5.7, the reason in its/LOGand inhMailServer-setup-refused.txtin%TEMP%. Chocolatey's install now passes the installer/LOG, and that log records setup's command line, so give the administrator password inHM_ADMIN_PASSWORD, set in the elevated prompt, rather than with/adminpasswordin--install-arguments. Once 6.3.8 is published, jobs started by hand send it to the Ubuntu PPA (add-apt-repository ppa:hmailserver/hmailserver), Fedora Copr (dnf copr enable progressiverobot/hmailserver), Docker Hub, Chocolatey (hmailserver-progressiverobot, listed once its moderators approve it), PyPI and the PowerShell Gallery; the signed apt and dnf repositories this topic describes are still not published (Channels.md). See the 6.3.8 announcement.This topic covers installing hMailServer 6.3.4 without a wizard: the Windows installer's silent switches and what a silent install does with the administrator password; where the
wingetand Chocolatey packages stand; the signed apt and dnf repositories and why they are not live; and, since 6.3.4, every setting from the environment and the four setting profiles, the two ways a deployment shapes a server before it starts. The one thing to know first: an unattended install leaves the administrator password unset unless you pass it, and 6.3.4 is installed by hand from the release page, because neither package manager carries it and no live update installs it (the 6.3.4 announcement).The Windows installer's switches
The installer is Inno Setup, so it takes the standard switches and a few of its own.
Switch Effect /SILENTNo wizard; progress window only /VERYSILENTNo wizard and no progress window /SUPPRESSMSGBOXESSuppress message boxes; some failure paths still raise one without it /LOG="<path>"Write an install log; it is the only record of what happened /DIR="<path>"Installation directory /COMPONENTS="server,admintools,controlpanel"serveris the service;admintoolsregisters the COM type library;controlpanelinstalls the Control Panel, which does not needadmintools/adminpassword=<password>Custom: sets the administrator password (at least 5 characters) and hands it to the database tools /upgradetoken=<hex>Custom: the single-use token of a live update; not for people to type /useinternaldbms=true\|falseCustom: true(the default) uses the bundled SQL Server Compact database/serviceaccount=virtual\|localsystem\|keepCustom: virtualisNT SERVICE\hMailServer, the default for a new installation;keepis the default for an upgrade/profile=NAMECustom, since 6.3.4: the setting profile a new installation applies, or none. Written and read, and not run (below)hMailServer-x.y.z-x64.exe /VERYSILENT /SUPPRESSMSGBOXES /LOG="C:\Temp\hmail-install.log" ^ /COMPONENTS="server,controlpanel" /useinternaldbms=trueTreat a non-zero exit code as a failed install and read the log. The installer checks both that the database tool launched and its exit code, so a failed or cancelled schema step fails the install rather than passing silently. The log has the tool's code: from
DBSetupQuick.exe, 0 is a database created or already up to date, 1 a failed create or aDBUpdater.exethat would not start, 3 a wrong or missing administrator password, and any otherDBUpdater.exe's own code. Ahm_dbversionstill on the old value afterwards is the same failure. A silent installation does not approve folders or key files the configuration names outside the program folder, and leaves such a service on LocalSystem rather than moving it to the virtual account.The administrator password, silently
- A fresh silent install leaves the administrator password unset unless you pass
/adminpassword=<password>or setHM_ADMIN_PASSWORD: without either, theAdministratorPasswordkey is left out ofhMailServer.inientirely. - Set it afterwards with
hMailServer.exe --set-admin-password, new in 6.3.4, from an elevated prompt, then restart the service. It takes the password fromHM_ADMIN_PASSWORDor, when that is not set, from one line of standard input when that is a pipe or a file, and never from an argument. Prefer the variable: a pipe from Windows PowerShell 5.1 turns every non-ASCII character into?, storing a password nobody typed. On Linux the command ishmailserver --set-admin-password. ServiceAccount.md and Upgrading.md write the Windows step ashMailServer.exe /SetAdministratorPassword. - The Control Panel and COM are refused under the virtual account. A new 6.3.4 installation runs the service as
NT SERVICE\hMailServerby default, and under that accounthMailServer.iniis read-only to the service: the Control Panel's Administrator password card and COM'sSettings.SetAdministratorPasswordare each refused with a sentence. They set the password only where the service may write the file, as it may under LocalSystem, which an upgrade keeps unless it is answered otherwise. - A silent upgrade of an installation that has a password still needs it for the database upgrade, and cannot prompt. Without it the database upgrade fails and the installer reports a non-zero exit code rather than waiting. With the password empty, a silent upgrade works.
- Since 6.3.4,
HM_ADMIN_PASSWORDis the safer of the two. Inno Setup drops every double quote from its command line, so/adminpassword=ab"cdsetsabcd, and anybody listing processes while setup runs can read the switch. The variable takes any character. Setup reads it only when neither/adminpassword=nor/upgradetoken=is given. - Set the variable in an elevated prompt. Setup started without administrator rights elevates itself through the UAC prompt, and the variable does not cross it.
Until 6.3.4 the password went unquoted on the database tools' command lines, so one with a space, a double quote or backslashes before one failed the database step with exit code 3. It now goes in
HM_ADMIN_PASSWORD.winget and Chocolatey: not in the public repositories yet
The manifests exist and are validated for each release, from the release's own Authenticode-signed installer. They are not in the public repositories: neither
winget install ProgressiveRobot.hMailServernorchoco install hmailserverinstalls this fork until a first submission has been reviewed and merged.Do not run
choco install hmailserverexpecting this fork. PackageManagers.md records none on 15 September 2026, but on 27 September 2026 the community feed held an unlistedhmailserverpackage: the original project's 5.6.8, not this fork's.What the packages are built to do, once accepted:
- Both run the signed installer the release page offers with
/VERYSILENT /SUPPRESSMSGBOXES /NORESTART./SUPPRESSMSGBOXESis not optional: without it a database-setup failure shows a message box, silent mode answers it with the default button, and a broken install reports success. /TYPE=fullis deliberately not passed, so an upgrade keeps the components already installed and does not put the Control Panel back on a server where it was left out.MinimumOSVersion: 10.0.14393.0is Windows 10 1607, the floor of the .NET 10 Desktop Runtime the Control Panel needs.- The administrator password is left unset, and neither package invents one. Set one before the server is reachable from anywhere but the machine itself.
- Uninstalling runs the installer's own uninstaller, which does not delete the message store, the database or
hMailServer.ini. - A pre-release is never submitted.
apt and dnf on Linux: written, tested in a lab, not live
The project keeps signed apt and dnf repositories on the update feed's site,
https://updates.progressiverobot.com. They are not live. The job that makes them,package-repos, was tested on the lab machine on 26 September 2026 with a throwaway key and dummy packages, and publishes nothing until the owner has made the signing key.This is what a Debian or Ubuntu user will type once it is live; on a release with no suite,
apt updateanswers 404 for itsInRelease.sudo install -d -m 0755 /etc/apt/keyrings sudo curl -fsSLo /etc/apt/keyrings/hmailserver.asc https://updates.progressiverobot.com/hmailserver-repository-key.asc gpg --show-keys /etc/apt/keyrings/hmailserver.asc # compare the fingerprint with the one below echo "deb [signed-by=/etc/apt/keyrings/hmailserver.asc] https://updates.progressiverobot.com/apt $(. /etc/os-release && echo "$ID$VERSION_ID") main" \ | sudo tee /etc/apt/sources.list.d/hmailserver.list sudo apt update sudo apt install hmailserverThe fingerprint does not exist yet: PackageManagers.md records it as
(not made yet).There is no dnf repository at all until a stable release carries
.rpmfiles built for each distribution, and 6.3.4 carries the generic one alone. Once one does, on Fedora and Enterprise Linux it issudo curl -fsSLo /etc/yum.repos.d/hmailserver.repo https://updates.progressiverobot.com/rpm/fc44/hmailserver.repoand thensudo dnf install hmailserver, withfc44replaced by the release's directory.What 6.3.4 carries limits what the repositories could hold. Its Linux packages are one generic x86-64
.deband one generic.rpm, neither built for one distribution; hMailServer on Linux: what you get and what you do not says where each installs. In the repositories as PackageManagers.md describes them, the.debbelongs in theubuntu26.04suite, and the.rpm, built on Ubuntu 26.04, goes in no repository. On 26 September 2026dnf installof the.rpmbuilt frommasterthat day resolved its dependencies on Fedora 43 and 44 and AlmaLinux 10, and was refused on AlmaLinux 9, whose glibc and libstdc++ are older than it asks for. Packages built for each distribution come from the release after 6.3.4. The packages carry no RPM signature of their own: the signed repository metadata carries every package's SHA-256. Not tried: the job on GitLab's runners, HTTPS end to end, arm64 and aarch64. Until it is live, First install on Linux is the walk.Every setting from the environment
Since 6.3.4. Every
[Settings]key and everyhm_settingsrow the server reads has a name in the environment.Variable Sets HM_SETTING_<key>The [Settings]key, one of 241:HM_SETTING_MaxSubmissionsPerIPPerMinute=30HM_PROPERTY_<name>The hm_settingsrow:HM_PROPERTY_maxmessagesize=20480HM_SETTING_<key>_FILE,HM_PROPERTY_<name>_FILEThe same, read from the file the variable names, such as a Kubernetes or Compose Secret; UTF-8, at most 64 KB, trailing line breaks stripped The prefixes and
_FILEare written in capitals; the name after the prefix is matched without regard to case, and a key is stored in its own spelling.What is refused, before anything is stored: a name that is not a setting of the store its prefix names (
MaxMessageSizeafterHM_SETTING_is refused namingHM_PROPERTY_maxmessagesize); a misspelt prefix such asHM_SETTINGS_; a read-only property such asWebPushVapidPublicKey; the plain and the_FILEform of one setting together; a_FILEnaming a directory, a missing path or a file over 64 KB, refused naming the path, never the content; the_FILEform of a setting a domain or an account may hold its own value of; and a value the setting's own REST check would refuse, in that check's words.maxmessagesize=offis refused rather than stored as 0, which is "no limit".The verb.
hmailserver --config /etc/hmailserver/hMailServer.ini --apply-environmenthMailServer.exe --apply-environmenton Windows is the same verb from the same code. It opens the configuration and the database as the service does, so run it as the user the service runs as. It checks every value first and exits 1 having changed nothing when any is refused, then writes each through the setterPUT /api/v1/settings/...uses and prints a line per variable:set,unchangedorrefused. A secret's value is never printed. Exit 2 is a configuration file that names no database. The verb's writes are not rows in the audit trail: its own output, in a container the container's log, says what it changed.Who runs it. No container image of 6.3.4 is published: the image is one you build yourself, from the Dockerfile in the tree. Its entrypoint runs the verb after
--create-databaseand--upgrade-databaseand before the server. On Windows nothing runs it for you: a Windows service has no environment of its own that anything sets, so the verb is there for a script or a deployment tool. Run beside a running server, its values reach that server at the next reinitialise (Apply now), or the next start for a key markedrestart.The environment wins, every start. The server records the managed names in the
hm_settingsrowEnvironmentManagedSettingsand refuses an administrator's change to one of them.Where What happens REST A PUTthat would change a managed key is409, with a sentence naming the variable;GET /api/v1/settings/environmentlists every managed setting with no valueCOM (Windows) Every setter refuses with the same sentence Control Deck Set by the environment beside the key, with its value and no control Control Panel (Windows) The same mark, with the field disabled hmctlhmctl config changedprints(set by the environment);hmctl config exportleaves managed settings outUnset the variable and restart to manage the setting in the server again. A value a
_FILEsupplied stays withheld after the variable is gone: REST answers(set), the Control Panel leaves the field empty, and it is never on a command line or in a log. The environment sets the server level only, and the two[SendingLimits]keys have no environment name.The container's own variables are not settings: the database's
HM_DB_*, TLS included;HM_ADMIN_PASSWORDandHM_ADMIN_PASSWORD_FILE;HM_INI;HM_CREATE_DATABASEandHM_UPGRADE_DATABASE;HM_PROFILEandHM_PROFILE_CONFIRM. The four REST ones are aliases:HM_REST_PORTstands forHM_SETTING_RestApiPort. The Helm chart takessettings,propertiesandsettingsFrom. In a container or on Kubernetes has the table, the chart, and the stored-secrets key a first start makes, to export at once.What has not been run. The verb has been run as
hMailServer.exe --apply-environmenton Windows only. Its POSIX half compiles; the image's entrypoint as a whole, the POSIX verb against a database, the chart and the Compose file have not been executed. There is no live reload from a ConfigMap change: a restart applies it.Profiles: the shape a new server starts in
Since 6.3.4. A profile is the thirty or so settings that make a server the kind it is, each with a reason written from what the setting's reader does. Four ship as reviewed documents; there is no route that makes one of your own.
Profile For What you would notice officeOne server that receives an office's mail and holds its mailboxes SPF, the MX check, DKIM and DMARC scoring; greylisting; the quarantine; auto-ban and lockout; a password policy and the breach check (31 entries) gatewayBehind a filtering gateway that has already judged the mail Greylisting off; XCLIENT and an ARC seal trusted only from the gateway and sealer you name (17 entries) relayAn outbound relay that holds no mailbox anybody reads IMAP and POP3 closed at the next restart; hard bounces suppressed; the trace kept three months (24 entries) senderA high-volume sender judged on its bounce and complaint rates The relay's shape, more deliveries at once, the feedback loops, the trace kept six months (32 entries) Every surface shows a diff first, then saves what it replaces, then writes, all or nothing. An entry that closes a listener, trusts an address range, turns a filter off or weakens a check, or shortens a window of days asks for a confirmation. A profile never touches a port, a path, a bind address, the database connection, a password or any secret, an IP range, Incoming relays, a DNS block list, a listener's TLS or a domain's own settings. What only you know, such as the gateway's addresses, is a step listed under the diff. Revert puts back each value the profile replaced and leaves alone one an administrator changed since. It puts back settings, not data: where a profile shortened a window of days, what the sweep deleted under the shorter window stays deleted, and a listener a profile closed opens again only at the next restart. There is one snapshot: a second apply waits for the first to be reverted or discarded.
Where a profile is chosen at install time:
- The Windows installer offers the four on a page of their own, after the administrator password and before the service-account page, for a new installation only, with "None" chosen until another is. No diff is shown there: each profile's sentence names the listener, filter or trust it changes, and choosing it is the confirmation, so
relayandsenderclose IMAP and POP3 with no further question. After the database step it runshMailServer.exe --apply-profile NAME --once --if-new --confirmbefore it starts the service. Silently, that is/profile=NAME. Every failure is said, and the installation still succeeds with the shipped settings. - The container applies
HM_PROFILEonce, before the server starts;HM_PROFILE_CONFIRM=yesconfirms an entry that asks, andHM_PROFILE=nonerecords that no profile is wanted. - The verb itself:
hmailserver --apply-profile NAME [--confirm] [--once] [--if-new] hmailserver --revert-profileExit Meaning 0 Done, or nothing to do 1 Refused or failed 2 No such profile, or no database 3 An entry needs --confirm4 The service is running 5 --if-new, and the server is in serviceOn Windows the verbs refuse while the service runs (exit 4). On Linux nothing says whether a server is running, so run them with the server stopped, as the container's entrypoint does.
--if-newdoes nothing on a server of ten accounts or more. A setting the environment manages is skipped, with its variable named.Afterwards a profile is chosen in the Control Panel's Maintenance, Setting profiles (Windows), the Deck's Checklist, COM's
Settings.ApplyProfile(Windows), REST orhmctl. Read the diff atGET /api/v1/settings/profiles/{name}, or withhmctl settings profile NAME, which prints adiff_token. Apply with{"confirm": true, "diff_token": ...}onPOST /api/v1/settings/profiles/{name}/apply, orhmctl settings apply-profile NAMEwith--confirm TOKEN: a diff that has moved since it was read is refused (409) and nothing is written. The way back isPOST /api/v1/settings/profiles/revert;POST /api/v1/settings/profiles/discarddrops the snapshot.The installer page with its
/profile=NAMEswitch, the container'sHM_PROFILEand the Linux verbs have been written and read, and not run: the installer was not built and the Linux server not compiled for this change, and no container was started.What it does not do
- No package configures the server: no password, no domain, no firewall port.
- No export of the configuration as an environment.
- Four profiles, no parameters, no profile per domain.
Where to read more
- The wiki pages: Profiles and Environment and Running in a Container
- winget, Chocolatey, apt and dnf: PackageManagers.md
- The naming rule and every refusal: EnvironmentConfiguration.md
- Every entry of the four profiles: Profiles.md
- The silent upgrade: Upgrading.md
- The documentation page: Run the installer
- On this forum: Upgrading to 6.3.4, Installing on Windows for the wizard's pages, and Behind a gateway for the gateway profile's steps.
- A fresh silent install leaves the administrator password unset unless you pass
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login