Modern, cloud-native industrial monitoring and control system (SCADA) built as a web application.
WebSCADA is a full-stack industrial IoT platform providing real-time monitoring of industrial devices, data visualization, alarm management, and control capabilities. Built with TypeScript, Next.js, and Fastify, it supports multiple industrial protocols including ESP32, LoRaWAN, MQTT, and integrates with InfluxDB for time-series data.
- Real-time Monitoring: Live device data updates via WebSocket
- Multi-Protocol Support: ESP32, LoRaWAN/ChirpStack, MQTT
- Time-Series Data: InfluxDB integration for historical data
- Device Management: Comprehensive device and tag management
- Alarm System: Configurable alarms and notifications
- Responsive UI: Modern web interface built with Next.js and Tailwind CSS
- RESTful API: Complete API for device control and data access
- Production Ready: Docker Compose deployment with Nginx reverse proxy
- Framework: Next.js 14 (React 18)
- Styling: Tailwind CSS
- UI Components: Radix UI, Recharts
- Real-time: Socket.io Client
- Framework: Fastify 4.x
- Database: PostgreSQL 16
- Cache: Redis 7
- WebSocket: Socket.io
- Protocols: MQTT (via Mosquitto)
- Container: Docker + Docker Compose
- Reverse Proxy: Nginx
- Time-Series: InfluxDB
- LoRaWAN: ChirpStack
- Ubuntu 20.04 LTS or 22.04 LTS
- Docker 20.10+
- Docker Compose 2.0+
- Nginx (for production)
- Domain name (for production)
- Clone the repository
cd /opt
git clone <repository-url> webscada
cd webscada- Run setup
chmod +x deploy-vps.sh
sudo ./deploy-vps.sh setup- Configure environment
cp .env.production.example .env.production
nano .env.productionUpdate:
DOMAIN- your domain namePOSTGRES_PASSWORD- generate withopenssl rand -base64 24REDIS_PASSWORD- generate withopenssl rand -base64 24JWT_SECRET- generate withopenssl rand -base64 32CORS_ORIGIN- your domain URL- API URLs
- Configure Nginx
sudo cp infrastructure/nginx/webscada.conf /etc/nginx/sites-available/webscada.conf
sudo nano /etc/nginx/sites-available/webscada.conf
# Update server_name and SSL paths
sudo ln -s /etc/nginx/sites-available/webscada.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx- Setup SSL (recommended)
sudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com- Deploy
sudo ./deploy-vps.sh deploy- Verify
sudo ./deploy-vps.sh statusAccess at: https://your-domain.com:8443
webscada/
├── apps/
│ ├── backend/ # Fastify API server
│ ├── frontend/ # Next.js web application
│ └── realtime-service/ # Real-time data service
├── packages/
│ ├── shared-types/ # TypeScript type definitions
│ ├── utils/ # Shared utilities
│ └── protocols/ # Protocol handlers
├── infrastructure/
│ ├── docker/ # Dockerfiles
│ ├── nginx/ # Nginx reverse proxy config
│ ├── database/ # Database init scripts
│ ├── mosquitto/ # MQTT broker config
│ ├── chirpstack/ # LoRaWAN server config
│ └── influxdb/ # InfluxDB config
├── firmware/
│ └── esp32/ # ESP32 device firmware
├── documents/
│ ├── architecture/ # System architecture docs
│ └── api/ # API documentation
├── docker-compose.vps.yml # Production Docker Compose
├── deploy-vps.sh # Deployment automation script
├── .env.production.example # Environment template
├── DEPLOYMENT.md # Complete deployment guide
└── README.md # This file
- Frontend (Port 3000): Next.js web application
- Backend (Port 3001): Fastify REST API and WebSocket server
- Realtime Service (Port 3002): Real-time data streaming
- PostgreSQL (Port 5432): Primary database
- Redis (Port 6379): Caching and pub/sub
- Mosquitto (Port 1883): MQTT broker
All services run in a Docker internal network (172.25.0.0/16). External access is routed through Nginx reverse proxy on ports 8080 (HTTP) and 8443 (HTTPS), avoiding conflicts with existing websites on ports 80/443.
- ESP32: MQTT-based device communication
- LoRaWAN: ChirpStack integration for LoRaWAN devices
- InfluxDB: Time-series data storage and querying
sudo ./deploy-vps.sh deploy # Deploy/update
sudo ./deploy-vps.sh start # Start services
sudo ./deploy-vps.sh stop # Stop services
sudo ./deploy-vps.sh restart # Restart services
sudo ./deploy-vps.sh status # Show status
sudo ./deploy-vps.sh logs # View logssudo ./deploy-vps.sh backup # Create backup
sudo ./deploy-vps.sh restore # Restore from backupdocker ps # List containers
docker logs webscada-backend # View backend logs
docker exec -it webscada-backend bash # Shell access
docker stats # Resource usageSee .env.production.example for all available configuration options.
Critical settings:
DATABASE_URL- PostgreSQL connection stringREDIS_URL- Redis connection stringJWT_SECRET- Authentication secretCORS_ORIGIN- Frontend URL for CORSNEXT_PUBLIC_API_URL- Backend API URLNEXT_PUBLIC_WS_URL- WebSocket URL
Nginx configuration includes:
- Reverse proxy for all services
- Rate limiting (10 req/s for API, 30 req/s for WebSocket)
- Connection limits (50 concurrent per IP)
- SSL/TLS termination
- WebSocket proxy support
- Security headers
- Strong passwords: Use
openssl rand -base64 32for all secrets - SSL/TLS: Always use HTTPS in production
- Firewall: Enable UFW and allow only necessary ports
- SSH keys: Disable password authentication
- Regular updates: Keep system and Docker images updated
- Fail2Ban: Install for brute-force protection
- Backups: Schedule daily automated backups
sudo ufw enable
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 8080/tcp # WebSCADA HTTP
sudo ufw allow 8443/tcp # WebSCADA HTTPS- Frontend:
http://localhost:3000/ - Backend:
http://localhost:3001/health - Realtime:
http://localhost:3002/health
# Application logs
docker logs -f webscada-backend
docker logs -f webscada-frontend
docker logs -f webscada-realtime
# Nginx logs
sudo tail -f /var/log/nginx/webscada_access.log
sudo tail -f /var/log/nginx/webscada_error.log
# System logs
sudo tail -f /var/log/webscada/*.log# Container stats
docker stats
# System resources
htop
df -h
free -hSetup daily backups at 2 AM:
sudo crontab -e
# Add: 0 2 * * * /opt/webscada/deploy-vps.sh backup >> /var/log/webscada/backup.log 2>&1# Database backup
docker exec webscada-postgres pg_dump -U webscada webscada > backup.sql
# Full system backup
sudo ./deploy-vps.sh backup# From automated backup
sudo ./deploy-vps.sh restore
# From manual backup
docker exec -i webscada-postgres psql -U webscada webscada < backup.sqlContainers won't start
docker logs webscada-backend
sudo ./deploy-vps.sh restart502 Bad Gateway
docker logs webscada-backend
docker restart webscada-backend
sudo nginx -tDatabase connection error
docker ps | grep postgres
docker logs webscada-postgres
docker exec webscada-postgres psql -U webscada -d webscada -c "SELECT 1;"Cannot access via domain
dig your-domain.com # Check DNS
sudo systemctl status nginx # Check Nginx
sudo ufw status # Check firewall
docker ps # Check containers- Deployment Guide:
DEPLOYMENT.md- Complete deployment instructions - Deployment Checklist:
DEPLOYMENT-CHECKLIST.md- Pre-deployment checklist - Architecture:
documents/architecture/- System architecture - API Reference:
documents/api/- API documentation
For local development:
# Install dependencies
pnpm install
# Start databases
docker-compose -f docker-compose.vps.yml up -d postgres redis mosquitto
# Start applications
pnpm devPrivate
For issues and questions:
- Check logs:
docker logs <container-name> - Review
DEPLOYMENT.md - Check
documents/architecture/ - Verify environment variables
- Consult troubleshooting section
Production deployment: See DEPLOYMENT.md for complete instructions.