0

I hope this is an easy one. I'm using Docker to run Homeassistant and Node-Red containers on a Raspberry Pi 4.

Based on this guide they recommend making a DockerFile to install Node-Red nodes to support Homeassistant. The install is handled via the npm command within the Node-Red container.

I created both docker-compose.yaml and Dockerfile in a directory (file contents below).

To boot the container I use the command docker-compose up in the directory where the docker-compose.yaml file lives. I also made a systemd service that does the same thing without any issues.

My issue is that the DockerFile doesn't get processed when I run docker-compose up

Is there a way to have docker-compose pick up changes to DockerFile every time the container is started/restarted?

[docker-compose.yaml]

version: "3.6"
services:
  node-red:
    build: .
    container_name: node-red
    environment:
      TZ: /etc/localtime
    image: nodered/node-red
    restart: unless-stopped
    ports:
      - "1880:1880"
    volumes:
      - "/[folders]/node-red/data:/data"


[DockerFile]
FROM nodered/node-red

RUN npm install node-red-contrib-actionflows \
    # https://flows.nodered.org/node/node-red-contrib-actionflows
                            node-red-contrib-home-assistant-websocket \
    # https://flows.nodered.org/node/node-red-contrib-home-assistant-websocket
                            node-red-contrib-stoptimer \
    # https://flows.nodered.org/node/node-red-contrib-stoptimer
                            node-red-contrib-time-range-switch \
    # A simple Node-RED node that routes messages depending on the time. If the current time falls within the range specified in the node configuration, the message is routed to output 1. Otherwise the message is routed to output 2.
                            node-red-contrib-timecheck \
    # Is it that time yet? This node compares a given time to the current time.
                            node-red-node-timeswitch
    # node to provide a simple timeswitch node to schedule daily on/off events
2

I just did some quick testing and I believe you have two problems here, one is straightforward and the other is actually very subtle.


The first problem is that Compose does not automatically rebuild a service's image if the image already exists. When you run the service for the first time Compose will build the image using the dockerfile, but on subsequent runs it will just re-use the already existing image. The docs are actually frustratingly unclear on this, but the command output when running docker-compose up from your sample file is more helpful:

...
WARNING: Image for service node-red was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
...

I believe that in order to get the behavior you're looking for you should modify your systemd service to use the --build flag which will trigger a rebuild regardless of whether an image with the same tag exists or not.


The second problem I believe you're running into (this is also based on a quick test I ran using a modified version of the sample configs) is that you are overwriting your base image tag on each build.

According to the Compose file reference section on the build directive (third block down at this link) when both build and image are specified for a service, as yours are, docker will build the image according to the build directive and then tag it using the value of image directive. Because your image directive in the docker-compose file and the FROM directive in the dockerfile use the same tag you are telling Docker to tag your locally built image with the same name as the base image your dockerfile pulls from.

This means that each rebuild of the container (after the first build) will in fact be using the previous version of itself as the base container, rather than using the nodered/node-red from the upstream.

To fix this just change the value of the image directive in the compose file to something else; e.g. local-custom-node-red

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.