Files
Edge/CHANGES.md
a.williamson 1911a4960f Initial commit: EDGE Ignition gateway docker-compose build
Custom Dockerfile-based build for an Ignition Edge gateway with
pre-baked base gwbk, module registration, and admin password
provisioning, backed by MariaDB.
2026-07-22 10:31:20 -05:00

5.2 KiB

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:

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:

# 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:

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:

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.