Search code examples
node-redinfrastructure-as-codegitops

How to run Node-Red on Docker with multiple environments with git


I'm running Node-Red on my server, and I want it to follow the deployment process like we are doing with code- working locally, making changes, commit and push.

Here is the list of the requirements:

  • Run Node-Red on Docker.
  • Track and backup tasks, configurations, all with Git
  • Ability to clone the repository and start Node-Red, without any configurations.
  • Make the changes on my local machine, and deploy them by pushing to Git.

To be more accurate, I need to add the flows.json, settings.json and package.json to the git.

And one of the main issues is when I'm adding a new package to the package.json, the NodeRed will not install it automaticlly.


Solution

  • The solution (workaround) I found is based on adding npm install to the docker entrypoint, how does it work?

    Mount to local folder

    First, we want to run the Node-Red, and mount its /data volume to our local folder:

    docker run -p 1880:1880 -v $(pwd)/node-red:/data nodered/node-red
    

    Now, if you're running from your local git repo, you will get a folder called node-red and it will include all the Node-Red workspace.

    Add Node-Red data to Git

    To track only the Node-Red configuration files, you need to add the next entries to your .gitignore file:

    node-red/*
    !node-red/package.json
    !node-red/package-lock.json
    !node-red/flows.json
    !node-red/flows_cred.json
    !node-red/settings.js
    

    All the other files are auto-generated.

    Install the missing packages on startup

    Now, the hard part. If you added a new library in your local environment, and you pushed the changes, you want Node-Red to install the new library before it starts.

    We will take the original Node-Red start command from Node-Red Dockerfile:

    npm --no-update-notifier --no-fund start --cache /data/.npm -- --userDir /data
    

    And before this command, we will take the npm install command suggested for a custom docker:

    npm install --unsafe-perm --no-update-notifier --no-fund --only=production
    

    Here is my final docker-compose.yml file, which includes a docker run commandline to run only this image in the development environment:

    node-red:
      # port 1880
      # Dev: docker run -p 1880:1880 -v $(pwd)/node-red:/data --entrypoint="" --env-file .env nodered/node-red /bin/sh -c "npm install --prefix /data --unsafe-perm --no-update-notifier --no-fund --only=production && npm --no-update-notifier --no-fund start --cache /data/.npm -- --userDir /data"
      image: nodered/node-red
      env_file:
        - shared.env
      network_mode: host
      entrypoint: >
        sh -c "
        npm install --prefix /data --unsafe-perm --no-update-notifier --no-fund --only=production
        && npm --no-update-notifier --no-fund start --cache /data/.npm -- --userDir /data"
      environment:
        NODE_RED_CREDENTIAL_SECRET: ${NODE_RED_CREDENTIAL_SECRET}
      volumes:
        - ./node-red:/data
      restart: unless-stopped