5. Non-interactive installation
POC deployment manual chapter. Verified against the 2026.10 mainline; command output follows the installer delivered for that engagement.
Back to overview · Full table of contents · Download full PDF
This chapter: non-interactive install replaces the questions with an answers file (--answers) and a secrets file (--secret-file). The installer asks nothing, which suits batch deploy, remote execution, and unattended runs. This chapter lists every field in the two files, what happens when a field is wrong, and two complete examples you can copy and change. The reader is an implementation engineer who must finish install from a script or a remote session. For a single host with someone at the terminal, use the interactive install in Chapter 4.
5.1 When to use non-interactive install
Applies to: the same parameters will be installed on several hosts; you can run only through a remote session or an automation tool; nobody will be at the terminal to answer questions during install.
Non-interactive and interactive install follow the same flow, the same host checks, dependency probe, four install stages, and post-install acceptance. The only differences are where the answers come from and what happens when a problem appears. Interactive install stops so you can fix it on the spot. Non-interactive install reports the error and exits; you correct the files and rerun the same command.
Rules
| Rule | Notes |
|---|---|
| How it becomes non-interactive | The command line includes --answers <file>. Adding --reconfigure at the same time still enters the questions; that is not non-interactive |
| Required sections | [postgres], [clickhouse], and [object_store] must be present. Notifications use [notify], or set notify_skipped = true at the top level to skip configuration explicitly. A missing required choice reports "answers are not valid: missing <item>" |
| Access-URL default | When public_url is omitted, the installer takes this host's egress address and writes http://<host-address> (with --business-entry-port other than 80, that port is included). When a proxy, NAT, TLS ingress, or domain is in use, write it explicitly |
| Answer precedence | The file given to --answers > answers saved from the last install (resume and --reconfigure) > prefills inside the offline package. --answers is a whole-file replacement; it is not merged with offline-package prefills |
| Credentials only through the secrets file | Passwords and access keys may be written only in the file given to --secret-file, never in the answers file. In non-interactive mode the installer does not ask for credentials on the terminal; missing credentials stop the run |
| Secrets-file mode | Group and other users must have no permissions (0600 or stricter); otherwise it reports "secrets-file mode must be 0600: <path>" |
| Capabilities | Specified with --with <capabilities,…>. The answers file has no capability field. Without --with: Zentrix Gateway enables only core; the full edition enables core and knowledge base |
| Host check | Every check still runs and is printed line by line. ⚠ items are warnings. Any blocking item makes the installer report the first blocking item and stop; later steps do not run |
| Notification test | When [notify] is present, the installer sends a test message. A send failure fails the install, with "operations-notification test failed: <reason>" on screen. Non-interactive mode has no skip |
| Unknown fields | Both files accept only the fields listed in this chapter. One extra field (including a hand-mixed password or license) reports "unrecognized field in the answers file: <field>" |
| Confirm page | Non-interactive mode does not show the confirm page. After every check and probe passes, writing starts immediately |
Procedure
- Write the answers file
answers.tomlper section 5.2. - When any dependency uses an existing service, write the secrets file
secrets.tomlper section 5.3 and set it to 0600. No secrets file is needed when the installer deploys all three dependencies. - Run preflight once with
--check-only. After it passes, drop--check-onlyand run for real. Full commands are in sections 5.4 and 5.5.
What you will see
- Preflight passed prints "Preflight passed: nothing was written".
- The real run prints host-check results, dependency-probe results, notification-test results (if configured), the four install stages, and post-install acceptance, then the sign-in account and initial password (see Chapter 4 section 4.7).
Note: after an interruption or failure, fix the cause and rerun the same command. The installer continues from the breakpoint. On resume the answers-file contents must match the first run; otherwise it reports "answers do not match the last install; to change configuration, rerun with --reconfigure". A --with that differs from last time is also refused, with the difference listed. --reconfigure enters the questions and needs someone at the terminal.
5.2 Answers-file fields
The answers file is TOML. Top-level fields must be written before every [section] — a top-level field written after a section is treated as a member of that section and then reported as unrecognized.
Top-level fields
| Field | Required | Values | If wrong |
|---|---|---|---|
public_url | Optional (strongly recommended) | Access URL, http://… or https://…, may include a port, for example "http://<host-address>:8080" | An illegal format reports "access URL is not a valid address" and stops. When omitted, this host's egress address is used, which is the wrong access URL when a proxy, NAT, or domain is in front |
business_listen_port | Optional | Integer 1–65535. Fill in only when a proxy, NAT, or TLS ingress sits in front of the access URL; it is the local listen port that traffic is forwarded to | 0 reports "the local listen port must be a number between 1 and 65535". Writing it without public_url reports "when filling in the local listen port you must also fill in the access URL". Same effect as --business-entry-port on the command line; when both are given, the command line wins |
notify_skipped | Write true when notifications are not configured | Explicitly skip operations notifications; mutually exclusive with [notify] | Write it at the top level, not inside another TOML table |
Two further optional top-level fields, rarely used in a POC: admin_public_url (admin access address; fill in only when the console has its own reverse proxy or domain; when blank it is derived from the access-URL host and the admin-ingress port) and otlp_endpoint (trace export address). Both must be valid http:// or https:// addresses.
[postgres] platform database
Write exactly one of the two forms below.
| Form | Meaning |
|---|---|
managed = {} | Deployed by the installer on this host, loopback only |
external = { host = "<address>", port = 5432, user = "<superuser-account>" } | Use existing PostgreSQL |
Fields inside external:
| Field | Required | Values | If wrong |
|---|---|---|---|
host | Required | Hostname or IP | Illegal value reports "platform database address is not valid" |
port | Required | Port, commonly 5432 | 0 same as above |
user | Required | Superuser account (rolsuper is true); the installer uses it to create the platform roles and databases | Omitting it reports "when using an existing platform database you must fill in the administrator account"; a non-superuser fails the dependency probe |
tls | Optional | Omitted is plaintext; "required" requires encryption and verifies the certificate and hostname with the system trust store; { verify_full = { ca_file = "<absolute-CA-path>" } } encrypts and verifies with a specified CA | A certificate issued by an internal CA with "required" fails the dependency probe on certificate verification |
database | Must not be filled in | — | The platform's three databases are created by the installer and the names are fixed. Writing it reports "platform databases are created by the installer and names are fixed; the answers file must not contain a database name" |
replicated | Must not be filled in | — | Writing it reports "replicated is meaningful only for the analytics database ClickHouse; the platform database cannot include it" |
[clickhouse] analytics database (required)
| Form | Meaning |
|---|---|
managed = {} | Deployed by the installer on this host, loopback only. The CPU must support the instruction set in Chapter 1 section 1.3 |
external = { host = "<address>", port = 8123, database = "<database-name>", user = "default" } | Use existing ClickHouse |
Fields inside external:
| Field | Required | Values | If wrong |
|---|---|---|---|
host, port | Required | HTTP interface port (commonly 8123) or HTTPS interface port (commonly 8443), not native port 9000 | 9000 makes the dependency probe fail to connect |
database | Recommended | Database name the platform uses, for example "zenova" | Behavior when omitted follows the actual output |
user | Recommended | Login account, usually default; the password goes in the secrets file as ch_password | An account without create-database rights fails the dependency probe |
tls | Optional | Same as [postgres] | Same as [postgres] |
replicated | Optional | Write true when the database is replicated (engine Replicated); omit for standalone | A declaration that does not match the actual engine is refused by the pre-install probe |
[object_store] object storage
Write exactly one of the three forms below. It cannot be changed online after install.
| Form | Meaning |
|---|---|
bundled = {} | Bundled object storage; recommended for production single-host |
local_dir = {} | Local directory; single-host trial only |
external_s3 = { endpoint = "<address>", region = "<region>", bucket = "<bucket>", addressing = "path" } | Use existing S3-compatible storage |
Fields inside external_s3 (all four required):
| Field | Values | If wrong |
|---|---|---|
endpoint | http://… or https://…, may include a port. Whether it is encrypted is decided by the address prefix; external_s3 has no tls field | An illegal address reports "object storage address is not valid"; an extra tls is an unrecognized field |
region | Region, for example "us-east-1" | A mismatch with the storage side makes the dependency probe fail read/write |
bucket | Bucket name created in advance | A missing bucket fails the dependency probe |
addressing | "path" (path-style) or "virtual-hosted" (virtual-hosted) | Omitting it rejects the answers file; any other value is a format error |
[notify] operations-notification channel
To skip configuration, omit this section and write notify_skipped = true at the top of the answers file. Put the signing secret in the secrets file as notify_secret; do not write it into the answers file.
| Field | Required | Values | If wrong |
|---|---|---|---|
kind | Required | "dingtalk" (DingTalk), "feishu" (Feishu), "wecom" (WeCom), "webhook" (Webhook). Email is not provided | Any other value is a format error |
target | Required | http:// / https:// address of the robot or webhook | An illegal address reports "address is not valid". A legal address that cannot send fails the install ("operations-notification test failed") |
[[hosts]] host list
Do not write this section for a single-host install. Writing [[hosts]] enters a multi-host install. Each row has address, role (control_plane, gateway, postgres, clickhouse, arbiter), and site. A multi-host install must use existing S3-compatible storage; bundled or local_dir reports "a multi-replica deployment must use existing S3-compatible storage; bundled object storage or a local directory cannot be used". Multi-host install is out of scope for this manual.
Note: the answers file contains no passwords, keys, or license, and can be filed with the handover materials. After install, the answers actually used this run are saved at /opt/zenova/state/answers.toml.
5.3 Secrets file
The secrets file is also TOML. Fill in the keys required by the chosen dependencies and notification channel.
| Key | When needed | Contents |
|---|---|---|
pg_admin_password | [postgres] is external | Password of the superuser account written in user. Used only during install to create the platform roles and databases; not written to any file or log |
ch_password | [clickhouse] is external | Login password of the account written in user |
s3_access_key_id | [object_store] is external_s3 | Access-key ID |
s3_access_key_secret | [object_store] is external_s3 | Secret access key |
notify_secret | DingTalk robot signing is enabled, or the webhook needs a signature | Optional signing secret; not echoed, not written into install answers; platform channel configuration is stored encrypted under the existing mechanism |
master_key | Only when installing onto existing platform data (takeover) | Master key of the previous deployment. Do not write it for a first single-host install |
Procedure
- In the install staging directory, create an empty file that only root can read and write. Do not use
echoto write a password, so the password does not enter command history.
# Install host · root · write (create an empty secrets file, mode 0600)
cd /root/zenova-install
umask 077
touch secrets.toml
chmod 600 secrets.toml- Open
secrets.tomlin a text editor and write what is needed, for example:
pg_admin_password = "<PostgreSQL-superuser-password>"
ch_password = "<ClickHouse-account-password>"
s3_access_key_id = "<access-key-id>"
s3_access_key_secret = "<secret-access-key>"- Check mode and owner.
# Install host · root · read-only
ls -l /root/zenova-install/secrets.tomlWhat you will see
- The mode column is
-rw-------, ownerroot.
Note: when a credential required by a dependency is missing, the installer reports "when using an existing service, non-interactive install must provide credentials with --secret-file" and stops on a failed dependency probe. It does not fall back to asking on the terminal. Wrong mode reports "secrets-file mode must be 0600: <path>". After install, delete the file per Chapter 8 section 8.3, or hand it over under the customer's credential-management rules.
5.4 Example 1: installer deploys all three dependencies
Applies to: the recommended POC combination. The platform database, analytics database, and object storage are all deployed by the installer on this host. No secrets file is needed.
Procedure
- Write the answers file
answers.tomlin the install staging directory:
# Top-level fields before every section
public_url = "http://<host-address>"
[notify]
kind = "webhook"
target = "https://hooks.example.com/zentrix"
[postgres]
managed = {}
[clickhouse]
managed = {}
[object_store]
bundled = {}- Preflight (writes nothing):
# Install host · root · read-only (preflight; writes nothing)
cd /root/zenova-install
sudo ./zenova install ./<offline-package>.zpkg --answers answers.toml --with core --check-only </dev/null- After preflight passes, install for real:
# Install host · root · write (start install; no further questions)
cd /root/zenova-install
sudo ./zenova install ./<offline-package>.zpkg --answers answers.toml --with core </dev/null</dev/null attaches standard input to the empty device. A non-interactive install does not ask questions in the normal case. If a step still needs input, the installer immediately reads end-of-input, treats it as typing q, and exits (exit code 130), instead of blocking forever in an unattended session. Always add it when calling from a remote session or an automation tool.
What you will see
- Preflight prints "Preflight passed: nothing was written".
- The real install completes the data layer, control plane, selected capabilities, and post-install acceptance in order; about 4 minutes on a clean host.
- Finally it prints time per stage, the acceptance result, the
rootaccount and initial password, Direct access on this host, and Access URL.
Note: --with must match the product of this offline package. Zentrix Gateway does not provide hosted agents or document parsing; including them reports "… does not include the "…" capability; remove it from --with". Capability IDs are core, knowledge_base, agent_runtime, doc_parse, ha_data.
5.5 Example 2: existing databases and object storage
Applies to: the customer requires the platform database, analytics database, and object storage all to be existing services, and the database connections must be encrypted.
Prerequisite: the existing services meet every requirement in Chapter 1 section 1.5 (PostgreSQL superuser and extensions, ClickHouse version and macros, a bucket created in advance with read/write/delete). If certificates are issued by an internal CA, the CA file is already on the install host.
Procedure
- Place the CA certificate the customer provided in the install staging directory, for example
/root/zenova-install/customer-ca.pem(it must be referenced by absolute path). - Write the answers file
answers.toml:
public_url = "https://<access-domain>"
business_listen_port = 80
[postgres]
# When the certificate is issued by a public CA you may write tls = "required"
external = { host = "<PostgreSQL-address>", port = 5432, user = "<superuser-account>", tls = { verify_full = { ca_file = "/root/zenova-install/customer-ca.pem" } } }
[clickhouse]
external = { host = "<ClickHouse-address>", port = 8443, database = "zenova", user = "default", tls = { verify_full = { ca_file = "/root/zenova-install/customer-ca.pem" } } }
[object_store]
external_s3 = { endpoint = "https://<object-storage-address>", region = "<region>", bucket = "<bucket-name>", addressing = "path" }
[notify]
kind = "wecom"
target = "<WeCom-robot-address>"Do not write database in [postgres]. When existing ClickHouse is replicated, add replicated = true inside external.
- Create the secrets file
secrets.toml(0600) per section 5.3 and write:
pg_admin_password = "<PostgreSQL-superuser-password>"
ch_password = "<ClickHouse-account-password>"
s3_access_key_id = "<access-key-id>"
s3_access_key_secret = "<secret-access-key>"- Preflight, then install for real:
# Install host · root · read-only (preflight; writes nothing)
cd /root/zenova-install
sudo ./zenova install ./<offline-package>.zpkg --answers answers.toml --secret-file secrets.toml --with core --check-only </dev/null# Install host · root · write (start install; no further questions)
cd /root/zenova-install
sudo ./zenova install ./<offline-package>.zpkg --answers answers.toml --secret-file secrets.toml --with core </dev/nullEncryption-mode spellings
| Scenario | tls spelling |
|---|---|
| Intranet plaintext | Omit tls |
| Server certificate issued by a CA the system trusts | tls = "required" |
| Server certificate issued by the customer's internal CA | tls = { verify_full = { ca_file = "<absolute-CA-path>" } } |
| Object-storage encryption | Do not write tls; start endpoint with https:// |
What you will see
- The dependency probe passes item by item: the PostgreSQL account can log in, is a superuser, and has the extensions; ClickHouse version, macros, and create-database rights are met; object storage read, write, and delete work. The probe creates and then deletes a temporary database or object; it does not write business data.
- The notification test shows "Test message sent; confirm it was received"; confirm receipt in the WeCom group.
- After that, same as example 1.
Note:
- When the dependency probe fails, the screen shows "dependency probe failed: <reason>, contact <owner>", for example needing the database administrator or storage administrator. After the fix, rerun the same command.
- When existing PostgreSQL already holds data for this platform, an ordinary install stops and tells you to use takeover (out of scope for this manual).
- This example's access URL is
https://. The certificate is terminated by the customer's front load balancer or reverse proxy.business_listen_portis the port the TLS ingress forwards to on this host. This host does not serve HTTPS. - With existing PostgreSQL and existing S3,
zenova backupdoes not include those two parts; the corresponding administrators are responsible. This environment also does not support wipe-and-reinstall.
5.6 Turning download-site prefills into a non-interactive run
Applies to: the offline package was downloaded after filling in Prefilled settings on the download site, so it already carries a set of answers, and you now want to run non-interactively.
Prefills from the download site travel with the offline package. During interactive install, the installer lists those items for confirmation: ordinary items are confirmed with Enter; address-type items (existing-service addresses, notification-channel address) are marked "from the customizer site, unsigned" and need y one by one.
To switch to non-interactive:
Procedure
- Write a complete
answers.tomlper section 5.2. You may copy the same prefills from the Configuration link on the download page (follow the actual page), but you must complete every required section —--answersis a whole-file replacement. Items prefilled in the offline package but missing from the answers file are not reused, and the installer reports "missing <item>". - Prepare a secrets file per section 5.3 when credentials are needed. The download site never collects credentials; this step cannot be skipped.
- Run the commands in section 5.4 or 5.5, including
--answers.
What you will see
- The installer no longer shows Confirm prefilled settings and does not require
yone by one. It goes straight to the host check.
Note: --answers has the highest precedence. After it is given, prefills inside the offline package do not take part in this install. The answers file is provided by the implementation engineer and is treated as already confirmed, so check address-type fields with the customer before writing them (you can compare with the confirmation table in Chapter 1 section 1.6).
Capability notes
| Not provided | Alternative |
|---|---|
| Writing passwords, keys, or a license in the answers file | Write passwords and access keys in a 0600 secrets file and pass --secret-file; after install the tenant administrator imports the license on the console (Chapter 6 section 6.4) |
| Automatically skipping a blocking item, a failed dependency probe, or a failed notification test in non-interactive mode | Follow the on-screen prompt to fix the host, dependency, or notification channel, or change the answers file and rerun the same command |
Automatically merging --answers with offline-package prefills | Write every required section in the answers file |
| Switching to another answers file or another capability set on resume | Add --reconfigure to return to the questions and reconfirm (someone must be at the terminal), or keep the answers and --with identical to the first run |
| Specifying a database name for existing PostgreSQL in the answers file | Platform databases are created by the installer with a superuser and names are fixed; supply only address, port, superuser account, and encryption |
Previous: 4. Interactive installation · Next: 6. First sign-in and initialization
4. Interactive installation
POC deployment manual chapter. Verified against the 2026.10 mainline; command output follows the installer delivered for that engagement.
6. First sign-in and initialization
POC deployment manual chapter. Verified against the 2026.10 mainline; command output follows the installer delivered for that engagement.