Hi,
I’m experimenting with porting WebThings Gateway to balenaOS.
I have a working docker-compose.yml that points to a pre-built image on Docker Hub which I have successfully deployed to a device, but am trying to create a build that uses balena push {local ip address}to build locally on the device during development.
I have an edited docker-compose.yml on my local branch which uses build: . instead of image: webthingsio/gateway:2.0.0-beta.1. This seems to work fine when I build it locally with docker build or docker compose up. However, when I try to build this on-device using balena push {local ip address}, the webthings-gateway service fails to start, with the error:
[Logs] [2025-08-18T21:24:31.692Z] [webthings-gateway] + WEBTHINGS_HOME=/home/node/.webthings
[Logs] [2025-08-18T21:24:31.692Z] [webthings-gateway] + args=
[Logs] [2025-08-18T21:24:31.692Z] [webthings-gateway] + start_task=run-only
[Logs] [2025-08-18T21:24:31.692Z] [webthings-gateway] + [[ /home/node/.webthings == \/\h\o\m\e\/\n\o\d\e\/\.\w\e\b\t\h\i\n\g\s ]]
[Logs] [2025-08-18T21:24:31.692Z] [webthings-gateway] + [[ -d /home/node/.mozilla-iot ]]
[Logs] [2025-08-18T21:24:31.692Z] [webthings-gateway] + is_container
[Logs] [2025-08-18T21:24:31.693Z] [webthings-gateway] + '[' -f /.dockerenv ']'
[Logs] [2025-08-18T21:24:31.693Z] [webthings-gateway] + return 0
[Logs] [2025-08-18T21:24:31.694Z] [webthings-gateway] ++ node --version
[Logs] [2025-08-18T21:24:31.694Z] [webthings-gateway] ++ egrep -o '[0-9]+'
[Logs] [2025-08-18T21:24:31.695Z] [webthings-gateway] ++ head -n1
[Logs] [2025-08-18T21:24:31.696Z] [webthings-gateway] + _node_version=20
[Logs] [2025-08-18T21:24:31.696Z] [webthings-gateway] + [[ ! -f /home/node/.webthings/.node_version ]]
[Logs] [2025-08-18T21:24:31.696Z] [webthings-gateway] + mkdir -p /home/node/.webthings/config
[Logs] [2025-08-18T21:24:31.697Z] [webthings-gateway] + cd /home/node/webthings/gateway
[Logs] [2025-08-18T21:24:31.697Z] [webthings-gateway] + ./tools/update-addons.sh
[Logs] [2025-08-18T21:24:31.698Z] [webthings-gateway] + export NVM_DIR=/home/node/.nvm
[Logs] [2025-08-18T21:24:31.698Z] [webthings-gateway] + NVM_DIR=/home/node/.nvm
[Logs] [2025-08-18T21:24:31.698Z] [webthings-gateway] + '[' -s /home/node/.nvm/nvm.sh ']'
[Logs] [2025-08-18T21:24:31.698Z] [webthings-gateway] +++ dirname ./tools/update-addons.sh
[Logs] [2025-08-18T21:24:31.699Z] [webthings-gateway] ++ readlink -f ./tools
[Logs] [2025-08-18T21:24:31.699Z] [webthings-gateway] + node /home/node/webthings/gateway/tools/update-addons.js
[Logs] [2025-08-18T21:24:31.726Z] [webthings-gateway] node:internal/modules/cjs/loader:1215
[Logs] [2025-08-18T21:24:31.726Z] [webthings-gateway] throw err;
[Logs] [2025-08-18T21:24:31.726Z] [webthings-gateway] ^
[Logs] [2025-08-18T21:24:31.726Z] [webthings-gateway]
[Logs] [2025-08-18T21:24:31.726Z] [webthings-gateway] Error: Cannot find module '../build/migrate'
[Logs] [2025-08-18T21:24:31.726Z] [webthings-gateway] Require stack:
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] - /home/node/webthings/gateway/tools/update-addons.js
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module._resolveFilename (node:internal/modules/cjs/loader:1212:15)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module._load (node:internal/modules/cjs/loader:1043:27)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module.require (node:internal/modules/cjs/loader:1298:19)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at require (node:internal/modules/helpers:182:18)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Object.<anonymous> (/home/node/webthings/gateway/tools/update-addons.js:1:17)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module._compile (node:internal/modules/cjs/loader:1529:14)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module._extensions..js (node:internal/modules/cjs/loader:1613:10)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module.load (node:internal/modules/cjs/loader:1275:32)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Module._load (node:internal/modules/cjs/loader:1096:12)
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:164:12) {
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] code: 'MODULE_NOT_FOUND',
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] requireStack: [ '/home/node/webthings/gateway/tools/update-addons.js' ]
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] }
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway]
[Logs] [2025-08-18T21:24:31.727Z] [webthings-gateway] Node.js v20.19.4
It appears that the build directory inside the docker image does not contain the .js files that I would expect to have been compiled by TypeScript with npm run build.
When I log into a container using the image built locally with Docker I can see the properly populated contents of the build directory:
root@7bd8499c2554:/home/node/webthings/gateway/build# ls
addon-loader.d.ts certificate-manager.js.map fluent.d.ts passwords.d.ts.map sleep.js.map
addon-loader.d.ts.map constants.d.ts fluent.d.ts.map passwords.js static
addon-loader.js constants.d.ts.map iso-639 passwords.js.map test
addon-loader.js.map constants.js jwt-middleware.d.ts platform.d.ts tunnel-service.d.ts
addon-manager.d.ts constants.js.map jwt-middleware.d.ts.map platform.d.ts.map tunnel-service.d.ts.map
addon-manager.d.ts.map controllers jwt-middleware.js platform.js tunnel-service.js
addon-manager.js db.d.ts jwt-middleware.js.map platform.js.map tunnel-service.js.map
addon-manager.js.map db.d.ts.map log-timestamps.d.ts platforms user-profile.d.ts
addon-utils.d.ts db.js log-timestamps.d.ts.map plugin user-profile.d.ts.map
addon-utils.d.ts.map db.js.map log-timestamps.js push-service.d.ts user-profile.js
addon-utils.js deferred.d.ts log-timestamps.js.map push-service.d.ts.map user-profile.js.map
addon-utils.js.map deferred.d.ts.map migrate.d.ts push-service.js utils.d.ts
addons-test deferred.js migrate.d.ts.map push-service.js.map utils.d.ts.map
api.d.ts deferred.js.map migrate.js router.d.ts utils.js
api.d.ts.map ec-crypto.d.ts migrate.js.map router.d.ts.map utils.js.map
app.d.ts ec-crypto.d.ts.map models router.js views
app.d.ts.map ec-crypto.js oauth-types.d.ts router.js.map wifi-setup.d.ts
app.js ec-crypto.js.map oauth-types.d.ts.map rules-engine wifi-setup.d.ts.map
app.js.map errors.d.ts oauth-types.js schema-form wifi-setup.js
certificate-manager.d.ts errors.d.ts.map oauth-types.js.map sleep.d.ts wifi-setup.js.map
certificate-manager.d.ts.map errors.js package.json sleep.d.ts.map
certificate-manager.js errors.js.map passwords.d.ts sleep.js
However, when I log into a container using the image created by balena push I note that the output JavaScript files are missing:
root@6e3d400caa0b:/home/node/webthings/gateway/build# ls
addons-test api.d.ts.map fluent.d.ts iso-639 package.json plugin schema-form static utils.d.ts views
api.d.ts controllers fluent.d.ts.map models platforms rules-engine src test utils.d.ts.map
What is odd is that I can see what appears to be the TypeScript compiler completing successfully in the build logs, but then the build directory does not contain the files it is supposed to.
I am not super experienced with Docker or balenaOS so it’s possible I’m just missing something obvious, but are there differences between docker compose up and balena push that could account for this difference?
Thank you.