CloudSense is a complete IoT monitoring system that collects sensor data from multiple ESP32 devices via MQTT, stores it in MongoDB Atlas (cloud database), and displays real-time updates on a React dashboard. The backend and MQTT broker are containerized with Docker, while the frontend is built and served directly on the host using Nginx. This project can be deployed to any cloud service (AWS, GCP, Azure, etc.) and is designed for college demonstration of cloud services, including the use of external cloud database services (MongoDB Atlas) and hybrid deployment patterns (containerized services + host-based services).
ESP32 Devices (NTP) β Mosquitto MQTT Broker (Container) β FastAPI Backend (Container) β MongoDB Atlas (Cloud Database)
β
WebSocket β React Dashboard β Nginx (Host)
Deployment Model:
- Containerized Services: Mosquitto MQTT broker and FastAPI backend run in Docker containers
- Host-based Service: React frontend is built and served directly on the host using Nginx
- External Cloud Service: MongoDB Atlas provides the database as a managed cloud service, eliminating the need to run and maintain a local database instance
This hybrid approach demonstrates both containerization benefits and host-based service deployment patterns.
- Backend: FastAPI (Python) - Containerized
- Frontend: React + Vite - Built and served on host via Nginx
- Database: MongoDB Atlas (Cloud Database Service)
- MQTT Broker: Mosquitto - Containerized
- Web Server: Nginx (installed on host)
- Containerization: Docker + Docker Compose (for backend and MQTT broker)
- Cloud: Any cloud provider (AWS EC2, GCP VM, Azure VM, etc.) with Ubuntu 22.04
- Docker and Docker Compose installed
- Nginx installed on host (for serving frontend)
- Node.js and npm installed (for building React frontend)
- Cloud VM instance (AWS EC2, GCP VM, Azure VM, etc.) with Ubuntu 22.04, or local machine for testing
- MongoDB Atlas account - Free tier available at mongodb.com/cloud/atlas
- ESP32 development boards with DHT22/DHT11 sensors
- Arduino IDE (for ESP32 firmware)
- For local development:
uvpackage manager (optional but recommended) or Python 3.11+
cd /home/luffy/work/cc_projectFor local backend development with uv:
cd backend
./setup.sh # Or manually: uv venv .venv --python 3.11 && source .venv/bin/activate && uv pip install -r requirements.txt
source .venv/bin/activate
uvicorn main:app --host 0.0.0.0 --port 8000 --reloadSee backend/README.md for more details.
-
Create MongoDB Atlas Account:
- Go to mongodb.com/cloud/atlas
- Sign up for a free account (M0 Free Tier available)
-
Create a Cluster:
- Choose your preferred cloud provider and region
- Select M0 (Free) tier
- Wait for cluster creation (2-3 minutes)
-
Configure Database Access:
- Go to "Database Access" β "Add New Database User"
- Create a username and password (save these securely)
- Set user privileges to "Read and write to any database"
-
Configure Network Access:
- Go to "Network Access" β "Add IP Address"
- For development: Add
0.0.0.0/0(allows from anywhere) - For production: Add your cloud VM's IP address only
-
Get Connection String:
- Go to "Database" β "Connect" β "Connect your application"
- Copy the connection string (format:
mongodb+srv://<username>:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority)
Create a .env file in the backend/ directory:
MQTT_BROKER=mosquitto
MQTT_PORT=1883
MONGODB_URL=mongodb+srv://<username>:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority
MONGODB_DB=iot_sensorsImportant: Replace <username>, <password>, and the cluster URL with your actual MongoDB Atlas credentials.
Build the React frontend on the host:
cd frontend
npm install
npm run buildThis creates a dist/ directory with the production-ready frontend files.
-
Install Nginx (if not already installed):
sudo apt update sudo apt install nginx -y
-
Copy Nginx configuration:
sudo cp nginx/nginx.conf /etc/nginx/sites-available/cloudsense sudo ln -s /etc/nginx/sites-available/cloudsense /etc/nginx/sites-enabled/
-
Update Nginx config to point to your frontend build:
- Edit
/etc/nginx/sites-available/cloudsense - Update the
rootdirective to point to your frontenddist/directory (e.g.,/home/luffy/work/cc_project/frontend/dist) - Update the
proxy_passfor backend API tohttp://localhost:8000
- Edit
-
Test and reload Nginx:
sudo nginx -t sudo systemctl reload nginx
docker-compose up --build -dThis will start:
- Mosquitto MQTT broker (port 1883) - Containerized
- FastAPI backend (port 8000) - Containerized, connects to MongoDB Atlas
Note:
- MongoDB Atlas runs as a managed cloud service, so no local MongoDB container is needed
- Frontend is served directly by host Nginx (not containerized)
Open your browser and navigate to:
- Local:
http://localhost - Cloud VM:
http://<your-vm-ip>(replace with your cloud instance IP)
- Open
esp32_firmware/esp32_sensor.inoin Arduino IDE - Update WiFi credentials:
const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD";
- Update MQTT broker IP (your cloud VM IP):
const char* mqtt_server = "YOUR_CLOUD_VM_IP";
- Set unique device ID for each ESP32:
const char* device_id = "esp_01"; // Change for each device
- Upload to ESP32
See esp32_firmware/README.md for detailed instructions.
- Subscribe:
sensors/+/data(wildcard for all devices) - Publish:
sensors/<device_id>/data
GET /api/data/latest?device_id=<device_id>- Get latest readingGET /api/data/history?device_id=<device_id>&limit=20- Get historical dataGET /api/devices- Get list of all devices
WS /ws- Real-time sensor data stream
- β Multi-device support
- β Real-time data visualization with charts
- β Historical data table (last 20 readings)
- β Online/offline device status
- β Auto-detection of new devices
- β WebSocket reconnection with exponential backoff
- β Responsive dashboard UI
| Service | Container Name | Port | Description |
|---|---|---|---|
| Mosquitto | iot_mosquitto |
1883 | MQTT broker |
| FastAPI | iot_backend |
8000 | Backend API |
| Service | Location | Port | Description |
|---|---|---|---|
| Nginx | Host | 80 | Web server serving React frontend and proxying API requests |
External Cloud Service:
- MongoDB Atlas - Managed cloud database (no local container needed)
cc_project/
βββ backend/ # FastAPI backend
β βββ main.py # Main application
β βββ requirements.txt # Python dependencies
β βββ Dockerfile # Backend container
βββ frontend/ # React frontend
β βββ src/
β β βββ components/ # React components
β β βββ App.jsx # Main app component
β β βββ main.jsx # Entry point
β βββ package.json # Node dependencies
β βββ dist/ # Built frontend (generated after npm run build)
βββ nginx/ # Nginx configuration for host
β βββ nginx.conf # Nginx config (to be copied to /etc/nginx/sites-available/)
βββ mosquitto/ # MQTT broker config
β βββ config/
β βββ mosquitto.conf
βββ esp32_firmware/ # ESP32 Arduino code
β βββ esp32_sensor.ino # Main firmware
β βββ README.md # Firmware instructions
βββ docker-compose.yml # Docker orchestration
βββ README.md # This file
# Check logs
docker-compose logs
# Restart services
docker-compose restart
# Rebuild containers
docker-compose up --build -d- Verify frontend is built:
ls frontend/dist/ - Check Nginx is running:
sudo systemctl status nginx - Verify Nginx config:
sudo nginx -t - Check Nginx error logs:
sudo tail -f /var/log/nginx/error.log - Ensure Nginx config points to correct frontend
dist/directory - Rebuild frontend if needed:
cd frontend && npm run build
- Verify MQTT broker IP is correct
- Check firewall rules (port 1883 should be open)
- Verify WiFi connection on ESP32
- Check Serial Monitor for error messages
- Verify host Nginx configuration includes WebSocket upgrade headers (check
/etc/nginx/sites-available/cloudsense) - Check backend logs:
docker-compose logs backend - Ensure frontend is using correct WebSocket URL
- Reload Nginx after config changes:
sudo systemctl reload nginx
- Verify MongoDB Atlas connection string in
.envfile (check username, password, and cluster URL) - Ensure MongoDB Atlas network access allows your IP address (check Network Access in Atlas dashboard)
- Verify database user credentials are correct
- Check backend logs:
docker-compose logs backend - Test connection string format:
mongodb+srv://username:password@cluster.mongodb.net/?retryWrites=true&w=majority
This project can be deployed to any cloud service provider (AWS, GCP, Azure, DigitalOcean, etc.). The following example uses GCP, but similar steps apply to other providers:
-
Create Cloud VM:
- Ubuntu 22.04
- Allow HTTP traffic (port 80)
- Allow custom TCP port 1883 (for MQTT)
-
SSH into VM:
# GCP example: gcloud compute ssh <instance-name> --zone=<zone> # AWS example: ssh -i your-key.pem ubuntu@<your-ec2-ip> # Azure example: ssh azureuser@<your-vm-ip>
-
Install required software:
sudo apt update sudo apt install docker.io docker-compose nginx nodejs npm -y sudo usermod -aG docker $USER # Log out and back in
-
Set up MongoDB Atlas:
- Follow steps in "Set Up MongoDB Atlas (Cloud Database)" section above
- Create
.envfile inbackend/directory with your MongoDB Atlas connection string - Ensure Network Access in Atlas allows your cloud VM's IP address
-
Clone repository:
git clone <your-repo> cd cc_project
-
Build frontend:
cd frontend npm install npm run build cd ..
-
Configure Nginx:
sudo cp nginx/nginx.conf /etc/nginx/sites-available/cloudsense # Edit the config file to update paths: sudo nano /etc/nginx/sites-available/cloudsense # Update root path to: /home/<user>/cc_project/frontend/dist (or your actual path) sudo ln -s /etc/nginx/sites-available/cloudsense /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
-
Start containerized services:
docker-compose up --build -d
-
Configure firewall:
- GCP: Use
gcloud compute firewall-rulesor Cloud Console - AWS: Configure Security Groups to allow ports 80 and 1883
- Azure: Configure Network Security Groups (NSG) to allow ports 80 and 1883
- Other providers: Follow their respective firewall/security group configuration
- GCP: Use
- MQTT broker allows anonymous connections (for MVP)
- MongoDB Atlas provides managed cloud database - no local database container needed
- Data is stored in MongoDB Atlas cloud service, demonstrating external cloud service integration
- Hybrid deployment model: Backend and MQTT broker are containerized, while frontend is served directly on host via Nginx
- Frontend must be built manually using
npm run buildbefore deployment - Nginx runs on the host (not in a container) and serves the built frontend static files
- ESP32 devices publish data every 5 seconds
- Device online status is based on last 10 seconds of activity
This project is designed for college demonstration of cloud services and showcases:
- β Cloud Deployment - Deployable to any cloud provider (AWS, GCP, Azure, etc.)
- β External Cloud Database Service - MongoDB Atlas as a managed cloud database (demonstrates Database-as-a-Service)
- β Hybrid Deployment Model - Combination of containerized services (backend, MQTT) and host-based services (frontend via Nginx)
- β Containerization - Docker and Docker Compose for backend and MQTT broker orchestration
- β Microservices Architecture - Modular, scalable service design
- β Real-time Communication - WebSocket for live data streaming
- β IoT Integration - MQTT protocol for sensor data collection
- β Modern Web Stack - FastAPI backend with React frontend
- β Reverse Proxy Pattern - Nginx for load balancing and routing
- β Cloud Infrastructure - Demonstrates practical cloud service utilization and integration of multiple cloud services
This project is for educational/demonstration purposes.
This is a college project. Feel free to use and modify as needed.