From e1c313bbfe51286a6e64a9bbd042db02d01138d7 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Thu, 15 Oct 2020 11:32:38 +0100 Subject: [PATCH] Pull latest Readme changes across from dev (#204) --- README.md | 160 ++++++++++++++++++++++++----------------------- volumechanges.md | 67 ++++++++++++++++++++ 2 files changed, 148 insertions(+), 79 deletions(-) create mode 100644 volumechanges.md diff --git a/README.md b/README.md index 84ba611c..c986601b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ This project describes some of the many ways Node-RED can be run under Docker and has support for multiple architectures (amd64, arm32v6, arm32v7, arm64v8, i386 and s390x). Some basic familiarity with Docker and the [Docker Command Line](https://docs.docker.com/engine/reference/commandline/cli/) is assumed. +**Note**: In version 1.2 we removed the named VOLUME from the build. It should not affect many users - but the details are [here](volumechanges). + As of Node-RED 1.0 this project provides the build for the `nodered/node-red` container on [Docker Hub](https://hub.docker.com/r/nodered/node-red/). Previous 0.20.x versions are still available at https://hub.docker.com/r/nodered/node-red-docker. @@ -24,7 +26,7 @@ Let's dissect that command: -p 1880:1880 - connect local port 1880 to the exposed internal port 1880 -v node_red_data:/data - mount the host node_red_data directory to the container /data directory so any changes made to flows are persisted --name mynodered - give this machine a friendly local name - nodered/node-red - the image to base it on - currently Node-RED v1.1.3 + nodered/node-red - the image to base it on - currently Node-RED v1.2.0 Running that command should give a terminal window with a running instance of Node-RED. @@ -32,17 +34,17 @@ Running that command should give a terminal window with a running instance of No Welcome to Node-RED =================== - 10 Jul 12:57:10 - [info] Node-RED version: v1.1.3 - 10 Jul 12:57:10 - [info] Node.js version: v10.21.0 - 10 Jul 12:57:10 - [info] Linux 4.9.184-linuxkit x64 LE - 10 Jul 12:57:11 - [info] Loading palette nodes - 10 Jul 12:57:16 - [info] Settings file : /data/settings.js - 10 Jul 12:57:16 - [info] Context store : 'default' [module=memory] - 10 Jul 12:57:16 - [info] User directory : /data - 10 Jul 12:57:16 - [warn] Projects disabled : editorTheme.projects.enabled=false - 10 Jul 12:57:16 - [info] Flows file : /data/flows.json - 10 Jul 12:57:16 - [info] Creating new flow file - 10 Jul 12:57:17 - [warn] + 10 Oct 12:57:10 - [info] Node-RED version: v1.2.0 + 10 Oct 12:57:10 - [info] Node.js version: v10.22.1 + 10 Oct 12:57:10 - [info] Linux 4.19.76-linuxkit x64 LE + 10 Oct 12:57:11 - [info] Loading palette nodes + 10 Oct 12:57:16 - [info] Settings file : /data/settings.js + 10 Oct 12:57:16 - [info] Context store : 'default' [module=memory] + 10 Oct 12:57:16 - [info] User directory : /data + 10 Oct 12:57:16 - [warn] Projects disabled : editorTheme.projects.enabled=false + 10 Oct 12:57:16 - [info] Flows file : /data/flows.json + 10 Oct 12:57:16 - [info] Creating new flow file + 10 Oct 12:57:17 - [warn] --------------------------------------------------------------------- Your flow credentials file is encrypted using a system-generated key. @@ -56,9 +58,9 @@ Running that command should give a terminal window with a running instance of No file using your chosen key the next time you deploy a change. --------------------------------------------------------------------- - 10 Jul 12:57:17 - [info] Starting flows - 10 Jul 12:57:17 - [info] Started flows - 10 Jul 12:57:17 - [info] Server now running at http://127.0.0.1:1880/ + 10 Oct 12:57:17 - [info] Starting flows + 10 Oct 12:57:17 - [info] Started flows + 10 Oct 12:57:17 - [info] Server now running at http://127.0.0.1:1880/ [...] @@ -112,36 +114,36 @@ The following table shows the variety of provided Node-RED images. | **Tag** |**Node**| **Arch** | **Python** |**Dev**| **Base Image** | |----------------------------|--------|----------|------------|-------|------------------------| -| 1.1.3-10-amd64 | 10 | amd64 | 2.x 3.x | yes | amd64/node:10-alpine | -| 1.1.3-10-arm32v6 | 10 | arm32v6 | 2.x 3.x | yes | arm32v6/node:10-alpine | -| 1.1.3-10-arm32v7 | 10 | arm32v7 | 2.x 3.x | yes | arm32v7/node:10-alpine | -| 1.1.3-10-arm64v8 | 10 | arm64v8 | 2.x 3.x | yes | arm64v8/node:10-alpine | -| 1.1.3-10-s390x | 10 | s390x | 2.x 3.x | yes | s390x/node:10-alpine | -| 1.1.3-10-i386 | 10 | i386 | 2.x 3.x | yes | i386/node:10-alpine | +| 1.2.0-10-amd64 | 10 | amd64 | 2.x 3.x | yes | amd64/node:10-alpine | +| 1.2.0-10-arm32v6 | 10 | arm32v6 | 2.x 3.x | yes | arm32v6/node:10-alpine | +| 1.2.0-10-arm32v7 | 10 | arm32v7 | 2.x 3.x | yes | arm32v7/node:10-alpine | +| 1.2.0-10-arm64v8 | 10 | arm64v8 | 2.x 3.x | yes | arm64v8/node:10-alpine | +| 1.2.0-10-s390x | 10 | s390x | 2.x 3.x | yes | s390x/node:10-alpine | +| 1.2.0-10-i386 | 10 | i386 | 2.x 3.x | yes | i386/node:10-alpine | | | | | | | | -| 1.1.3-10-minimal-amd64 | 10 | amd64 | no | no | amd64/node:10-alpine | -| 1.1.3-10-minimal-arm32v6 | 10 | arm32v6 | no | no | arm32v6/node:10-alpine | -| 1.1.3-10-minimal-arm32v7 | 10 | arm32v7 | no | no | arm32v7/node:10-alpine | -| 1.1.3-10-minimal-arm64v8 | 10 | arm64v8 | no | no | arm64v8/node:10-alpine | -| 1.1.3-10-minimal-s390x | 10 | s390x | no | no | s390x/node:10-alpine | -| 1.1.3-10-minimal-i386 | 10 | i386 | no | no | i386/node:10-alpine | +| 1.2.0-10-minimal-amd64 | 10 | amd64 | no | no | amd64/node:10-alpine | +| 1.2.0-10-minimal-arm32v6 | 10 | arm32v6 | no | no | arm32v6/node:10-alpine | +| 1.2.0-10-minimal-arm32v7 | 10 | arm32v7 | no | no | arm32v7/node:10-alpine | +| 1.2.0-10-minimal-arm64v8 | 10 | arm64v8 | no | no | arm64v8/node:10-alpine | +| 1.2.0-10-minimal-s390x | 10 | s390x | no | no | s390x/node:10-alpine | +| 1.2.0-10-minimal-i386 | 10 | i386 | no | no | i386/node:10-alpine | | **Tag** |**Node**| **Arch** | **Python** |**Dev**| **Base Image** | |----------------------------|--------|----------|------------|-------|------------------------| -| 1.1.3-12-amd64 | 12 | amd64 | 2.x 3.x | yes | amd64/node:12-alpine | -| 1.1.3-12-arm32v6 | 12 | arm32v6 | 2.x 3.x | yes | arm32v6/node:12-alpine | -| 1.1.3-12-arm32v7 | 12 | arm32v7 | 2.x 3.x | yes | arm32v7/node:12-alpine | -| 1.1.3-12-arm64v8 | 12 | arm64v8 | 2.x 3.x | yes | arm64v8/node:12-alpine | -| 1.1.3-12-s390x | 12 | s390x | 2.x 3.x | yes | s390x/node:12-alpine | -| 1.1.3-12-i386 | 12 | i386 | 2.x 3.x | yes | i386/node:12-alpine | +| 1.2.0-12-amd64 | 12 | amd64 | 2.x 3.x | yes | amd64/node:12-alpine | +| 1.2.0-12-arm32v6 | 12 | arm32v6 | 2.x 3.x | yes | arm32v6/node:12-alpine | +| 1.2.0-12-arm32v7 | 12 | arm32v7 | 2.x 3.x | yes | arm32v7/node:12-alpine | +| 1.2.0-12-arm64v8 | 12 | arm64v8 | 2.x 3.x | yes | arm64v8/node:12-alpine | +| 1.2.0-12-s390x | 12 | s390x | 2.x 3.x | yes | s390x/node:12-alpine | +| 1.2.0-12-i386 | 12 | i386 | 2.x 3.x | yes | i386/node:12-alpine | | | | | | | | -| 1.1.3-12-minimal-amd64 | 12 | amd64 | no | no | amd64/node:12-alpine | -| 1.1.3-12-minimal-arm32v6 | 12 | arm32v6 | no | no | arm32v6/node:12-alpine | -| 1.1.3-12-minimal-arm32v7 | 12 | arm32v7 | no | no | arm32v7/node:12-alpine | -| 1.1.3-12-minimal-arm64v8 | 12 | arm64v8 | no | no | arm64v8/node:12-alpine | -| 1.1.3-12-minimal-s390x | 12 | s390x | no | no | s390x/node:12-alpine | -| 1.1.3-12-minimal-i386 | 12 | i386 | no | no | i386/node:12-alpine | +| 1.2.0-12-minimal-amd64 | 12 | amd64 | no | no | amd64/node:12-alpine | +| 1.2.0-12-minimal-arm32v6 | 12 | arm32v6 | no | no | arm32v6/node:12-alpine | +| 1.2.0-12-minimal-arm32v7 | 12 | arm32v7 | no | no | arm32v7/node:12-alpine | +| 1.2.0-12-minimal-arm64v8 | 12 | arm64v8 | no | no | arm64v8/node:12-alpine | +| 1.2.0-12-minimal-s390x | 12 | s390x | no | no | s390x/node:12-alpine | +| 1.2.0-12-minimal-i386 | 12 | i386 | no | no | i386/node:12-alpine | - All images have bash, tzdata, nano, curl, git, openssl and openssh-client pre-installed to support Node-RED's Projects feature. @@ -150,53 +152,53 @@ The following table shows the provided Manifest Lists. | **Tag** | **Node-RED Base Image** | |----------------------------------------|--------------------------------------------| -| latest, 1.1.3, | nodered/node-red:1.1.3-10-amd64 | -| latest-10, 1.1.3-10 | nodered/node-red:1.1.3-10-arm32v6 | -| | nodered/node-red:1.1.3-10-arm32v7 | -| | nodered/node-red:1.1.3-10-arm64v8 | -| | nodered/node-red:1.1.3-10-s390x | -| | nodered/node-red:1.1.3-10-i386 | +| latest, 1.2.0, | nodered/node-red:1.2.0-10-amd64 | +| latest-10, 1.2.0-10 | nodered/node-red:1.2.0-10-arm32v6 | +| | nodered/node-red:1.2.0-10-arm32v7 | +| | nodered/node-red:1.2.0-10-arm64v8 | +| | nodered/node-red:1.2.0-10-s390x | +| | nodered/node-red:1.2.0-10-i386 | | | | -| latest-minimal, 1.1.3-minimal, | nodered/node-red:1.1.3-10-amd64-minimal | -| latest-10-minimal, 1.1.3-10-minimal | nodered/node-red:1.1.3-10-arm32v6-minimal | -| | nodered/node-red:1.1.3-10-arm32v7-minimal | -| | nodered/node-red:1.1.3-10-arm64v8-minimal | -| | nodered/node-red:1.1.3-10-s390x-minimal | -| | nodered/node-red:1.1.3-10-i386-minimal | +| latest-minimal, 1.2.0-minimal, | nodered/node-red:1.2.0-10-amd64-minimal | +| latest-10-minimal, 1.2.0-10-minimal | nodered/node-red:1.2.0-10-arm32v6-minimal | +| | nodered/node-red:1.2.0-10-arm32v7-minimal | +| | nodered/node-red:1.2.0-10-arm64v8-minimal | +| | nodered/node-red:1.2.0-10-s390x-minimal | +| | nodered/node-red:1.2.0-10-i386-minimal | | **Tag** | **Node-RED Base Image** | |----------------------------------------|--------------------------------------------| -| latest-12, 1.1.3-12 | nodered/node-red:1.1.3-12-amd64 | -| | nodered/node-red:1.1.3-12-arm32v6 | -| | nodered/node-red:1.1.3-12-arm32v7 | -| | nodered/node-red:1.1.3-12-arm64v8 | -| | nodered/node-red:1.1.3-12-s390x | -| | nodered/node-red:1.1.3-12-i386 | +| latest-12, 1.2.0-12 | nodered/node-red:1.2.0-12-amd64 | +| | nodered/node-red:1.2.0-12-arm32v6 | +| | nodered/node-red:1.2.0-12-arm32v7 | +| | nodered/node-red:1.2.0-12-arm64v8 | +| | nodered/node-red:1.2.0-12-s390x | +| | nodered/node-red:1.2.0-12-i386 | | | | -| latest-12-minimal, 1.1.3-12-minimal | nodered/node-red:1.1.3-12-amd64-minimal | -| | nodered/node-red:1.1.3-12-arm32v6-minimal | -| | nodered/node-red:1.1.3-12-arm32v7-minimal | -| | nodered/node-red:1.1.3-12-arm64v8-minimal | -| | nodered/node-red:1.1.3-12-s390x-minimal | -| | nodered/node-red:1.1.3-12-i386-minimal | +| latest-12-minimal, 1.2.0-12-minimal | nodered/node-red:1.2.0-12-amd64-minimal | +| | nodered/node-red:1.2.0-12-arm32v6-minimal | +| | nodered/node-red:1.2.0-12-arm32v7-minimal | +| | nodered/node-red:1.2.0-12-arm64v8-minimal | +| | nodered/node-red:1.2.0-12-s390x-minimal | +| | nodered/node-red:1.2.0-12-i386-minimal | With the support of Docker manifest list, there is no need to explicitly add the tag for the architecture to use. When a docker run command or docker service command or docker stack command is executed, docker checks which architecture is required and verifies if it is available in the docker repository. If it does, docker pulls the matching image for it. Therefore all tags regarding Raspberry PI's are dropped. -For example: suppose you are running on a Raspberry PI 3B, which has `arm32v7` as architecture. Then just run the following command to pull the image (tagged by `1.1.3-10-arm32v7`), and run the container. +For example: suppose you are running on a Raspberry PI 3B, which has `arm32v7` as architecture. Then just run the following command to pull the image (tagged by `1.2.0-10-arm32v7`), and run the container. ``` docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red:latest ``` -The same command can be used for running on an amd64 system, since docker discovers its running on a amd64 host and pulls the image with the matching tag (`1.1.3-10-amd64`). +The same command can be used for running on an amd64 system, since docker discovers its running on a amd64 host and pulls the image with the matching tag (`1.2.0-10-amd64`). This gives the advantage that you don't need to know/specify which architecture you are running on and makes docker run commands and docker compose files more flexible and exchangeable across systems. **Note**: Currently there is a bug in Docker's architecture detection that fails for `arm32v6` - eg Raspberry Pi Zero or 1. For these devices you currently need to specify the full image tag, for example: ``` -docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red:1.1.3-10-minimal-arm32v6 +docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered nodered/node-red:1.2.0-10-minimal-arm32v6 ``` @@ -330,7 +332,7 @@ Docker build process, the dependencies are installed under `/usr/src/node-red`. The main sections to modify are "dependencies": { - "node-red": "^1.1.3", <-- set the version of Node-RED here + "node-red": "^1.2.0", <-- set the version of Node-RED here "node-red-dashboard": "*" <-- add any extra npm packages here }, @@ -384,11 +386,11 @@ This tool assumes Node-RED is available at the following address Refreshing the browser page should now reveal the newly added node in the palette. -### Node-RED Commands from the host +### Node-RED Commands from the host Admin commands can also be accessed without installing npm or the node-red-admin tool on the host machine. Simply prepend your command -with "npx" and apply it to the container - e.g +with "npx" and apply it to the container - e.g $ docker exec -it mynodered npx node-red admin hash-pw @@ -461,7 +463,7 @@ Then run nodered docker, also added to the same bridge docker run -itd -p 1880:1880 --network iot --name mynodered nodered/node-red -containers on the same user-defined bridge can take advantage of the built in name resolution provided by the bridge and use the container name (specified using the **--name** option) as the target hostname. +containers on the same user-defined bridge can take advantage of the built in name resolution provided by the bridge and use the container name (specified using the **--name** option) as the target hostname. In the above example the broker can be reached from the Node-RED application using hostname *mybroker*. @@ -520,7 +522,7 @@ Let's dissect both commands: -it - attach a terminal session so we can see what is going on -p 1880:1880 - connect local port 1880 to the exposed internal port 1880 -p 9229:9229 - connect local port 9229 to the exposed internal port 9229 (for debugger communication) - -v node_red_data:/data - mount the internal /data to the host mode_red_data directory + -v node_red_data:/data - mount the internal /data to the host mode_red_data directory --name mynodered - give this machine a friendly local name --entrypoint npm - overwrite the default entrypoint (which would run the *'start'* script) nodered/node-red - the image to base it on - currently Node-RED v1.1.0 @@ -530,7 +532,7 @@ Let's dissect both commands: ## Common Issues and Hints -Here is a list of common issues users have reported with possible solutions. +Here is a list of common issues users have reported with possible solutions.
@@ -545,11 +547,11 @@ If you are seeing *permission denied* errors opening files or accessing host dev docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered -u root nodered/node-red ``` -__References:__ +__References:__ -https://github.com/node-red/node-red/issues/15 +https://github.com/node-red/node-red/issues/15 -https://github.com/node-red/node-red/issues/8 +https://github.com/node-red/node-red/issues/8
@@ -560,9 +562,9 @@ If you want to access a device from the host inside the container, e.g. serial p ``` docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered --device=/dev/ttyACM0 nodered/node-red ``` -__References:__ +__References:__ -https://github.com/node-red/node-red/issues/15 +https://github.com/node-red/node-red/issues/15
@@ -574,8 +576,8 @@ If you want to modify the default timezone, use the TZ environment variable with docker run -it -p 1880:1880 -v node_red_data:/data --name mynodered -e TZ=Europe/London nodered/node-red ``` -__References:__ +__References:__ -https://groups.google.com/forum/#!topic/node-red/ieo5IVFAo2o +https://groups.google.com/forum/#!topic/node-red/ieo5IVFAo2o
diff --git a/volumechanges.md b/volumechanges.md new file mode 100644 index 00000000..62ad882a --- /dev/null +++ b/volumechanges.md @@ -0,0 +1,67 @@ +## Resolution for issue #197 _"docker image always creates a /data volume"_ + +### Introduction + +This page describes the resolution of issue [#197 docker image always creates a /data volume](https://github.com/node-red/node-red-docker/issues/197) and potential impact. It must be noted that most of us won't see any impact and that the new Node-RED docker images with respect to docker volumes will behave as expected. + +### Change = removal of line: "`VOLUME [/data]`" + +The Node-RED docker images at [nodered/node-red](https://hub.docker.com/r/nodered/node-red/) up to Node-RED version 1.1.3 contained the following line: + +``` +VOLUME [/data] +```` + +This single line is now removed in recently published docker images (starting from Node-RED version 1.2.0). + +### Impact of the line "`VOLUME [/data]`" + +See also [documentation for `VOLUME` instruction in dockerfile reference](https://docs.docker.com/engine/reference/builder/#volume) + +When a docker container is created without explicitly specifying a docker volume for `/data` folder then this line assures that a docker volume is automatically created and that the contents of the `/data` folder from the base image are copied to this automatically created volume. + +Note that removing the container, will not automatically remove this volume ! So you need to explicitly remove this volume if you no longer need it - which is not that easy as this anonymous volume has a randomly generated name like "`76cc15fa0b6184c7ce6a2a4b865cdf2cd7d62661256e8ba2b5a4dff2d30da1e4`". + +#### Unexpected behaviour when used with `docker-compose` + +This section explains unexpected behaviour when using docker images containing also the flows based on old Node-RED docker images (v1.1.3 and earlier) in combination with docker-compose. + +The problem scenario: + +1. Someone creates a docker image `Img:1.0.0` which contains the Node-RED flow `Flow_1.0.0` +2. You have created a docker-compose file defining a service using this `Img:1.0.0` +3. The command "`docker-compose up`" will properly start this service and the very first time will create an anonymous volume that is mounted to the `/data` folder where the flow `Flow_1.0.0` is copied to. +4. Someone updates the docker image (= `Img:2.0.0`) which now contains the updated Node-RED flows `Flow_2.0.0`. +5. You want to use the new version of the image, so You run first the `docker-compose pull` command. Which will correctly download image `Img:2.0.0` +6. then you run command "`docker-compose up`" to deploy the new version but this will indeed deploy the new version of the image but it won't create a new volume: it will still use the same volume created in step 3. This also means that it will NOT copy flow `FLow_2.0.0` from the image to the mounted volume and consequently it will still use the old flow `Flow_1.0.0` instead of the new flow `Flow_2.0.0` + +So in order to avoid this problem you must explicitly remove the "anonymous volume" before executing step 6. + +FYI it is especially the "`(preserving mounted volumes)`" in the following paragraph of [docker-compose up documentation](https://docs.docker.com/compose/reference/up/) that explains why we have this problem with docker-compose. + +``` +If there are existing containers for a service, and the service’s configuration or image was changed after the container’s creation, docker-compose up picks up the changes by stopping and recreating the containers (preserving mounted volumes). +``` + +# Should I care about this change ? + +### A. I have explicitly specified a volume to be mounted to /data. + +In case you have explicitly defined a volume to be mounted to the "`/data`" folder when creating the container then nothing changes for you. Everything will work exactly as before. When upgrading to a new docker image without the "`VOLUME [/data]`" it will still use the latest flows you have saved just before the upgrade. + +### B. I didn't explicitly specify a volume to be mounted to /data. + +It still means that the file changes saved in the "`/data`" folder when using new Node-RED docker image (= image without the "`VOLUME [/data]`") are not lost when stopping and starting the container or rebooting the docker host machine ! They are persisted in the container writeable layer and will be kept as long as the container is not removed. + +So when using the standard docker commands to start/stop/run/remove/create containers everything will work as before. Moreover with new Node-RED docker images you no longer need to cleanup those anonymous volumes when removing the container. + +#### **ATTENTION**: I am using `docker-compose` and have not explicitly specified a volume to be mounted to /data + +So when upgrading a service to use a new Node-RED docker image (= image without the "`VOLUME [/data]`") using the "`docker-compose up`" command you will notice that the anonymous volume is still mounted to the `/data` folder as the "`docker-compose up`" command is preserving mounted volumes. This might be a good thing in case you still want to use the flows you have saved before the upgrade. +... but this might also be an undesired thing, in case you want to use the flows in the "`/data`" folders of the new docker image. The fix for this is easy. You first have to remove the respective docker container and only then run the "`docker-compose up`" command as this command will now rebuild the container without mounting any volume. + +When upgrading from one image to another image and both images are based on a recent Node-RED docker image (= image without the "`VOLUME [/data]`") AND there was no preserved mount of the `/data` folder then the `/data` folder is completely replaced by the `/data` folder of the new image ! + +## Support + +If you are still stuck or need more support then we recommend to open a topic in the [Node-RED forum](https://discourse.nodered.org/) for this. \ No newline at end of file