Node-RED is a lightweight flow-based programming tool for wiring together APIs, hardware, and services. This guide runs it in Docker with persistent storage and a secured, TLS-fronted web UI.
Target environment: Ubuntu 24.04 LTS, 1 vCPU / 1 GB RAM is enough for most flows; bump to 2 GB if you'll run heavier function nodes or dashboards.
1. Initial server prep
apt update && apt upgrade -y
apt install -y curl ufw
adduser deploy
usermod -aG sudo deploy
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enableRe-login as deploy for the remaining steps.
2. Install Docker
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker3. Set up persistent storage and Compose file
mkdir -p ~/node-red/data
cd ~/node-rednano docker-compose.ymlservices:
node-red:
image: nodered/node-red:latest
restart: unless-stopped
environment:
- TZ=America/New_York
ports:
- "127.0.0.1:1880:1880"
volumes:
- ./data:/data
user: "1000"Set TZ to your VPS's actual timezone (matters for scheduled flows). Bind to 127.0.0.1 only — Nginx will handle the public-facing side.
docker compose up -d
docker compose logs -fCtrl+C once you see "Server now running at http://127.0.0.1:1880/".
4. Secure the editor and admin API
By default Node-RED's editor is wide open to anyone who can reach port 1880. Since we're about to expose it via a reverse proxy, lock it down first.
Generate a password hash:
docker run -it --rm nodered/node-red:latest node-red admin hash-pwEnter a strong password when prompted; copy the resulting $2b$... hash.
Create a settings override:
nano ~/node-red/data/settings.jsIf the file doesn't already exist with defaults, copy the stock settings.js out of the container first:
docker cp $(docker compose ps -q node-red):/data/settings.js ~/node-red/data/settings.jsThen edit it to add (uncomment) the adminAuth block:
adminAuth: {
type: "credentials",
users: [{
username: "admin",
password: "PASTE_YOUR_HASH_HERE",
permissions: "*"
}]
},Restart to apply:
docker compose restart5. Put Nginx + TLS in front of it
sudo apt install -y nginx certbot python3-certbot-nginx
sudo nano /etc/nginx/sites-available/node-redserver {
listen 80;
server_name nodered.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:1880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}The Upgrade/Connection headers are required — Node-RED's editor relies on WebSockets for live updates.
sudo ln -s /etc/nginx/sites-available/node-red /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d nodered.yourdomain.com6. First login
Visit https://nodered.yourdomain.com, log in with the admin credentials you set, and confirm you can create and deploy a trivial flow (e.g., an inject node wired to a debug node).
7. Installing additional nodes
Use the "Manage palette" menu in the editor UI, or install directly:
docker compose exec node-red npm install node-red-contrib-<package-name>
docker compose restart8. Backups
Everything that matters lives in ~/node-red/data — flows, credentials, installed nodes, and settings:
tar -czf node-red-backup-$(date +%F).tar.gz -C ~/node-red dataNode-RED also has built-in flow export (Menu → Export) for quick flow-only backups you can store separately in version control.
9. Updating
cd ~/node-red
docker compose pull
docker compose up -d