I want to use the same container image with another service when executing balena push

Hi.

I want to use the same container image with another service when executing balena push.
When I tried it in the local environment, there was no problem.
Is there any solution?

docker-compose.yml:

version: "2"
services:
  controller:
    image: controller:latest
    build: .
    ...
  healthcheck:
    image: controller:latest
    depends_on:
      - controller
    ...

Error log:

$ balena push HogeApp

...

[controller]   Successfully built 1baxxxxxx
[controller]   Successfully tagged controller:latest
[Info]         Uploading images
[Success]      Successfully uploaded images
[Error]        Some services failed to build:
[Error]          Service: healthcheck
[Error]            Error: pull access denied for controller, repository does not exist or may require 'docker login'
[Info]         Built on arm03
[Error]        Not deploying release.

Hi, That seems very odd. Is the controller:latest image accessible on dockerhub? I will see if I can replicate this on my side. What version of balena CLI are you using for this push?

I think the problem is that the controller has both a build and image field, so on the builder the image: directive will try fetch the controller:latest image from dockerhub, which it can’t find so it fails. I believe when you do this locally with docker compose up (i assume) it does a docker tag of the image in the build: . step, which does not happen on our builders. I will chat internally with our builder maintainers, because perhaps this is behaviour that should be supported.

One other thing to test on the local docker compose is delete any images or references of controller:latest on the local docker instance and then do the build again

Thank you for your reply.

balena cli version is

$ balena --version
11.18.3

And I succeeded after deleting all the local images in my local.

$ docker rm $(docker ps -q -a)
$ docker rmi $(docker images -q)
$ docker-compose up

Can’t balena Cloud see the image after the build?

Hi @kazuph,

At the moment, the balena builders expect that any referenced image is a pre-built image that already exist on Dockerhub. In the case of the controller service, although it builds the source and then tags it locally, it doesn’t check locally to see if that image exists, instead attempting to fetch it from Dockerhub (which is why we see the [Error] Error: pull access denied for controller, repository does not exist or may require 'docker login' error.

My hope was that you could use the build context to do this instead, ensuring that a single image is produced for both services, eg:

version: "2"
services:
  controller:
    build:
        context: .
    ...
  healthcheck:
    build:
        context: .
    depends_on:
      - controller

However, after carrying out a quick test, this also doesn’t work, instead producing two images (although the layers are shared, so the device essentially downloads what comprises the single image, with slightly different metadata). Obviously this isn’t the same as what happens under a Linux/Window/macOS native install, where the service images use the same image ID.

I’ve raised an internal ticket here, as I believe what should happen is that the builder parses the docker-compose manifest to see if the build context matches that for other services, or an image is referenced along with a build context for use in other services. We’ll then discuss this in a product meeting and determine future steps.

Unfortunately, the best I can recommend at the moment is the use of the same build context (as I’ve shared above). Although it will still produce separate images, the actual downloaded layers will be (apart from a small amount of metadata) the same (and therefore not take up extra space).

Best regards,

Heds

1 Like

Hi @hedss

Thank you for the detailed explanation.
I was satisfied with your answer.

Try the recommended method.