Node-RED Project Deployment Guide¶
Overview¶
This guide explains how to deploy Node-RED flows from the separate gaisro-technika-nodered Git repository to your Raspberry Pi fleet using Ansible.
Architecture¶
The deployment system supports two modes:
- Git-based deployment (recommended): Deploys Node-RED project directly from the Git repository
- Local file copy (fallback): Copies local Node-RED files from
node-red/directory
Quick Start¶
Deploy Node-RED Project to All Devices¶
# Deploy from main branch (default)
cd ansible
ansible-playbook playbooks/deploy-nodered-project.yml
# Deploy specific version/tag
ansible-playbook playbooks/deploy-nodered-project.yml \
--extra-vars "node_red_project_version=v1.0.0"
# Deploy to specific device
ansible-playbook playbooks/deploy-nodered-project.yml --limit rpi-prod-1883c404a12f
# Deploy to multiple devices
ansible-playbook playbooks/deploy-nodered-project.yml --limit rpi-prod-1883c404a12f,rpi-staging-1883c404a130,rpi-dev-1883c4049f6c
Deploy via Taskfile (Recommended)¶
# From project root
task ansible:deploy-nodered-project
# Deploy to specific device
task ansible:deploy-nodered-project LIMIT=rpi-prod-1883c404a12f
# Deploy specific version
task ansible:deploy-nodered-project VERSION=v1.0.0
Configuration¶
Repository Settings¶
Configuration is in ansible/group_vars/nodered.yml:
# Enable Git-based deployment
node_red_project_enabled: true
# Repository URL
node_red_project_repo: "https://github.com/mbTagai/gaisro-technika-nodered.git"
# Branch, tag, or commit hash
node_red_project_version: "main"
# Installation path on devices
node_red_project_path: "/home/tagai/.node-red"
Override Per Environment¶
Create environment-specific configurations:
# ansible/group_vars/production.yml
node_red_project_version: "v1.2.3" # Use stable release
# ansible/group_vars/staging.yml
node_red_project_version: "develop" # Use development branch
# ansible/group_vars/development.yml
node_red_project_version: "feature/new-mqtt-nodes" # Use feature branch
Deployment Process¶
What Happens During Deployment¶
- Pre-deployment checks
- Validates Git repository configuration
-
Checks device connectivity
-
Backup existing flows
-
Creates timestamped backup:
flows.json.backup.{timestamp} -
Deploy from Git
- Clones/updates repository to device
- Sets correct file ownership
-
Installs npm dependencies (if package.json changed)
-
Restart Node-RED
- Gracefully restarts Node-RED service
-
Waits for health check (up to 60 seconds)
-
Batch processing
- Deploys to devices in batches (default: 10 devices)
- Pauses 30 seconds between batches
- Stops if >10% of devices fail
Rollback¶
If deployment fails, restore from backup:
# SSH into device
ssh tagai@rpi-prod-1883c404a12f.tagai.uk
# Stop Node-RED
sudo systemctl stop nodered
# Restore backup (use latest timestamp)
cd ~/.node-red
cp flows.json.backup.1738000000 flows.json
# Restart Node-RED
sudo systemctl start nodered
Repository Structure¶
Your gaisro-technika-nodered repository should contain:
gaisro-technika-nodered/
├── flows.json # Node-RED flows
├── flows_cred.json # Credentials (encrypted)
├── package.json # Node-RED project metadata & dependencies
├── settings.js # (optional) Node-RED settings
└── README.md
Important: The flows_cred.json file contains encrypted credentials. Ensure it's properly encrypted by Node-RED before committing.
Working with Versions¶
Deploy Stable Releases¶
# Tag a release in gaisro-technika-nodered repo
git tag v1.0.0
git push origin v1.0.0
# Deploy to production
ansible-playbook playbooks/deploy-nodered-project.yml \
--extra-vars "node_red_project_version=v1.0.0" \
--limit production
Deploy from Feature Branch¶
# Deploy feature branch to development devices
ansible-playbook playbooks/deploy-nodered-project.yml \
--extra-vars "node_red_project_version=feature/mqtt-improvements" \
--limit rpi-dev-1883c4049f6c,rpi-dev-1883c404a12f
Deploy Specific Commit¶
# Deploy specific commit hash
ansible-playbook playbooks/deploy-nodered-project.yml \
--extra-vars "node_red_project_version=a1b2c3d4"
Deployment Strategies¶
Rolling Deployment (Default)¶
Deploys to devices in batches with pauses:
ansible-playbook playbooks/deploy-nodered-project.yml
- Batch size: 10 devices
- Pause: 30 seconds between batches
- Max failures: 10%
All-at-Once Deployment¶
Deploy to all devices simultaneously (use with caution):
ansible-playbook playbooks/deploy-nodered-project.yml \
--extra-vars "update_batch_size=100"
Canary Deployment¶
Test on one device first:
# Deploy to canary device
ansible-playbook playbooks/deploy-nodered-project.yml --limit rpi-prod-1883c404a12f
# Verify it works
# Then deploy to rest of fleet
ansible-playbook playbooks/deploy-nodered-project.yml --limit '!rpi-prod-1883c404a12f'
Full Stack Deployment¶
To deploy entire infrastructure including Node-RED project:
# Deploy everything (prerequisites, cloudflared, node-red with project, mqtt)
ansible-playbook playbooks/site.yml
# Deploy with specific Node-RED version
ansible-playbook playbooks/site.yml \
--extra-vars "node_red_project_version=v1.0.0"
Troubleshooting¶
Check Deployment Status¶
# View Node-RED logs on device
ssh tagai@rpi-prod-1883c404a12f.tagai.uk
sudo journalctl -u nodered -f
# Check Node-RED status
sudo systemctl status nodered
# View Node-RED flows
cat ~/.node-red/flows.json | jq .
Common Issues¶
Git Clone Fails¶
Symptom: fatal: could not read Username for 'https://github.com'
Solution: If using private repository, configure Git credentials:
# ansible/group_vars/nodered.yml
node_red_project_repo: "https://{{ github_token }}@github.com/mbTagai/gaisro-technika-nodered.git"
Store github_token in Ansible Vault:
ansible-vault edit group_vars/all.yml
# Add: github_token: "ghp_yourtoken"
NPM Install Fails¶
Symptom: npm ERR! missing script: install
Solution: Check package.json exists and is valid:
# On device
cd ~/.node-red
cat package.json
npm install --verbose
Node-RED Won't Start¶
Symptom: Health check timeout
Solution: Check Node-RED logs:
ssh tagai@rpi-prod-1883c404a12f.tagai.uk
sudo journalctl -u nodered -n 50
Common causes: - Syntax error in flows.json - Missing npm dependencies - Port 1880 already in use - Invalid credentials in flows_cred.json
Debug Mode¶
Run playbook with verbose output:
ansible-playbook playbooks/deploy-nodered-project.yml -vvv
CI/CD Integration¶
GitHub Actions Example¶
Create .github/workflows/deploy-nodered.yml in infrastructure repo:
name: Deploy Node-RED to Fleet
on:
repository_dispatch:
types: [deploy-nodered]
workflow_dispatch:
inputs:
version:
description: 'Version to deploy (branch/tag/commit)'
required: true
default: 'main'
environment:
description: 'Target environment'
required: true
type: choice
options:
- development
- staging
- production
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Ansible
run: |
pip install ansible
- name: Deploy Node-RED Project
run: |
cd ansible
ansible-playbook playbooks/deploy-nodered-project.yml \
--limit ${{ inputs.environment }} \
--extra-vars "node_red_project_version=${{ inputs.version }}"
env:
ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }}
Trigger from Node-RED Repo¶
In gaisro-technika-nodered repository:
# .github/workflows/trigger-deployment.yml
name: Trigger Fleet Deployment
on:
push:
branches: [main]
tags: ['v*']
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Trigger deployment
uses: peter-evans/repository-dispatch@v2
with:
token: ${{ secrets.DEPLOYMENT_TOKEN }}
repository: mbTagai/gaisro-technika-infra
event-type: deploy-nodered
client-payload: |
{
"version": "${{ github.ref_name }}",
"environment": "production"
}
Security Considerations¶
Credentials Management¶
- Never commit unencrypted credentials
- Use Node-RED's built-in credential encryption
- Store sensitive variables in Ansible Vault
- Rotate credentials regularly
SSH Access¶
- Ansible connects via SSH using credentials in
group_vars/all.yml(encrypted) - Ensure firewall allows SSH from Ansible controller
- Consider using SSH keys instead of passwords
Git Authentication¶
For private repositories: - Use Personal Access Tokens (PAT) with minimal scope - Store in Ansible Vault - Rotate tokens quarterly
Best Practices¶
- Version Control Everything
- Tag stable releases in gaisro-technika-nodered
-
Document breaking changes in CHANGELOG.md
-
Test Before Production
- Deploy to development devices first
- Run integration tests
-
Monitor for 24 hours before wider rollout
-
Maintain Backups
- Automated backups are created during deployment
- Keep backups for 30 days minimum
-
Test restore process quarterly
-
Monitor Deployments
- Check health endpoints after deployment
- Monitor MQTT connectivity
-
Review Node-RED logs for errors
-
Document Changes
- Update README.md in nodered repo
- Document new nodes/dependencies
- Keep API documentation current
Related Documentation¶
- Ansible Fleet Management
- Environment Deployment
- Project Overview (archived)
- Cloudflare Infrastructure
Support¶
For issues or questions:
1. Check troubleshooting section above
2. Review Node-RED logs on device
3. Check Ansible playbook output with -vvv flag
4. Review closed GitHub issues in both repositories