Skip to main content

Where is the configuration file

Data lake configuration is built from «two sources, one direction». The files that operators edit are fixed, and the configuration files inside the container are what get generated by multiplying those together.

호스트 /etc/kopens/conf/*.template ← 설정의 «형태» (빈칸이 뚫린 원본)
× /etc/kopens/plantpulse-platform.env ← 시크릿 (비밀번호 · API 키)
× /etc/kopens/platform.node.env ← 이 노드의 값 (IP · 모드)
+ 이미지 안 config/defaults.env ← 비밀 아닌 기본값 (위에서 안 준 것만)
─────────────────────────────────────────
→ pd config render → /opt/kopens/plantpulse-platform/<module>/conf/… (생성물)

pd start is rendered first, without exception, every time. So even if you hand-edit the generated files inside the container, they disappear on the next startup. On 2026-09-01, there was an actual incident where someone edited cassandra.yaml inside the container to enable authentication, and then a regeneration reverted the file, breaking authentication entirely.

The four canonical files

#FileWhat it holdsFormatWho writes it
1/etc/kopens/plantpulse-platform.envSecrets — service account passwords, API keys, TLS passwords. Non-secret common values may also be written hereOne per line in VAR=값, without export. The two header lines (# generated: · # last rotation:) are managed by the toolCreated by install.sh, updated by passwd.sh. Non-secret lines are edited directly by the operator
2/etc/kopens/platform.node.envValues true only for this boxPP_MASTER_IP · PP_KAFKA_ADVERTISED_HOST · DOCKER_PP_EXTERNAL_IP · PP_NODE_IDSame formatCreated from a template by the installer, and edited directly by the operator
3/etc/kopens/conf/*.templateThe shape of the configuration — 33 original configuration files for each engineEach engine's own syntax + ${PP_변수} placeholdersSeeded from the image on first startup, then edited directly by the operator
4(inside the image) plantpulse-datalake-cli/config/defaults.envNon-secret defaults — port, account name, directory, TLS settingsKEY=valueProduct-provided. Operators don't edit this directly but override it with 1 and 2
Editing the file does not change the password

Editing the password line on the sidecar alone does not complete the change. For values where the server account is the source of truth, such as PostgreSQL and Cassandra, the server side must also be changed, and doing this out of order will prevent the platform from starting. bin/passwd.sh performs that sequence for you → Changing Passwords / API Keys

The order in which values are determined

The order in which the host's bin/env.sh reads things from top to bottom is the priority order. What is read later wins.

PrioritySourceWhy it wins
1 (highest)/etc/kopens/platform.node.envAn unconditional assignment read after the sidecar
2/etc/kopens/plantpulse-platform.envAn unconditional assignment in VAR=값 — also overrides the shell's export
3The calling shell's exportOnly when 1 and 2 don't specify that name
4 (lowest)${VAR:-기본값} of bin/env.shOnly when no one has set it

That value flows through compose into the container as an environment variable, and inside the container the value passed in overrides defaults.env.

On a node whose installation is already complete, export is silently ignored

Methods of supplying a value from the shell, such as PP_PG_PASSWORD=새값 bin/up.sh, only work on a node that doesn't yet have a sidecar. If the sidecar already holds that name, the sidecar wins. There have been actual incidents where someone believed the value had been changed this way and moved on.

To see the effective value and its source for this box right now, don't try to simulate it in your head — run this command instead. Secrets are masked with ****.

cd /opt/kopens/plantpulse-platform-docker
bin/env.sh --print

There is no sidecar inside the container

The /etc/kopens/plantpulse-platform.env file is not mounted into the container. Values only get in through the path where the host's bin/env.sh reads the sidecar and compose injects that as an environment variable into the container.

This has two consequences.

  • After editing the sidecar, the container must be recreated for the new value to take effect. The host's bin/restart-datalake.sh does this.
  • No matter what you write in the sidecar, a name that compose doesn't pass through never reaches the container. Which names reach it is determined by the x-pp-secrets anchor in compose/docker-compose.yml and the environment: block of the plantpulse-datalake service. The Variable Reference collects only the «names that reach».

If you run pd doctor inside the container, the sidecar row doesn't show up as "file not found" — it doesn't show up at all. Instead, the all required secrets set row is the actual measurement — this is expected.

Template list — what renders where

The 33 templates in the host's /etc/kopens/conf/ (23 top-level + 10 cluster/) go to the locations below. The source of truth for the mapping table is plantpulse-datalake-cli/config/render.map inside the container, and pd config list prints the row corresponding to this node's mode.

TemplateRender location (relative to PP_HOME)MASTERWORKER
valkey.confplantpulse-storage/cache/valkey/conf/valkey.conf○ (cluster/)
postgresql.conf · pg_hba.confplantpulse-storage/db/postgres/conf/○ (cluster/)
cassandra.yaml · jvm-server.optionsplantpulse-storage/db/cassandra/conf/○ (cluster/)
spark-env.sh · spark-defaults.conf · metrics.propertiesplantpulse-analytics/spark/conf/
hive-site.xml · hive-auth.propertiesplantpulse-analytics/spark/conf/○ (cluster/)
hive-site.xmlplantpulse-analytics/hive/conf/hive-site.xml
kyuubi-defaults.confplantpulse-analytics/kyuubi/conf/
gravitino-iceberg-rest-server.confplantpulse-analytics/gravitino/conf/
kafka.properties · kafka-jaas.confplantpulse-messaging/kafka/config/kafka.properties · jaas.conf
hivemq.xml · plantpulse-mq-auth.propertiesplantpulse-messaging/mqtt/conf/config.xml · auth.properties
plantpulse-timeseries-engine.confplantpulse-timeseries/engine/conf/ (under two names)
plantpulse-datalake-admin-api.propertiesplantpulse-datalake-admin-api/config/○ (cluster/)
workflow.yaml · application.yamlplantpulse-workflow/temporal/config/ · kestra/config/
plantpulse-cep.propertiesplantpulse-cep/config/
plantpulse-jdbc.properties · plantpulse-data-gateway.propertiesplantpulse-data-gateway/config/

The cluster/ mark means the WORKER node uses a different template under /etc/kopens/conf/cluster/. For example, MASTER's valkey.conf.template has no replicaof, while cluster/valkey.conf.template has replicaof ${PP_MASTER_IP} ${PP_REDIS_PORT}.

Template syntax

There are only three.

SyntaxMeaning
${PP_VAR}If the value is missing, the entire render fails (exit 4). It will not proceed by filling in an empty value
${PP_VAR:기본값} · ${PP_VAR:-기본값}If the value is missing, use the default

Secrets cannot have inline defaults. There was an incident where the old renderer filled in an empty value and proceeded, resulting in Cassandra coming up with an empty-string password, so it now lists all missing names and halts instead.

Configuration that isn't rendered — the management console account

The management console's login account is not part of any template. The admin-api process reads it directly from environment variables. This is to avoid creating one more copy of the password on disk.

VariableWhere it comes fromDefault
PP_DATALAKE_ADMIN_USERdefaults.envadmin
PP_DATALAKE_ADMIN_PASSWORDsidecarInstalls from 2026-09-05 onward use the same development default as the web console admin → Changing the initial password. Installs before that date have this empty, so the console is disabled
PP_DATALAKE_ADMIN_API_KEYsidecarNone — if empty, only key authentication is disabled; browser login still works

Differences from old guidance

Old documentationNow
configure.sh generates the configurationpd config render (and pd start every time)
/etc/kopens/conf is mounted as plantpulse-startup/templateMounted as plantpulse-datalake-cli/config/templates (2026-09-03). The old location was a copy that nothing reads, so operator edits there never reached the render
env.sh · env-reset.sh inside the containerRemoved. Values are decided by the host and passed in by compose
Disabling a component with PP_OPTIONSThe variable name changed to PD_OPTIONS, and the current compose stack does not pass this value into the containerFAQ
PP_TIER (FULL / DATALAKE / APP)Removed on 2026-09-02. Every box is a full install