Cross Build Error During Balena Push

I’m trying to create a Balena Docker image that can be built on either my target platform (Arm64) or my development machine X86.

Following the instructions on the Balena docs, I’ve added the RUN [ “cross-build-start” ] command to my docker file, which I believed would let me achieve this by starting kernel emulation. This seems to work fine on my desktop machine here and on a Gitlab builder. However, when I try to do a balena push, I get the following error:

balena push keenan-tx2

[main]     Step 1/7 : FROM balenalib/aarch64-ubuntu:bionic
[main]      ---> 7b3cc058e071
[main]     Step 2/7 : RUN [ "cross-build-start" ]
[main]      ---> Running in 31951ab722b4
[main]     standard_init_linux.go:207: exec user process caused "exec format error"
[main]     
[main]     Removing intermediate container 31951ab722b4
[main]     The command 'cross-build-start' returned a non-zero code: 1
[Info]     Uploading images

Here is my docker file:

FROM balenalib/aarch64-ubuntu:bionic

RUN [ "cross-build-start" ]

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get install -y python3.6 python3-pip python3-yaml python3-empy python3-netifaces
RUN pip3 install defusedxml

RUN [ "cross-build-end" ]

CMD ["/usr/src/start.bash"]

I’m very confused why this doesn’t work. Please help haha.

Hi there, I suspect the approach you are using only works for 32bit ARM architectures. There is a easier way to do this now, using balena CLI emulated builds as documented here: https://www.balena.io/docs/learn/more/masterclasses/cli-masterclass/#51-building-an-image-on-a-development-machine

I see. So you would suggest removing the crossbuild flags and instead using a command like this to build the image on my development machine and in CI?

balena build --arch aarch64 --device-type astro-tx2 --emulated

If that’s the case, we should definitely update the docs here to state that this does not work for 64 bit builds.

Actually, I think I know what’s going on. We have native ARM builders, which do not require the cross build magic in the Dockerfile(s) anymore. You can switch to using Dockerfile.template format, which will cover all the supported architectures automatically, by resolving the target application architecture as follows:

$ cat Dockerfile.template 

FROM balenalib/%%BALENA_ARCH%%-ubuntu:bionic

RUN ...

Then just use native commands in the file and the job will be automatically sent to the correct builders.

I see. How can I set the template variable if I want to run the build command in my CI system?

Your CI system only needs to know which applications it’s pushing to, the Dockerfile template is identical in each case.

Correct but what if I want to only build the application, but not push. Does the balena build command set the the %%BALENA_ARCH%% variable accordingly? Or is there a way to set it with docker build?

%%BALENA_ARCH%% and other template variables are only resolved when doing balena build|push or git push to balena git server(s).

Ah I see. So there is no way to use the docker template with a local balena build or normal docker build?

You can use the template approach using balena build (but not using docker build):

https://www.balena.io/docs/reference/balena-cli/#build-source
https://www.balena.io/docs/reference/base-images/base-images/#supported-architectures-distros-and-languages

Great thank you so much for your help!

So I’m trying to build a tempalted image locally with Balena build.

I have this docker file:

FROM balenalib/%%BALENA_ARCH%%-ubuntu:bionic

RUN dpkg --print-architecture

but when I run it with this command:

balena build --arch amd64 --device-type generic --dockerfile Dockerfile --debug --nocache

I get this error:

[Debug] Parsing input…
[Debug] Loading project…
[Debug] Resolving project…
[Info] No “docker-compose.yml” file found at “/home/keenan/consultants_repo/src/payload”
[Info] Creating default composition with source: “/home/keenan/consultants_repo/src/payload”
[Debug] Creating project…
[Info] Building for amd64/generic
[Build] Building services…
[Build] main Preparing…
[Info] Emulation is enabled
[Debug] Found build tasks:
[Debug] main: build [.]
[Debug] Resolving services with [generic|amd64]
[Debug] Found project types:
[Debug] main: Standard Dockerfile
[Debug] Prepared tasks; building…
[Build] Built 1 service in 0:05
[Error] Build failed
invalid reference format: repository name must be lowercase

Error: invalid reference format: repository name must be lowercase
at Stream. (/usr/local/lib/node_modules/balena-cli/node_modules/resin-docker-build/build/builder.js:181:23)
at Stream.stream.write (/usr/local/lib/node_modules/balena-cli/node_modules/through/index.js:26:11)
at Stream.ondata (internal/streams/legacy.js:19:31)
at Stream.emit (events.js:314:20)
at Stream.EventEmitter.emit (domain.js:486:12)
at drain (/usr/local/lib/node_modules/balena-cli/node_modules/through/index.js:36:16)
at Stream.stream.queue.stream.push (/usr/local/lib/node_modules/balena-cli/node_modules/through/index.js:45:5)
at Parser.parser.onToken (/usr/local/lib/node_modules/balena-cli/node_modules/JSONStream/index.js:132:18)
at Parser.proto.write (/usr/local/lib/node_modules/balena-cli/node_modules/jsonparse/jsonparse.js:135:34)
at Stream. (/usr/local/lib/node_modules/balena-cli/node_modules/JSONStream/index.js:23:12)
at Stream.stream.write (/usr/local/lib/node_modules/balena-cli/node_modules/through/index.js:26:11)
at IncomingMessage.ondata (_stream_readable.js:713:22)
at IncomingMessage.emit (events.js:314:20)
at IncomingMessage.EventEmitter.emit (domain.js:486:12)
at addChunk (_stream_readable.js:303:12)
at readableAddChunk (_stream_readable.js:279:9)
From previous event:
at /usr/local/lib/node_modules/balena-cli/node_modules/resin-docker-build/build/builder.js:73:20
at processImmediate (internal/timers.js:458:21)
From previous event:
at Builder.createBuildStream (/usr/local/lib/node_modules/balena-cli/node_modules/resin-docker-build/build/builder.js:72:97)
at /usr/local/lib/node_modules/balena-cli/node_modules/resin-multibuild/build/build.js:84:21

Additional information may be available with the --debug flag.
For help, visit our support forums: https://forums.balena.io
For bug reports or feature requests, see: https://github.com/balena-io/balena-cli/issues/

So it would seem that balena build is not populating the template variable on my machine.

Hi Keenan, you need to use the filename Dockerfile.template and the variables will be substituted appropriately.