# EDGE docker-compose build/runtime fixes — 2026-07-22 ## Starting problem `docker compose -f EDGE/docker-compose.yml up -d --build` failed. The custom `gw-build/Dockerfile` (patterned after https://github.com/thirdgen88/ignition-examples/tree/main/iiot) referenced four helper scripts that did not exist anywhere in `gw-build/` or on disk: - `retrieve-modules.sh` - `register-module.sh` - `register-password.sh` - `docker-entrypoint-shim.sh` Build cache masked this initially — earlier `RUN` layers that *used* these scripts showed `CACHED` from a prior successful build, while the `COPY` steps that needed the actual files on disk failed with "not found". ## What was checked - Searched the whole filesystem (`~/git`, home directory) for the four filenames — not found anywhere, including in the sibling `BAT/` repo (which uses the stock Ignition image directly, no custom Dockerfile). - Checked for any previously-built `edge-ignition` image, container, or volume that might have the files baked in — none existed; this build has never succeeded on this machine. - User confirmed the reference source: the `iiot` example in `thirdgen88/ignition-examples`, which contains all four scripts plus a matching `Dockerfile`. ## Changes made ### 1. Copied the four missing scripts from the reference repo Fetched from `thirdgen88/ignition-examples` (`iiot/gw-build/`) into `EDGE/gw-build/`, marked executable (0755): - `retrieve-modules.sh` - `register-module.sh` - `register-password.sh` - `docker-entrypoint-shim.sh` — this one already existed locally, identical to upstream, so no change was needed there. Note: a stray `register-modules.sh` (plural) was found already sitting in `gw-build/` — an exact duplicate of `retrieve-modules.sh`'s content under the wrong filename, unreferenced by the Dockerfile. Left in place, not deleted (flagged to user). ### 2. Dropped `mqttdistributor`/`mqttengine` from the build (user decision) The reference `Dockerfile` defines `ARG` pairs (`SUPPLEMENTAL_MQTTENGINE_DOWNLOAD_URL`/`_SHA256`, `SUPPLEMENTAL_MQTTDISTRIBUTOR_DOWNLOAD_URL`/`_SHA256`) that our local Dockerfile was missing, even though `docker-compose.yml` requested `SUPPLEMENTAL_MODULES: "mqttdistributor mqttengine"`. User said they don't want those modules, so instead of adding the missing ARGs, the module list in `docker-compose.yml` was changed to: ```yaml SUPPLEMENTAL_MODULES: "" ``` ### 3. Fixed `retrieve-modules.sh` invocation for the empty-module case `retrieve-modules.sh`'s `main()` is written to silently no-op when `SUPPLEMENTAL_MODULES` is empty, but its own `getopts` argument-validation block rejects `-m ""` before `main()` ever runs (`exit 1` with a usage message). This is a bug in the vendored script itself, inherited from the reference repo — not something introduced here. Rather than edit the vendored script (to keep it matching upstream), the Dockerfile's `RUN` line was changed to skip calling the script at all when there are no modules to fetch: ```dockerfile # before RUN ./retrieve-modules.sh \ -m "${SUPPLEMENTAL_MODULES:-}" # after RUN if [ -n "${SUPPLEMENTAL_MODULES:-}" ]; then ./retrieve-modules.sh -m "${SUPPLEMENTAL_MODULES}"; fi ``` ### 4. Fixed `BASE_GWBK_NAME` mismatch `docker-compose.yml` passed `BASE_GWBK_NAME: gateway.gwbk` as a build arg, but the actual gateway backup file in `gw-build/` is named `base.gwbk` (matching the Dockerfile's own default `ARG BASE_GWBK_NAME="base.gwbk"`). This mismatch didn't hard-fail the build immediately — it caused `unzip` inside the module/password-registration `RUN` step to silently fail-and-fallback ("cannot find or open gateway.gwbk" / "skipping password registration"), masking the real problem until the final `COPY --from=prep .../${BASE_GWBK_NAME}` step errored with "not found". Fixed by correcting the compose arg to match the real filename: ```yaml BASE_GWBK_NAME: base.gwbk ``` This also means admin password registration now actually runs during the build (previously it was silently skipped due to the filename mismatch). ### 5. Fixed a runtime crash loop after the image built successfully Once the image built, the `EDGE` container crash-looped with: ``` ERROR: Gateway Public HTTP/HTTPS/Address must be specified together: - HTTPS Port not specified or is invalid ``` The compose `command:` for the `ignition` service set `-a gateway.localtest.me` (public address) and `-h 8088` (HTTP port) but no `-s` (HTTPS port). Ignition's entrypoint requires all three (address, HTTP port, HTTPS port) to be set together or none at all — this is just gateway public-address metadata used for URL generation, not a request to actually expose HTTPS. Fixed by adding the conventional Ignition default HTTPS port: ```yaml command: > -n FW-DST-SEN -m 512 -a gateway.localtest.me -h 8088 -s 8043 ``` No compose port mapping was added for 8043 — it isn't published, only used for the internal public-address config. ## Result `docker compose -f EDGE/docker-compose.yml up -d --build` now completes successfully. Both `EDGE` (Ignition gateway) and `EDGE-db` (MariaDB) containers reach `healthy` status. Gateway is reachable at `http://gateway.localtest.me:8088` (or `http://localhost:8088`). ## Open item for follow-up - Confirm whether the stray `gw-build/register-modules.sh` (plural, unused duplicate) should be deleted.