Custom Dockerfile-based build for an Ignition Edge gateway with pre-baked base gwbk, module registration, and admin password provisioning, backed by MariaDB.
125 lines
5.2 KiB
Markdown
125 lines
5.2 KiB
Markdown
# 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.
|