DockerFile und Docker-Compose (Homeassistant und Node-Red Nodes)

DockerFile und Docker-Compose (Homeassistant und Node-Red Nodes)

Ich hoffe, das ist einfach. Ich verwende Docker, um Homeassistant- und Node-Red-Container auf einem Raspberry Pi 4 auszuführen.

Bezogen aufdieser LeitfadenSie empfehlen, ein DockerFile zu erstellen, um Node-Red-Knoten zu installieren und Homeassistant zu unterstützen. Die Installation erfolgt über den npmBefehl im Node-Red-Container.

Ich habe beides erstellt docker-compose.yamlund Dockerfilein einem Verzeichnis(Dateiinhalt unten).

Um den Container zu booten, verwende ich den Befehl docker-compose upim Verzeichnis, in dem sich die docker-compose.yamlDatei befindet. Ich habe auch einen systemd-Dienst erstellt, der dasselbe ohne Probleme macht.

Mein Problem ist, dass die DockerFilenicht verarbeitet wird, wenn ichdocker-compose up

Gibt es eine Möglichkeit, docker-composeÄnderungen bei DockerFilejedem Starten/Neustart des Containers zu übernehmen?

[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

Antwort1

Ich habe gerade ein paar schnelle Tests durchgeführt und bin der Meinung, dass es hier zwei Probleme gibt. Das eine ist ganz offensichtlich, das andere ist eigentlich sehr subtil.


Das erste Problem besteht darin, dass Compose das Image eines Dienstes nicht automatisch neu erstellt, wenn das Image bereits vorhanden ist. Wenn Sie den Dienst zum ersten Mal ausführen, erstellt Compose das Image mithilfe der Docker-Datei, bei nachfolgenden Ausführungen wird jedoch einfach das bereits vorhandene Image erneut verwendet.Die Dokumentesind diesbezüglich tatsächlich frustrierend unklar, aber die Befehlsausgabe beim Ausführen docker-compose upaus Ihrer Beispieldatei ist hilfreicher:

...
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`.
...

Ich bin der Meinung, dass Sie, um das gewünschte Verhalten zu erzielen, Ihren systemd-Dienst so ändern sollten, dass er das --buildFlag verwendet, das einen Neuaufbau auslöst, unabhängig davon, ob ein Image mit demselben Tag vorhanden ist oder nicht.


Das zweite Problem, auf das Sie meiner Meinung nach stoßen (auch dies basiert auf einem kurzen Test, den ich mit einer geänderten Version der Beispielkonfigurationen durchgeführt habe), besteht darin, dass Sie Ihren Basis-Image-Tag bei jedem Build überschreiben.

Gemäß dem Abschnitt „Compose-Dateireferenz“ in der buildDirektive (dritter Block von oben beidieser Link) Wenn sowohl buildals auch imagefür einen Dienst angegeben sind, wie bei Ihnen, erstellt Docker das Image gemäß der Build-Direktive und markiert es dann mit dem Wert der Image-Direktive. Da Ihre imageDirektive in der Docker-Compose-Datei und die FROMDirektive im Dockerfile dasselbe Tag verwenden, weisen Sie Docker an, Ihr lokal erstelltes Image mit demselben Namen zu markieren wie das Basisimage, von dem Ihr Dockerfile zieht.

Dies bedeutet, dass bei jedem Neuaufbau des Containers (nach dem ersten Aufbau) tatsächlich die vorherige Version von sich selbst als Basiscontainer verwendet wird, anstatt die nodered/node-redaus dem Upstream.

Um dies zu beheben, ändern Sie einfach den Wert der imageDirektive in der Compose-Datei in etwas anderes; zBlocal-custom-node-red

verwandte Informationen