Table of Contents
Note: Added a branch runnable-project
to experiment - https://github.com/node-red/node-red/tree/runnable-project. Currently works as described below... but maybe not final design choices.
One of the goals of the Projects feature is to treat a project as a deployable artefact.
It should be possible to deploy a project without using the editor. For example:
1. git clone https://example.com/my-node-red-project.git
2. cd my-node-red-project
3. npm install
4. npm start -- --credentialSecret="my-secret-key"
Missing pieces
We can't quite do this today. Here are the missing pieces:
- the project's
package.json
needs to listnode-red
as a dependency. On balance, I think this is the right approach, rather than treat node-red as an assumed prerequisite. I don't think we should do this be default; maybe add a checkbox in the project settings' dependencies page to includenode-red
.
DCJ: Yes - agree it should be a dependency. Currently not hard to add manually, but could be even easier. It would be a prerequisite dependency for inside a Docker container.
DCJ: Added a button to dependencies panel to add node-red core - As it's not "known" it shows as greyed in the list- but I actually think this is good, as it indicates it may not be required also.
NOL: Not sure a standalone button passes the "why is it there?" test.
- it must be possible to point node-red at a project on start-up, without using the editor to do so. Currently we overload the flowFile argument to set the active project - but that only works if the project is 'known'. It would be better to point at a
projectDir
wherever it may exist.
DCJ: Are we pointing Node-RED or npm start ? Which are we calling to run it ? If npm start then don't we already have to be in the correct project directory ? (or use npm start --prefix projectDir)
DCJ: Having played with it a while - I think
npm start
from within the relevant directory is the way to go to start with.
- it must be possible to provide the credentialSecret for the project without it being part of any of the version controlled files. Options for this include:
- env var -
NODE_RED_CREDENTIAL_SECRET
- [DCJ] easy to add to settings.js -
credentialSecret: process.env.NODE_RED_CREDENTIAL_SECRET
and would suit Docker style deploy.
- [DCJ] easy to add to settings.js -
- command-line flag -
--credentialSecret="..."
- [DCJ] added as new command line option to runnable-project dev branch
- env var -
DCJ/NOL: a) If environment variable works do we need command line option ? When would you use it? b) should using env var be baked into core or just via settings file so can be removed if required.
- Must handle running in a read-only environment. If the package is installed globally (in order to insert a command link into /usr/bin) then the flow file and settings.js will be in root space - which ought not to be writable by the user. Currently even starting Node-RED with -u option pointing somewhere protected will fail. Options include
- just handling the error - i.e. log something (useful) - but fail to start.
- on detecting this condition, marking the settings.readOnly as true thus stopping the library failing - but run.
- setting disableEditor to
true
also.
The package would provide an npm start script that runs node-red with the appropriate command-line args.
DCJ: currently just using
node-red -u . flow.json
- i.e. start Node-RED using the current directory as the base and the current flow file.
NOL: instead should it use (say) a -p option to specify a package.json file to use instead to read the extra settings from (like flow file etc)
It could also provide a bin
section that could allow starting via command line if installed globally - but that requires a command to be run (that doesn't take parameters) so in order to do that we would also need to create that script/.js file or provide a template.
DCJ: Actually by pre-req node-red it automatically adds the node-red command to the node_modules/.bin so the package.json start script can just call
node-red
and all is good.
Runtime settings
When deploying the project, there will also be a need to have the runtime settings provided. These are not normally part of a project generated by Node-RED. The question is whether we have some tooling support to generate, or we just document how to do it. For example, the user would manually add a settings.js
file to their project repo.
DCJ: If we have the "add node-red as a dependency" button - could it not also have a ... "copy default settings.js into project" button or create a minimal settings.js (i.e. without defaults and comments) ? (but ensuring flowFile doesn't clash) e.g.
module.exports = {
uiPort: process.env.PORT || 1880,
credentialSecret: process.env.NODE_RED_CREDENTIAL_SECRET
}
Dockerfile
We should also have an example Dockerfile that can be used to build and run a project.
DCJ: Here is an example Dockerfile.template that works with various flavours of Docker - note that the flow file is set using the start command in package.json, and it needs node red as a dependency)
"scripts": {"start": "node-red -u . flow.json"},
# Expects -e NODE_RED_CREDENTIAL_SECRET="my_secret_key" to be part of the docker run command at start time
# and settings.js to exist as per above
#
# Note the node:slim image doesn't have node-gyp
## Uncomment one of the following FROM lines to suit your environment
# For generic servers
#FROM node:8-slim
# For Pi...
FROM arm32v7/node:8-slim
# For Resin.io
#FROM resin/%%RESIN_MACHINE_NAME%%-node:8-slim
# Uncomment the next three lines if you want GPIO for Pi
#RUN apt-get update && apt-get install -yq \
# rpi.gpio && \
# apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
COPY package.json package.json
RUN JOBS=MAX npm install --production --unsafe-perm --no-optional && npm cache clean --force && rm -rf /tmp/*
COPY . ./
# required for Resin.io
ENV INITSYSTEM on
# useful for pigpiod node to be able to talk to daemon on host.
ENV HOST_IP=172.17.0.1
ENV NODE_PATH=/usr/src/app/node_modules
EXPOSE 1880
CMD ["npm", "start"]
A really minimal Dockerfile to build an image (but not run) could be as simple as
FROM node:8-onbuild
VOLUME /root/.node-red
EXPOSE 1880