Web UI Multi-User Deployment Guide¶
Overview¶
This guide covers deploying the MBASIC web UI for multi-user, production environments. Multi-user mode adds session persistence, error logging, rate limiting, and other features needed for load-balanced, long-running deployments.
Single-user mode (default) stores everything in memory - simple but sessions are lost on restart.
Multi-user mode adds: - Redis-backed session storage (survives restarts, load balancing) - MySQL error logging (track bugs across sessions) - Rate limiting (prevent abuse) - Centralized configuration
Quick Start¶
For local development or single-user deployments, just run:
For production multi-user deployments, follow this guide.
Architecture¶
┌─────────────────────────────────────────────────────────────┐
│ Load Balancer (optional) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
┌───────▼──────┐ ┌───────▼──────┐ ┌──────▼──────┐
│ MBASIC Web 1 │ │ MBASIC Web 2 │ │ MBASIC Web N│
└───────┬──────┘ └───────┬──────┘ └──────┬──────┘
│ │ │
└─────────────────────┼─────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
┌───────▼──────┐ ┌───────▼──────┐
│ Redis │ │ MySQL │
│ (Sessions) │ │ (Errors) │
└──────────────┘ └──────────────┘
Installation¶
1. Install Dependencies¶
Base requirements:
For Redis session storage (load balancing):
For MySQL error logging:
All at once:
Note: No apt packages needed - all dependencies are pure Python!
2. Install Redis (Optional)¶
Only needed for load-balanced deployments with multiple web server instances.
Debian/Ubuntu:
Or use Docker:
Test connection:
3. Install MariaDB/MySQL (Optional)¶
Only needed if you want error logging for debugging production issues.
Debian/Ubuntu:
Secure installation:
Create database:
Test connection:
Configuration¶
1. Create Configuration File¶
2. Configure Multi-User Settings¶
Edit config/multiuser.json:
Minimal Configuration (In-Memory)¶
For single-server deployments without external dependencies:
{
"enabled": false,
"session_storage": {
"type": "memory"
},
"error_logging": {
"type": "stderr"
}
}
Redis Session Storage (Load Balancing)¶
For multiple web server instances sharing sessions:
{
"enabled": true,
"session_storage": {
"type": "redis",
"redis": {
"url": "redis://localhost:6379/0",
"key_prefix": "mbasic:session:"
}
},
"error_logging": {
"type": "stderr"
}
}
MySQL Error Logging (Unix Socket)¶
For local MariaDB/MySQL with Unix socket authentication:
{
"enabled": true,
"session_storage": {
"type": "memory"
},
"error_logging": {
"type": "mysql",
"mysql": {
"unix_socket": "/run/mysqld/mysqld.sock",
"user": "your_username",
"password": "",
"database": "mbasic_logs",
"table": "web_errors"
},
"log_expected_errors": false
}
}
MySQL Error Logging (TCP/Password)¶
For remote MySQL or password authentication:
{
"enabled": true,
"session_storage": {
"type": "memory"
},
"error_logging": {
"type": "mysql",
"mysql": {
"host": "mysql.example.com",
"port": 3306,
"user": "mbasic",
"password": "your_password",
"database": "mbasic_logs",
"table": "web_errors"
},
"log_expected_errors": false
}
}
Full Production Configuration¶
Redis sessions + MySQL logging + rate limiting:
{
"enabled": true,
"session_storage": {
"type": "redis",
"redis": {
"url": "redis://localhost:6379/0",
"key_prefix": "mbasic:session:"
}
},
"error_logging": {
"type": "both",
"mysql": {
"unix_socket": "/run/mysqld/mysqld.sock",
"user": "mbasic",
"password": "",
"database": "mbasic_logs",
"table": "web_errors"
},
"log_expected_errors": false
},
"rate_limiting": {
"enabled": true,
"max_requests_per_minute": 60,
"max_concurrent_sessions": 100
},
"autosave": {
"enabled": true,
"interval_seconds": 60
}
}
3. Environment Variables (Legacy)¶
For backward compatibility, environment variables still work:
# Redis session storage
export NICEGUI_REDIS_URL="redis://localhost:6379/0"
# MySQL error logging
export MBASIC_MYSQL_HOST="localhost"
export MBASIC_MYSQL_USER="mbasic"
export MBASIC_MYSQL_PASSWORD="password"
export MBASIC_MYSQL_DB="mbasic_logs"
Note: config/multiuser.json takes precedence over environment variables.
Setup Database (MySQL/MariaDB)¶
Using Unix Socket (Recommended)¶
If your user can run mysql without a password:
-
Create database:
-
Verify:
-
Configure:
Using Password Authentication¶
-
Create database and user:
-
Configure:
Running the Web UI¶
Development¶
Production (Single Instance)¶
Using systemd:
# /etc/systemd/system/mbasic-web.service
[Unit]
Description=MBASIC Web UI
After=network.target redis.service mariadb.service
[Service]
Type=simple
User=mbasic
WorkingDirectory=/opt/mbasic
Environment="PATH=/opt/mbasic/venv/bin:/usr/bin"
ExecStart=/opt/mbasic/venv/bin/python3 /opt/mbasic/mbasic --ui web --port 8080
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Production (Load Balanced)¶
Requirements: - Redis for session storage - Multiple web instances on different ports - Nginx/HAProxy for load balancing
Start multiple instances:
# Instance 1
python3 mbasic --ui web --port 8081 &
# Instance 2
python3 mbasic --ui web --port 8082 &
# Instance 3
python3 mbasic --ui web --port 8083 &
Nginx configuration:
upstream mbasic_backend {
least_conn;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
server 127.0.0.1:8083;
}
server {
listen 80;
server_name mbasic.example.com;
location / {
proxy_pass http://mbasic_backend;
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;
}
}
Monitoring¶
View Error Logs¶
Recent errors:
Error summary:
Unexpected errors only:
Filter by session:
Full error details:
Database Queries¶
Recent unexpected errors:
SELECT timestamp, session_id, error_type, context, message
FROM mbasic_logs.web_errors
WHERE is_expected = FALSE
AND timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
ORDER BY timestamp DESC
LIMIT 50;
Error summary:
Recent errors view:
Redis Session Monitoring¶
Check session count:
View session data:
Clear old sessions:
Maintenance¶
Clear Old Error Logs¶
Using utility script:
Manual cleanup:
Backup Database¶
Restore Database¶
Troubleshooting¶
Redis Connection Failed¶
Symptom: Warning about Redis not available
Solutions:
1. Check Redis is running: systemctl status redis
2. Test connection: redis-cli ping
3. Check URL in config: redis://localhost:6379/0
4. Check firewall: sudo ufw allow 6379
Fallback: System automatically falls back to in-memory sessions
MySQL Connection Failed¶
Symptom: Warning about MySQL not available
Solutions:
1. Check MySQL running: systemctl status mariadb
2. Test connection: mysql -u mbasic -p mbasic_logs
3. Check socket path: /run/mysqld/mysqld.sock
4. Verify grants: SHOW GRANTS FOR 'mbasic'@'localhost';
Fallback: System automatically falls back to stderr logging
Sessions Not Persisting¶
Possible causes:
1. Redis not configured in config/multiuser.json
2. Redis server not running
3. Connection refused (check firewall)
Verify:
Errors Not Being Logged¶
Check:
1. config/multiuser.json has "type": "mysql" or "both"
2. MySQL credentials are correct
3. Database table exists: mysql mbasic_logs -e "SHOW TABLES;"
Test:
python3 << 'EOF'
import sys
sys.path.insert(0, 'src')
from error_logger import log_web_error
try:
raise ValueError("Test error")
except Exception as e:
log_web_error("test", e, session_id="TEST")
print("Error logged!")
EOF
Security Considerations¶
MySQL Security¶
-
Use separate user with limited privileges:
-
Don't use root in production
-
Use Unix sockets when possible (more secure than TCP)
-
Rotate passwords regularly
Redis Security¶
-
Enable password authentication:
-
Bind to localhost only:
-
Disable dangerous commands:
Rate Limiting¶
Enable in config/multiuser.json:
Performance Tuning¶
Redis¶
Increase max memory:
Enable persistence:
MySQL¶
Optimize for writes:
Add indexes if needed:
Web Server¶
Increase worker threads if handling many concurrent users:
# In nicegui_backend.py start_web_ui()
ui.run(
port=port,
reload=False,
show=False,
workers=4 # Add this for multiple workers
)
Production Checklist¶
- Dependencies installed (nicegui, redis, mysql-connector-python)
- Redis server running (if using session storage)
- MySQL/MariaDB server running (if using error logging)
- Database created (
config/setup_mysql_logging.sql) - Configuration file created (
config/multiuser.json) - Credentials configured (MySQL user/password)
- Systemd service created (if using)
- Load balancer configured (if using)
- Firewall rules set (ports 8080, 6379, 3306)
- Monitoring set up (error logs, sessions)
- Backup strategy in place (database dumps)
- Security hardened (passwords, socket permissions)
- Rate limiting enabled (if public-facing)
- SSL/TLS configured (nginx/haproxy)
Example Deployments¶
Small Team (5-10 users)¶
Setup: - Single web instance - In-memory sessions - MySQL error logging (Unix socket)
Config:
{
"enabled": true,
"session_storage": {"type": "memory"},
"error_logging": {
"type": "mysql",
"mysql": {
"unix_socket": "/run/mysqld/mysqld.sock",
"user": "mbasic",
"database": "mbasic_logs"
}
}
}
Medium Organization (50-100 users)¶
Setup: - 3 web instances (load balanced) - Redis session storage - MySQL error logging - Nginx load balancer
Config:
{
"enabled": true,
"session_storage": {
"type": "redis",
"redis": {"url": "redis://localhost:6379/0"}
},
"error_logging": {
"type": "both",
"mysql": {
"unix_socket": "/run/mysqld/mysqld.sock",
"user": "mbasic",
"database": "mbasic_logs"
}
},
"rate_limiting": {
"enabled": true,
"max_requests_per_minute": 100,
"max_concurrent_sessions": 200
}
}
Large Scale (1000+ users)¶
Setup: - 10+ web instances - Redis Cluster for sessions - Remote MySQL cluster - HAProxy load balancer - Docker/Kubernetes orchestration
Config:
{
"enabled": true,
"session_storage": {
"type": "redis",
"redis": {"url": "redis://redis-cluster:6379/0"}
},
"error_logging": {
"type": "mysql",
"mysql": {
"host": "mysql-cluster.internal",
"port": 3306,
"user": "mbasic",
"password": "ENV_VAR_PASSWORD",
"database": "mbasic_logs"
}
},
"rate_limiting": {
"enabled": true,
"max_requests_per_minute": 200,
"max_concurrent_sessions": 5000
}
}
Related Documentation¶
- WEB_ERROR_LOGGING.md - Error logging system details
config/multiuser.json.example- Configuration templateconfig/setup_mysql_logging.sql- Database schemautils/view_error_logs.py- Error viewing utilityold_dev_docs/INSTALLATION_FOR_DEVELOPERS.md- Development setup (archived)