# docker-dev/docker-compose.script-runner-shadow.yml — optional overlay: run the central pair in SHADOW mode # (lmxopcua#780 P2, Scripting:Runner=Shadow). Every compiled VirtualTag / Calculation / scripted-alarm evaluation runs # IN PROCESS — that is what is published — and is mirrored to the ScriptWorker pool, whose result is only compared. # Shadow doubles script CPU and keeps the in-process risk: a time-boxed diagnostic, never a production mode. # # Up (the image must be built from a branch that has the shadow runner): # docker compose -f docker-dev/docker-compose.yml -f docker-dev/docker-compose.script-runner-shadow.yml up -d --no-deps central-1 central-2 # Back to InProcess: re-run `up -d --no-deps central-1 central-2` with the base file alone. # # Watch it: `/metrics` on :9000 carries otopcua_script_shadow_compared_total{kind,result}, # otopcua_script_shadow_mismatch_total{kind,reason,script}, otopcua_script_shadow_dropped_total{kind,reason} and # otopcua_script_shadow_inflight; each script's first mismatch per reason logs one Warning "Script shadow mismatch: …" # with a diff summary; `/health/ready`'s `script-runner` entry stays Healthy and carries the shadow counters as data. x-script-runner-shadow-env: &script-runner-shadow-env Scripting__Runner: "Shadow" Scripting__Runner__Seams__0: "VirtualTag" Scripting__Runner__Seams__1: "Calculation" Scripting__Runner__Seams__2: "ScriptedAlarm" Scripting__Worker__PeCacheDir: "/tmp/otopcua-pe-cache" services: central-1: environment: <<: *script-runner-shadow-env central-2: environment: <<: *script-runner-shadow-env