Kubernetes Deployment Guide¶
This guide holds the step-by-step setup and operations detail for deploying the MBASIC web UI to DigitalOcean Kubernetes. The quick start, prerequisites, and file list are in deployment/README.md.
Setup Steps¶
1. Create Kubernetes Cluster¶
# Via DigitalOcean dashboard or CLI
doctl kubernetes cluster create mbasic-cluster \
--region nyc1 \
--node-pool "name=worker-pool;size=s-2vcpu-4gb;count=3"
# Get kubeconfig
doctl kubernetes cluster kubeconfig save mbasic-cluster
2. Install cert-manager (SSL Certificates)¶
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Wait for cert-manager to be ready
kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=cert-manager -n cert-manager --timeout=300s
3. Install nginx-ingress Controller¶
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/do/deploy.yaml
# Wait for load balancer to be created
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=300s
4. Create Container Registry¶
# Via DigitalOcean dashboard or:
doctl registry create YOUR_REGISTRY_NAME
# Login
doctl registry login
5. Set Up MySQL Database¶
Option A: DigitalOcean Managed Database (Recommended)
- Create MySQL cluster via DigitalOcean dashboard
- Create database:
mbasic_logs - Download CA certificate
- Run schema:
Option B: In-cluster MySQL
Deploy StatefulSet (see k8s/mysql-statefulset.yaml.example)
6. Get hCaptcha Keys¶
- Sign up at https://www.hcaptcha.com/
- Create a new site
- Get site key and secret key
- Add to
k8s/mbasic-secrets.yaml
7. Configure Secrets¶
# Copy template to working directory
cp deployment/k8s_templates/mbasic-secrets.yaml.example k8s/mbasic-secrets.yaml
Edit k8s/mbasic-secrets.yaml:
- MySQL host, user, password
- hCaptcha site and secret keys
- MySQL CA certificate (from DigitalOcean)
Important: Never commit mbasic-secrets.yaml to Git!
8. Update Configuration¶
Edit deployment/k8s_templates/ingress.yaml:
- Change email address for Let's Encrypt
Edit deployment/deploy.sh:
- Set your container registry URL (line 16)
9. Deploy¶
10. Configure DNS¶
Get load balancer IP:
Add DNS A record:
11. Wait for SSL Certificate¶
# Check certificate status
kubectl describe certificate mbasic-tls -n mbasic
# Wait for "Certificate issued successfully"
12. Test¶
Open browser: - https://mbasic.awohl.com/ (landing page) - https://mbasic.awohl.com/ide/ (web IDE)
Monitoring¶
View pods:
View logs:
# MBASIC web
kubectl logs -f deployment/mbasic-web -n mbasic
# Landing page
kubectl logs -f deployment/landing-page -n mbasic
# Redis
kubectl logs -f deployment/redis -n mbasic
Check autoscaling:
View error logs:
# SSH to a pod
kubectl exec -it deployment/mbasic-web -n mbasic -- bash
# Run error log viewer
python3 utils/view_error_logs.py --summary
Scaling¶
Manual scaling:
Auto-scaling is configured (3-10 replicas based on CPU/memory)
Updates¶
Deploy new version:
Rollback:
Check rollout status:
Troubleshooting¶
Pods not starting:
SSL certificate not issued:
kubectl describe certificate mbasic-tls -n mbasic
kubectl logs -n cert-manager deployment/cert-manager
Load balancer IP not assigned:
Database connection issues:
# Test from pod
kubectl exec -it deployment/mbasic-web -n mbasic -- bash
mysql -h $MYSQL_HOST -u $MYSQL_USER -p$MYSQL_PASSWORD mbasic_logs
Rate limiting too strict:
Edit k8s/ingress.yaml and adjust:
Cost Management¶
Current setup costs (approximate): - Kubernetes cluster (3x $12 nodes): $36/month - Load Balancer: $12/month - Managed MySQL: 15/month - **Total: ~63/month**
To reduce costs: - Use 2 nodes instead of 3: $24/month - Use in-cluster MySQL: Save $15/month - Use smaller nodes: $4/node/month minimum
Security¶
Best practices: - [x] Non-root containers - [x] Secrets encrypted at rest - [x] TLS/SSL enabled - [x] Rate limiting configured - [x] Bot protection (CAPTCHA) - [x] Resource limits set - [x] Network policies (TODO)
Regular maintenance: - Update images monthly - Rotate secrets quarterly - Review logs for abuse - Monitor error rates - Check for security patches
Backup¶
Redis (sessions): - Automatically backed up via PersistentVolume - Can lose sessions without data loss
MySQL (error logs):
- DigitalOcean automatic daily backups
- Or manual: mysqldump to object storage
Configuration: - All manifests in Git - Tag each deployment version