Docs: Add comprehensive IIS reverse proxy deployment guide
Created complete step-by-step guide for deploying Flask behind IIS. Covers: - IIS module installation (URL Rewrite, ARR) - ARR proxy configuration - Flask service setup with NSSM - IIS site configuration - End-to-end testing - Troubleshooting common issues - Maintenance commands - Security considerations - Performance tuning options - Backup and recovery Deployment architecture: Browser → IIS (HTTPS :443) → Reverse Proxy → Flask (HTTP :3001) → MySQL This is the complete production deployment guide for Windows Server environments where IIS must handle SSL/HTTPS public access. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
545
DEPLOYMENT_IIS_PROXY.md
Normal file
545
DEPLOYMENT_IIS_PROXY.md
Normal file
@@ -0,0 +1,545 @@
|
||||
# IIS Reverse Proxy Deployment Guide
|
||||
|
||||
Complete guide for deploying the Shopfloor Dashboard with IIS as a reverse proxy to Flask.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
[Browser] → [IIS :443 HTTPS] → [Reverse Proxy] → [Flask :3001 HTTP] → [MySQL]
|
||||
```
|
||||
|
||||
- **IIS**: Handles HTTPS, SSL certificates, and public access
|
||||
- **Flask**: Runs backend API on localhost:3001
|
||||
- **MySQL**: Database (can be local or remote)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Windows Server 2016+ or Windows 10/11
|
||||
- IIS installed with default features
|
||||
- Python 3.8+ installed
|
||||
- MySQL 5.6+ accessible
|
||||
- Administrative access
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Install IIS Modules
|
||||
|
||||
### 1.1 Download and Install URL Rewrite
|
||||
|
||||
1. Download: https://www.iis.net/downloads/microsoft/url-rewrite
|
||||
2. Run installer: `rewrite_amd64_en-US.msi`
|
||||
3. Accept defaults and install
|
||||
|
||||
### 1.2 Download and Install Application Request Routing (ARR)
|
||||
|
||||
1. Download: https://www.iis.net/downloads/microsoft/application-request-routing
|
||||
2. Run installer: `ARR_3.0_amd64.exe`
|
||||
3. Accept defaults and install
|
||||
|
||||
### 1.3 Verify Installation
|
||||
|
||||
```cmd
|
||||
REM Open IIS Manager
|
||||
inetmgr
|
||||
```
|
||||
|
||||
You should see:
|
||||
- "URL Rewrite" icon in IIS site features
|
||||
- "Application Request Routing Cache" at server level
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Enable ARR Proxy
|
||||
|
||||
**In IIS Manager:**
|
||||
|
||||
1. Click the **server name** at the top level (NOT a site)
|
||||
2. Double-click **Application Request Routing Cache**
|
||||
3. In the right panel, click **Server Proxy Settings**
|
||||
4. Check the box: **Enable proxy**
|
||||
5. Click **Apply**
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Deploy Application Files
|
||||
|
||||
### 3.1 Copy Files
|
||||
|
||||
Copy the entire `shopfloor-dashboard` folder to:
|
||||
```
|
||||
C:\inetpub\wwwroot\shopfloor-dashboard\
|
||||
```
|
||||
|
||||
Files should include:
|
||||
- `app.py` (Flask application)
|
||||
- `requirements.txt` (Python dependencies)
|
||||
- `web.config` (IIS reverse proxy configuration)
|
||||
- `public\` folder (index.html, logo, etc.)
|
||||
|
||||
### 3.2 Install Python Dependencies
|
||||
|
||||
```cmd
|
||||
cd C:\inetpub\wwwroot\shopfloor-dashboard
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
This installs:
|
||||
- Flask
|
||||
- mysql-connector-python
|
||||
|
||||
### 3.3 Configure Database Connection
|
||||
|
||||
Edit `app.py` lines 14-18:
|
||||
|
||||
```python
|
||||
DB_CONFIG = {
|
||||
'host': 'localhost', # Your MySQL server
|
||||
'port': 3306,
|
||||
'user': '570005354', # Your MySQL username
|
||||
'password': '570005354', # Your MySQL password
|
||||
'database': 'shopdb'
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Test Flask Manually
|
||||
|
||||
Before setting up the service, test Flask works:
|
||||
|
||||
```cmd
|
||||
cd C:\inetpub\wwwroot\shopfloor-dashboard
|
||||
python app.py
|
||||
```
|
||||
|
||||
You should see:
|
||||
```
|
||||
Shopfloor Dashboard running on port 3001
|
||||
Access at: http://localhost:3001
|
||||
DEBUG MODE: DISABLED
|
||||
Database: localhost:3306/shopdb
|
||||
```
|
||||
|
||||
**Test in browser or curl:**
|
||||
```cmd
|
||||
curl http://localhost:3001/health
|
||||
curl http://localhost:3001/api/notifications
|
||||
```
|
||||
|
||||
Both should return JSON responses (not errors).
|
||||
|
||||
Press `Ctrl+C` to stop.
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Install Flask as Windows Service (NSSM)
|
||||
|
||||
### 5.1 Download NSSM
|
||||
|
||||
1. Download: https://nssm.cc/download
|
||||
2. Extract to `C:\nssm\`
|
||||
|
||||
### 5.2 Install Service
|
||||
|
||||
```cmd
|
||||
REM Open Command Prompt as Administrator
|
||||
cd C:\nssm\win64
|
||||
|
||||
REM Install service
|
||||
nssm install ShopfloorDashboard "C:\Python312\python.exe" "app.py"
|
||||
```
|
||||
|
||||
**Note:** Adjust Python path if different. Find with: `where python`
|
||||
|
||||
### 5.3 Configure Service
|
||||
|
||||
```cmd
|
||||
REM Set working directory
|
||||
nssm set ShopfloorDashboard AppDirectory "C:\inetpub\wwwroot\shopfloor-dashboard"
|
||||
|
||||
REM Set display name
|
||||
nssm set ShopfloorDashboard DisplayName "Shopfloor Dashboard (Flask)"
|
||||
|
||||
REM Set description
|
||||
nssm set ShopfloorDashboard Description "GE Aerospace Shopfloor Events Dashboard - Flask Backend"
|
||||
|
||||
REM Set to start automatically
|
||||
nssm set ShopfloorDashboard Start SERVICE_AUTO_START
|
||||
|
||||
REM Set environment variables (optional - defaults work)
|
||||
nssm set ShopfloorDashboard AppEnvironmentExtra PORT=3001
|
||||
|
||||
REM Configure logging
|
||||
nssm set ShopfloorDashboard AppStdout "C:\inetpub\wwwroot\shopfloor-dashboard\stdout.log"
|
||||
nssm set ShopfloorDashboard AppStderr "C:\inetpub\wwwroot\shopfloor-dashboard\stderr.log"
|
||||
|
||||
REM Start service
|
||||
nssm start ShopfloorDashboard
|
||||
|
||||
REM Verify status
|
||||
nssm status ShopfloorDashboard
|
||||
```
|
||||
|
||||
Should show: `SERVICE_RUNNING`
|
||||
|
||||
### 5.4 Verify Flask Service
|
||||
|
||||
```cmd
|
||||
REM Test Flask is responding
|
||||
curl http://localhost:3001/health
|
||||
|
||||
REM Should return: {"status":"ok","timestamp":"..."}
|
||||
```
|
||||
|
||||
If not working, check logs:
|
||||
```cmd
|
||||
type "C:\inetpub\wwwroot\shopfloor-dashboard\stderr.log"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Configure IIS Site
|
||||
|
||||
### 6.1 Create or Configure Site
|
||||
|
||||
**In IIS Manager:**
|
||||
|
||||
1. Right-click **Sites** → **Add Website** (or use existing site)
|
||||
2. Configure:
|
||||
- **Site name**: ShopfloorDashboard
|
||||
- **Physical path**: `C:\inetpub\wwwroot\shopfloor-dashboard`
|
||||
- **Binding**:
|
||||
- Type: https
|
||||
- Port: 443
|
||||
- Host name: tsgwp00525.rd.ds.ge.com
|
||||
- SSL Certificate: (select your cert)
|
||||
|
||||
### 6.2 Verify web.config
|
||||
|
||||
Ensure `web.config` exists in site root with reverse proxy rules.
|
||||
|
||||
The file should contain:
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="Reverse Proxy to Flask" stopProcessing="true">
|
||||
<match url="(.*)" />
|
||||
<action type="Rewrite" url="http://localhost:3001/{R:1}" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
<httpErrors existingResponse="PassThrough" />
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
### 6.3 Restart IIS Site
|
||||
|
||||
```cmd
|
||||
REM Restart specific site
|
||||
iisreset /restart
|
||||
|
||||
REM Or in IIS Manager: Right-click site → Manage Website → Restart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Test End-to-End
|
||||
|
||||
### 7.1 Test from Server
|
||||
|
||||
```cmd
|
||||
REM Test health check
|
||||
curl https://tsgwp00525.rd.ds.ge.com/health
|
||||
|
||||
REM Test API
|
||||
curl https://tsgwp00525.rd.ds.ge.com/api/notifications
|
||||
```
|
||||
|
||||
### 7.2 Test from Browser
|
||||
|
||||
Open browser on any computer:
|
||||
```
|
||||
https://tsgwp00525.rd.ds.ge.com
|
||||
```
|
||||
|
||||
Should show the dashboard with:
|
||||
- GE Aerospace logo
|
||||
- Clock
|
||||
- Current and upcoming events
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue 1: IIS Returns 500.31 Error
|
||||
|
||||
**Cause:** Flask service not running
|
||||
|
||||
**Fix:**
|
||||
```cmd
|
||||
nssm status ShopfloorDashboard
|
||||
nssm start ShopfloorDashboard
|
||||
```
|
||||
|
||||
### Issue 2: IIS Returns 502 Bad Gateway
|
||||
|
||||
**Cause:** Flask is running but IIS can't reach it
|
||||
|
||||
**Fix:**
|
||||
```cmd
|
||||
REM Test Flask directly
|
||||
curl http://localhost:3001/health
|
||||
|
||||
REM If Flask works, check ARR proxy is enabled
|
||||
REM IIS Manager → Server → ARR → Server Proxy Settings → Enable proxy
|
||||
```
|
||||
|
||||
### Issue 3: API Returns Empty Data
|
||||
|
||||
**Cause:** Database connection issue
|
||||
|
||||
**Fix:**
|
||||
```cmd
|
||||
REM Enable debug mode
|
||||
nssm stop ShopfloorDashboard
|
||||
set DEBUG=true
|
||||
python app.py
|
||||
|
||||
REM Watch console for database errors
|
||||
```
|
||||
|
||||
### Issue 4: Changes Not Appearing
|
||||
|
||||
**Fix:**
|
||||
```cmd
|
||||
REM Restart Flask service
|
||||
nssm restart ShopfloorDashboard
|
||||
|
||||
REM Clear browser cache
|
||||
Ctrl+Shift+R
|
||||
```
|
||||
|
||||
### Issue 5: Service Won't Start
|
||||
|
||||
**Check logs:**
|
||||
```cmd
|
||||
type "C:\inetpub\wwwroot\shopfloor-dashboard\stderr.log"
|
||||
```
|
||||
|
||||
**Common causes:**
|
||||
- Python not in PATH
|
||||
- Missing dependencies: `pip install -r requirements.txt`
|
||||
- Database unreachable
|
||||
- Port 3001 already in use
|
||||
|
||||
---
|
||||
|
||||
## Maintenance Commands
|
||||
|
||||
### Service Management
|
||||
|
||||
```cmd
|
||||
REM Start service
|
||||
nssm start ShopfloorDashboard
|
||||
|
||||
REM Stop service
|
||||
nssm stop ShopfloorDashboard
|
||||
|
||||
REM Restart service
|
||||
nssm restart ShopfloorDashboard
|
||||
|
||||
REM Check status
|
||||
nssm status ShopfloorDashboard
|
||||
|
||||
REM View service configuration
|
||||
nssm get ShopfloorDashboard AppDirectory
|
||||
nssm get ShopfloorDashboard AppEnvironmentExtra
|
||||
|
||||
REM Uninstall service
|
||||
nssm stop ShopfloorDashboard
|
||||
nssm remove ShopfloorDashboard confirm
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```cmd
|
||||
REM Flask stdout (normal messages)
|
||||
type "C:\inetpub\wwwroot\shopfloor-dashboard\stdout.log"
|
||||
|
||||
REM Flask stderr (error messages)
|
||||
type "C:\inetpub\wwwroot\shopfloor-dashboard\stderr.log"
|
||||
|
||||
REM IIS logs (requests)
|
||||
type "C:\inetpub\logs\LogFiles\W3SVC1\*.log"
|
||||
|
||||
REM Windows Event Viewer (service events)
|
||||
eventvwr.msc → Windows Logs → Application
|
||||
```
|
||||
|
||||
### Update Application
|
||||
|
||||
```cmd
|
||||
REM 1. Stop service
|
||||
nssm stop ShopfloorDashboard
|
||||
|
||||
REM 2. Update files
|
||||
REM Copy new files to C:\inetpub\wwwroot\shopfloor-dashboard\
|
||||
|
||||
REM 3. Update dependencies (if needed)
|
||||
cd C:\inetpub\wwwroot\shopfloor-dashboard
|
||||
pip install -r requirements.txt --upgrade
|
||||
|
||||
REM 4. Start service
|
||||
nssm start ShopfloorDashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Database Credentials
|
||||
|
||||
**Option 1: Environment Variables (Recommended)**
|
||||
|
||||
```cmd
|
||||
nssm set ShopfloorDashboard AppEnvironmentExtra DB_HOST=mysql-server DB_USER=user DB_PASS=password DB_NAME=shopdb
|
||||
```
|
||||
|
||||
**Option 2: Edit app.py**
|
||||
|
||||
Not recommended for production - credentials in code.
|
||||
|
||||
### Firewall
|
||||
|
||||
```cmd
|
||||
REM Flask only listens on localhost:3001 - no firewall rules needed
|
||||
REM IIS handles public HTTPS on port 443
|
||||
```
|
||||
|
||||
### SSL Certificate
|
||||
|
||||
Ensure valid SSL certificate installed in IIS for HTTPS.
|
||||
|
||||
---
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Check Service Health
|
||||
|
||||
```cmd
|
||||
REM Quick health check
|
||||
curl http://localhost:3001/health
|
||||
|
||||
REM Check from external
|
||||
curl https://tsgwp00525.rd.ds.ge.com/health
|
||||
```
|
||||
|
||||
### Monitor Logs
|
||||
|
||||
```cmd
|
||||
REM Watch Flask logs in real-time
|
||||
powershell Get-Content -Path "C:\inetpub\wwwroot\shopfloor-dashboard\stderr.log" -Wait
|
||||
```
|
||||
|
||||
### Windows Task Scheduler
|
||||
|
||||
Create scheduled task to verify service is running every 5 minutes:
|
||||
|
||||
```cmd
|
||||
schtasks /create /tn "Check Shopfloor Dashboard" /tr "nssm status ShopfloorDashboard" /sc minute /mo 5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Tuning
|
||||
|
||||
### For Production Workloads
|
||||
|
||||
Consider using **Gunicorn** or **Waitress** instead of Flask's built-in server:
|
||||
|
||||
```cmd
|
||||
REM Install Waitress (pure Python, Windows-friendly)
|
||||
pip install waitress
|
||||
|
||||
REM Create app_production.py:
|
||||
```
|
||||
|
||||
```python
|
||||
from waitress import serve
|
||||
from app import app
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('Shopfloor Dashboard (Waitress) running on port 3001')
|
||||
serve(app, host='0.0.0.0', port=3001, threads=4)
|
||||
```
|
||||
|
||||
```cmd
|
||||
REM Update NSSM service
|
||||
nssm set ShopfloorDashboard AppParameters "app_production.py"
|
||||
nssm restart ShopfloorDashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Backup and Disaster Recovery
|
||||
|
||||
### Files to Backup
|
||||
|
||||
- `app.py` (application code)
|
||||
- `web.config` (IIS configuration)
|
||||
- `requirements.txt` (dependencies)
|
||||
- `public/` folder (frontend files)
|
||||
- NSSM service configuration
|
||||
|
||||
### Export NSSM Configuration
|
||||
|
||||
```cmd
|
||||
REM Export service settings to registry file
|
||||
reg export "HKLM\SYSTEM\CurrentControlSet\Services\ShopfloorDashboard" shopfloor-service-backup.reg
|
||||
```
|
||||
|
||||
### Quick Restore
|
||||
|
||||
```cmd
|
||||
REM 1. Copy files back to C:\inetpub\wwwroot\shopfloor-dashboard\
|
||||
REM 2. Import registry (if service deleted)
|
||||
reg import shopfloor-service-backup.reg
|
||||
REM 3. Start service
|
||||
nssm start ShopfloorDashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
**View this guide:**
|
||||
```
|
||||
C:\inetpub\wwwroot\shopfloor-dashboard\DEPLOYMENT_IIS_PROXY.md
|
||||
```
|
||||
|
||||
**Common Issues:** See Troubleshooting section above
|
||||
|
||||
**Logs:** Check stderr.log and stdout.log files
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
✅ IIS handles HTTPS and public access
|
||||
✅ Flask runs as Windows service on localhost:3001
|
||||
✅ URL Rewrite proxies requests to Flask
|
||||
✅ MySQL database for notifications
|
||||
✅ Auto-starts on server boot
|
||||
✅ Logs to files for troubleshooting
|
||||
|
||||
**Access:** `https://tsgwp00525.rd.ds.ge.com`
|
||||
|
||||
**Service:** `ShopfloorDashboard`
|
||||
|
||||
**Files:** `C:\inetpub\wwwroot\shopfloor-dashboard\`
|
||||
Reference in New Issue
Block a user