The AI-Based Smart Complaint Management System is a web application that allows users to submit complaints digitally and automatically categorizes them using AI. The system streamlines complaint handling by organizing reports, reducing manual effort, and helping authorities respond faster. Built with Node.js and Docker, the platform ensures scalable deployment, efficient processing, and a modern cloud-ready architecture. It is highly adaptable and can be used across multiple sectorsβnot only for civic complaints but also for managing workflows in hospitals, municipalities, government offices, and private institutions.
- AI-Powered Categorization: Automatic complaint classification using NLP
- User Dashboard: Submit and track complaints with image uploads
- Admin Panel: Manage all complaints, update statuses, view analytics
- Real-time Status Tracking: Monitor complaint progress from submission to resolution
- Modern UI/UX: Glassmorphism design with dark/light mode support
- Secure Authentication: JWT-based auth with bcrypt password hashing
- Dockerized Deployment: Consistent environment across dev/test/prod
- Apache Reverse Proxy: Load balancing and secure routing
- HTML5, CSS3, JavaScript (Vanilla)
- Glassmorphism UI with 2025 design trends
- Responsive design for mobile/tablet/desktop
- Node.js with Express.js
- MongoDB with Mongoose ODM
- JWT authentication
- Multer for file uploads
- Rule-based NLP for AI categorization
- Docker & Docker Compose
- Apache HTTP Server (reverse proxy)
- Linux (Ubuntu Server)
- AWS EC2 ready
-
Docker & Docker Compose
-
Git Secrets
-
The compose file expects
JWT_SECRETandGEMINI_API_KEYto be provided for secure operation and AI features. For local development you can create a project-level.envfile in the repository root with the following:
# .env (project root)
JWT_SECRET=your_local_jwt_secret_here
GEMINI_API_KEY=your_gemini_api_key_hereNote: don't commit production secrets. Use a secrets manager or CI/CD secrets for deployments.
- Clone the repository
git clone <repository-url>
cd Dockerized-nodejs-cloud-app- Build and run with Docker Compose
docker-compose up --build- Access the application
- Frontend: https://civicsphere-backend.onrender.com/
- Backend: https://civicsphere-backend.onrender.com/
- Register: Create an account at
/register.html - Login: Sign in at
/login.html - Submit Complaint:
- Navigate to Dashboard
- Click "New Complaint"
- Fill in details (title, location, description)
- Upload image (optional)
- Submit
- Track Status: View all your complaints on the dashboard
-
Create Admin Account:
- Register normally
- Manually update role to 'admin' in MongoDB:
db.users.updateOne( { email: "admin@example.com" }, { $set: { role: "admin" } } )
-
Access Admin Panel: Navigate to
/admin.html -
Manage Complaints:
- View all complaints
- Filter by category/status
- Update complaint status
- View analytics
The system uses a rule-based NLP engine that analyzes complaint text and assigns categories:
- Garbage & Sanitation: trash, waste, dump, etc.
- Roads & Infrastructure: pothole, road, street, etc.
- Water Supply: leak, pipe, drainage, etc.
- Electricity & Power: light, power, outage, etc.
- Public Safety: accident, unsafe, crime, etc.
- General: Default category
Client (Browser)
β
Apache HTTP Server (Port 80)
β
Node.js/Express (Port 3000)
β
MongoDB (Port 27017)
/
βββ docker-compose.yml
βββ backend/
β βββ Dockerfile
β βββ package.json
β βββ src/
β βββ app.js
β βββ server.js
β βββ models/
β βββ controllers/
β βββ routes/
β βββ middleware/
β βββ services/
β βββ public/
β βββ index.html
β βββ login.html
β βββ register.html
β βββ dashboard.html
β βββ create-complaint.html
β βββ admin.html
β βββ css/
β βββ js/
β βββ uploads/
βββ apache/
βββ Dockerfile
βββ httpd.conf
- Password hashing with bcrypt
- JWT token-based authentication
- Protected API routes
- Role-based access control (Admin/Citizen)
- AWS Security Group firewall rules (when deployed)
- Launch Ubuntu EC2 instance
- Install Docker & Docker Compose
- Clone repository
- Configure security groups (ports 80, 443, 22)
- Run
docker-compose up -d --build - Configure domain/DNS (optional)
-
Create three Railway services:
- Backend: Root directory
backend/(Docker) - Webserver (Apache): Root directory
apache/(Docker) - Database: Use Railway MongoDB plugin
- Backend: Root directory
-
Configure environment variables for the Backend service in Railway Dashboard:
PORT= 3001NODE_ENV= productionMONGO_URI=JWT_SECRET= <secure_jwt_secret>GEMINI_API_KEY= <your_gemini_key> (optional - for AI features)
-
Configure environment variable for the Webserver service:
BACKEND_URL= https://.up.railway.app
-
Build & deploy each service via Railway using their respective directories. The Apache image uses
BACKEND_URLat container runtime to proxy/apirequests to the backend service.
Note on Railway networking: Railway does not provide internal container DNS between services the way Docker Compose does locally. Set BACKEND_URL to the public Railway backend URL (for example: https://<your-backend>.up.railway.app). Do not use localhost or internal container names β Apache must proxy to the public backend URL.
- Verification:
- Backend health:
https://<your-backend>.up.railway.app/api/health - Frontend:
https://<your-apache>.up.railway.app - Ensure
/apiroutes are proxied correctly and MongoDB is connected.
- Backend health:
Local smoke test (optional):
- Build the Apache image locally from the repository root (so the Dockerfile can copy frontend files):
docker build -t local-apache-test -f apache/Dockerfile .- Start a temporary stub backend to validate proxying (or use your running backend on port 3001):
# run a stub that responds at /api/health on port 4001
node stub-backend.js &- Create a user-defined docker network and run both containers on it so they can discover each other by name:
docker network create local-test-net
docker run -d --name stub-backend --network local-test-net -v "$PWD/stub-backend.js":/stub-backend.js:ro node:18-alpine node /stub-backend.js
docker run -d --name local-apache-test --network local-test-net -p 8080:80 -e BACKEND_URL=http://stub-backend:4001 local-apache-test- Verify the proxy works:
curl http://localhost:8080/api/health
# should return JSON from stub backendBelow are copy-paste commands for running and testing the app locally on Windows (cmd.exe). Use Docker Compose (recommended) to run all services, or run the backend directly with Node when debugging.
- Prepare env file
copy .env.example .env
rem Edit .env in an editor and add values (JWT_SECRET, MONGO_URI, etc.). Do NOT commit .env- Start with Docker Compose (recommended)
docker-compose up -d --build
docker-compose logs -f backendVerify backend health (from host):
curl http://localhost:3001/api/healthIf curl on Windows prints no body, use a containerized curl on the same Docker network (reliable):
docker run --rm --network dockerized-nodejs-cloud-app_app-network curlimages/curl:8.4.0 http://complaint-backend:3001/api/health -v- Run backend directly (no Docker) β for debugging
rem Start a local MongoDB (if needed)
docker run -d --name local-mongo -p 27017:27017 mongo:6.0
set PORT=3001
set MONGO_URI=mongodb://127.0.0.1:27017/complaint_db
set JWT_SECRET=devsecret
set NODE_ENV=development
node backend/src/server.js- Test Apache proxy locally
Option A (host.docker.internal):
docker build -t local-apache-test -f apache/Dockerfile .
docker run -p 8080:80 -e BACKEND_URL=http://host.docker.internal:3001 local-apache-test
curl http://localhost:8080/api/healthOption B (same Docker network β recommended for reliability):
docker network create local-test-net
docker run -d --name backend-test --network local-test-net -e PORT=3001 -e MONGO_URI="mongodb://..." your-backend-image
docker run -p 8080:80 --network local-test-net -e BACKEND_URL=http://backend-test local-apache-test
curl http://localhost:8080/api/health- If the Apache build fails with "file not found" for
apache/docker-entrypoint.shorhttpd.conf, ensure you build theapache/Dockerfile from the repository root (the compose file already does this) or use thedocker-composeservice which sets the correct context. - If
curlon Windows returns empty output, use the containerized curl command above or try PowerShell'sInvoke-WebRequest. - If you set
NODE_ENV=production, the backend will exit at startup ifJWT_SECRETorMONGO_URIare missing β this is intentional (fail-fast) so deployments surface missing configuration.
Note: When configuring the Apache service on Railway, set the build context to the repository root and the Dockerfile path to apache/Dockerfile so the Docker build can include backend/src/public in the image.
Note: For security, never store production secrets in your Git repository β use Railway environment variables or a secrets manager.
POST /api/auth/register- Register new userPOST /api/auth/login- Login user
POST /api/complaints- Create complaintGET /api/complaints- Get user's complaints
GET /api/admin/complaints- Get all complaintsPUT /api/admin/complaints/:id/status- Update statusGET /api/admin/analytics- Get statistics
- Colors: HSL-based for easy theming
- Typography: Outfit & Inter fonts
- Components: Glassmorphism panels, badges, buttons
- Animations: Smooth transitions and hover effects
- Responsive: Mobile-first approach
This is a demonstration project for learning Docker, Node.js, and modern web development practices.
MIT License
Ansh Mishra β Full-stack developer specializing in Node.js, Docker, and cloud deployment.
This project showcases containerized backend architecture and real-world DevOps practices.
Note: This project demonstrates real-world application architecture suitable for civic tech solutions, showcasing modern DevOps practices and AI integration.