Skip to content

Environment Variables

Jeroen Simonetti edited this page Sep 17, 2026 · 1 revision

Environment Variables Reference

Every service in the mimirheim container — the solver itself, all 11 input helpers, and the config editor — can be controlled entirely through environment variables. This page is for anyone running plain Docker or Docker Compose who wants to enable services and supply MQTT broker credentials without hand-authoring any YAML file upfront, finishing the rest of the configuration through the Config Editor in a browser.

If you are using the Home Assistant add-on instead, none of this applies: the Supervisor sets every variable below for you from the add-on's own options UI. See Hassio-App.


Contents

  1. ENABLE_<SERVICE> variables: which processes run at all
  2. MQTT variables: broker credentials and topic root
  3. Worked example: config-editor plus one helper, no filled-in YAML upfront

1. ENABLE_<SERVICE> variables: which processes run at all

Each of the 12 services below only starts if its ENABLE_<SERVICE> variable is set to the exact string "true". Any other value — unset, "false", "1", empty, anything else — leaves the service down. There is no default-enabled fallback for any of them: this is a fail-closed gate, not a convenience default.

Variable Service
ENABLE_BASELOAD_HA baseload-ha
ENABLE_BASELOAD_HA_DB baseload-ha-db
ENABLE_BASELOAD_STATIC baseload-static
ENABLE_CONFIG_EDITOR config-editor
ENABLE_EPEXPREDICTOR epexpredictor
ENABLE_NORDPOOL nordpool
ENABLE_PV_FETCHER pv-fetcher
ENABLE_PV_ML_LEARNER pv-ml-learner
ENABLE_PV_OPENMETEO pv-openmeteo
ENABLE_REPORTER reporter
ENABLE_SCHEDULER scheduler
ENABLE_ZONNEPLAN zonneplan

The mimirheim solver itself has no ENABLE_MIMIRHEIM variable and is not gated this way — it always runs.

Enabling a service no longer requires its config file to exist first, and an existing config file no longer enables a service by itself. These two concerns used to be conflated (a service started, or idled, purely based on whether its YAML file was present); they are now fully independent:

  • ENABLE_<SERVICE> decides whether the process starts at all.
  • Whether its config file exists and validates decides whether it runs its normal function immediately, or comes up in Awaiting Configuration: connected to MQTT, publishing only enough of the Config Service protocol (Descriptor, Operational State, get_current_values, validate_and_write, restart_request) for the Config Editor to fix it.

A service enabled this way, with no config file at all, comes up in Awaiting Configuration rather than idling or crash-looping. See the worked example below.

Upgrading from an older version? If you previously relied on a config file's mere presence to enable a helper, this is a breaking change: see the changelog entry in container/README.md for exactly which ENABLE_<SERVICE> variables to set to reproduce your previous behavior.


2. MQTT variables: broker credentials and topic root

These variables override the mqtt: section of every service's own YAML file. They exist so the Home Assistant Supervisor can inject broker credentials without an add-on needing any YAML at all, but they work identically under plain Docker or Compose.

Variable Overrides Notes
MQTT_HOST mqtt.host Broker hostname or IP. Required — from the environment or from YAML — for any service to connect at all.
MQTT_PORT mqtt.port Broker TCP port. Must parse as an integer in 1-65535; an unparseable value is a fatal error, since a silently-ignored bad port is worse than refusing to start.
MQTT_USERNAME mqtt.username Broker username.
MQTT_PASSWORD mqtt.password Broker password.
MQTT_SSL mqtt.tls The literal string "true" enables TLS (broker listens on an encrypted port, typically 8883); any other value leaves TLS disabled.
MQTT_PREFIX mqtt.topic_prefix (mimirheim core only) and the Config Service protocol's topic root for every service Default "mimir". See below.

Precedence: when any of these variables is set, it wins over the corresponding field in the service's YAML file, unconditionally. A config file that omits mqtt: entirely, or leaves it empty, is valid as long as MQTT_HOST is supplied by the environment — this is what lets a service start with no meaningful config file at all (see the worked example).

MQTT_PREFIX is not the same knob as mqtt.topic_prefix. Every service — the solver, every helper, and the config editor — publishes its Config Service protocol topics (Descriptor, Operational State, validate_and_write, restart_request) under <MQTT_PREFIX>/config-service/..., regardless of anything in its own YAML. Every Config Owner in a deployment must agree on this root, so it comes from the environment only, never from a per-service config file. Setting MQTT_PREFIX additionally overrides mqtt.topic_prefix in mimirheim core's own YAML, which is what its business topics (prices, schedules, per-device setpoints — see MQTT-Topics) are derived from. Helpers do not derive their own input/output topics from a prefix field; those are set explicitly per helper (trigger_topic, output_topic, and so on — see Configuration).

If you never set MQTT_PREFIX, everything defaults to "mimir" and you will not notice any of this.


3. Worked example: config-editor plus one helper, no filled-in YAML upfront

This sets up config-editor and nordpool from a Compose file alone, with no meaningful config file contents prepared in advance — only an empty placeholder for config-editor.yaml (see the note below on why that one file has to exist).

# docker-compose.yml
services:
  mimirheim:
    image: ghcr.io/jsimonetti/mimirheim
    volumes:
      - ./config:/config
    environment:
      TZ: Europe/Amsterdam
      MQTT_HOST: 192.0.2.10        # your broker
      MQTT_PORT: "1883"
      MQTT_USERNAME: mimir
      MQTT_PASSWORD: changeme
      ENABLE_CONFIG_EDITOR: "true"
      ENABLE_NORDPOOL: "true"
    ports:
      - "8099:8099"                # config editor web UI
    restart: unless-stopped
mkdir -p config
touch config/config-editor.yaml
docker compose up -d

Why config-editor.yaml has to exist, even empty: a config file that is missing entirely (as opposed to present but empty) always puts its service into Awaiting Configuration, regardless of whether the environment alone would otherwise be enough — see helper_common.config.load_helper_config. For every other service that is exactly the point: it comes up, connects to MQTT, and waits to be fixed through the browser. But the config editor's own browser UI is how every service gets fixed, including itself, so if its own file is missing there is no browser UI yet to fix anything with — nothing else can send it the Restart Request that would end Awaiting Configuration. An empty file sidesteps this: config-editor.yaml's schema needs nothing beyond mqtt.host, already supplied by MQTT_HOST above, so it validates immediately and the config editor comes up fully Operational, serving its web UI right away. This one-time bootstrap step is the only YAML this worked example writes by hand; nordpool.yaml genuinely never has to exist beforehand.

Once the container is up: config-editor is Operational (its own schema was satisfied by the empty file plus the environment), and nordpool is Awaiting Configuration (nordpool.yaml does not exist at all, and its schema needs more than broker settings — an area code, at minimum).

  1. Open http://<host>:8099 in a browser. The config editor lists every Config Owner it can see on the broker, including nordpool, marked as Awaiting Configuration.
  2. Open the nordpool entry and fill in the form: the environment variables above get a bare process past its own startup validation, but the Config Editor's validate_and_write step only ever sees the file on disk plus what you submit — it does not know what MQTT_HOST and friends resolved to at runtime. Enter the same broker host/port (and username/password if your broker requires them) you put in the environment above, plus your Nordpool area code and any price formula, then click Save. This writes a valid, self-contained nordpool.yaml into ./config — the editor validates the submitted values against nordpool's own schema before writing anything.
  3. A saved configuration is not picked up in place: no Config Owner ever reloads its configuration while running (see ADR-0012). Restart it so it re-reads the file it now has. This all-in-one image runs every service under s6-overlay inside one container, so docker compose restart mimirheim restarts everything at once — every other already-Operational service comes back up unaffected, since each independently re-validates its own file at startup. To restart only nordpool without touching the rest, run docker compose exec mimirheim s6-svc -r /run/service/nordpool instead. Either way, nordpool comes back up Operational.
  4. config-editor itself is already Operational, but its own entry in the editor still works the same way if you want to change its optional settings (listen port, log level, allowed_ip) later: fill in the form, Save, then restart it the same way as step 3.

See Quick-Start for a full walkthrough that includes writing mimirheim.yaml by hand instead, and Configuration for the complete field reference of every service's YAML schema.

Clone this wiki locally