Qubinode Navigator Unified Deployment with Nginx
π― Overview
Single-script deployment of complete Qubinode Navigator stack with production-ready security via nginx reverse proxy.
β¨ Whatβs Included
Components Deployed:
- AI Assistant - RAG-powered assistant
- Apache Airflow - Workflow orchestration with kcli/virsh
- Nginx Reverse Proxy - Secure single entry point
- Firewall Configuration - Proper security rules
- Podman Network - Shared networking for all services
Security Features:
- β Direct ports (8888, 8080) closed
- β Access only through nginx (80/443)
- β Production-ready architecture
- β SSL/TLS ready
- β Single entry point for all services
π Quick Start
One-Command Deployment:
cd /opt/qubinode_navigator
./deploy-qubinode-with-airflow.sh
Thatβs it! The script handles:
- Base infrastructure deployment
- Airflow workflow orchestration setup
- Nginx reverse proxy configuration
- Firewall security rules
- Service verification
π Deployment Steps
The unified script performs these steps automatically:
Step 1: Base Infrastructure (1/4)
- Deploys hypervisor setup
- Starts AI Assistant container
- Configures base networking
Step 2: Airflow Deployment (2/4)
- Builds custom Airflow image with kcli
- Deploys Airflow services (webserver, scheduler, postgres)
- Mounts volumes and scripts
- Connects to shared network
Step 3: Nginx Reverse Proxy (3/4)
- Installs nginx if needed
- Creates reverse proxy configuration
- Configures firewall (closes 8888/8080, opens 80/443)
- Starts and enables nginx service
Step 4: Verification (4/4)
- Verifies all services running
- Tests connectivity
- Displays access URLs
π Access Points
After deployment:
| Service | URL | Credentials |
|---|---|---|
| Airflow UI | http://YOUR_IP/ | admin / admin |
| AI Assistant | http://YOUR_IP/ai/ | (no auth) |
| Health Check | http://YOUR_IP/health | (status) |
Replace YOUR_IP with your server IP (shown in deployment output).
π Security Architecture
Before (Direct Access):
Internet β Port 8888 β Airflow
Internet β Port 8080 β AI Assistant
β Multiple entry points
β Ports exposed directly
After (Nginx Reverse Proxy):
Internet β Port 80/443 β Nginx β {
Port 8888 (localhost only) β Airflow
Port 8080 (localhost only) β AI Assistant
}
β
Single entry point
β
SSL termination point
β
Better security
Firewall Rules:
Closed:
- β Port 8888 (Airflow direct access)
- β Port 8080 (AI Assistant direct access)
Open:
- β Port 80 (HTTP via nginx)
- β Port 443 (HTTPS via nginx - ready for SSL)
- β Port 22 (SSH)
- β Port 9090 (Cockpit - if installed)
π§ Configuration Files
Nginx Configuration:
Location: /etc/nginx/conf.d/airflow.conf
Automatically created by deployment script with:
- Airflow UI served at root (
/) - AI Assistant API at
/ai/ - Health check at
/health - WebSocket support for Airflow live updates
- Proper timeout settings
Airflow Configuration:
Location: /opt/qubinode_navigator/airflow/docker-compose.yml
Key settings:
- No BASE_URL (serves at any path)
- ENABLE_PROXY_FIX enabled
- Shared network with AI Assistant
- Scripts mounted for DAGs
π§ͺ Testing
Verify Deployment:
# Check nginx status
systemctl status nginx
# Check Airflow containers
cd /opt/qubinode_navigator/airflow
podman ps
# Test health endpoint
curl http://localhost/health
# Test Airflow UI
curl -I http://localhost/
# Check firewall rules
firewall-cmd --list-services
firewall-cmd --list-ports
Expected Results:
$ systemctl status nginx
β
Active: active (running)
$ podman ps
β
airflow_airflow-webserver_1 (healthy)
β
airflow_airflow-scheduler_1 (running)
β
airflow_postgres_1 (healthy)
β
qubinode-ai-assistant (running)
$ curl http://localhost/health
β
{"metadatabase": {"status": "healthy"}, ...}
$ firewall-cmd --list-services
β
http https ssh cockpit
$ firewall-cmd --list-ports
(empty - good! no direct port access)
π Usage
Access Airflow UI:
- Open browser:
http://YOUR_SERVER_IP/ - Login: admin / admin
- Enable DAGs you want to run
- Trigger test DAG to verify VM creation
Test VM Creation:
# From command line
cd /opt/qubinode_navigator/airflow
./scripts/test-kcli-create-vm.sh test-vm centos10stream 1024 1 10
# Or trigger via Airflow UI:
# - Go to DAGs page
# - Find "example_kcli_script_based"
# - Click play button βΆοΈ
# - Watch it create a real VM!
Check Logs:
# Nginx logs
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
# Airflow logs
podman logs -f airflow_airflow-webserver_1
podman logs -f airflow_airflow-scheduler_1
π Adding SSL/TLS
The deployment is SSL-ready. To add HTTPS:
Option 1: Letβs Encrypt (Recommended for production)
# Install certbot
dnf install -y certbot python3-certbot-nginx
# Get certificate (requires domain name)
certbot --nginx -d yourdomain.com
# Certbot will automatically update nginx config
# Firewall already has port 443 open!
Option 2: Self-Signed Certificate (Testing)
# Generate certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/nginx.key \
-out /etc/ssl/certs/nginx.crt
# Update nginx config
vim /etc/nginx/conf.d/airflow.conf
# Add SSL server block (see template in config file)
# Reload nginx
nginx -t && systemctl reload nginx
π Architecture Diagram
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Internet / Users β
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β Nginx :80 β β Single Entry Point
β (Reverse Proxy)β
ββββββββββ¬βββββββββ
β
βββββββββββββββββ΄ββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββ ββββββββββββββββ
β Airflow β β AI Assistant β
β :8888 βββββββββββββββββ€ :8080 β
β (localhost)β Network β (localhost) β
ββββββββ¬βββββββ Connection ββββββββββββββββ
β
βΌ
βββββββββββββββ
β PostgreSQL β
β :5432 β
βββββββββββββββ
βββββββββββββββ
β libvirt β β VM Management
β :qemu/// β
βββββββββββββββ
Network: airflow_default (podman)
Security: Firewall (firewalld)
π οΈ Customization
Change Nginx Port:
Edit /etc/nginx/conf.d/airflow.conf:
server {
listen 8080; # Change from 80
# ...
}
Update firewall:
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
Add IP Restrictions:
Edit nginx config to allow only specific IPs:
server {
# Existing config...
allow 192.168.1.0/24; # Internal network
allow YOUR_IP_HERE; # Your IP
deny all; # Block everyone else
}
Add Basic Authentication:
# Create password file
htpasswd -c /etc/nginx/.htpasswd admin
# Update nginx config
location / {
auth_basic "Airflow Access";
auth_basic_user_file /etc/nginx/.htpasswd;
# ... rest of proxy config
}
π Updating
Update Airflow:
cd /opt/qubinode_navigator/airflow
./deploy-airflow.sh rebuild
Update Nginx Config:
vim /etc/nginx/conf.d/airflow.conf
nginx -t
systemctl reload nginx
Re-run Full Deployment:
cd /opt/qubinode_navigator
./deploy-qubinode-with-airflow.sh
π¨ Troubleshooting
Issue: Canβt access Airflow UI
Check nginx:
systemctl status nginx
curl http://localhost/
Check firewall:
firewall-cmd --list-services | grep http
Check Airflow:
podman ps | grep airflow
curl http://localhost:8888/
Issue: 502 Bad Gateway
Cause: Backend not responding
Fix:
# Restart Airflow
cd /opt/qubinode_navigator/airflow
podman-compose restart
# Check logs
podman logs airflow_airflow-webserver_1
Issue: SSL Certificate Errors
For Letβs Encrypt:
certbot renew --dry-run
For self-signed:
# Browsers will show warning (expected)
# Click "Advanced" β "Proceed anyway"
π Related Documentation
airflow/NGINX-REVERSE-PROXY-SETUP.md- Detailed nginx guideairflow/DEPLOYMENT-STATUS.md- Current deployment statusairflow/FIREWALL-SETUP.md- Firewall configurationairflow/SUMMARY-AND-NEXT-STEPS.md- Next steps
β Success Criteria
Deployment is successful when:
- All containers running
- Nginx active and serving
- Can access http://YOUR_IP/
- Airflow login page loads
- Can login with admin/admin
- DAGs are visible
- Health check returns healthy
- Direct ports 8888/8080 NOT accessible externally
- Only port 80/443 accessible
π― Production Checklist
Before going to production:
- Add SSL certificate (Letβs Encrypt)
- Change default admin password
- Configure authentication (LDAP/OAuth)
- Set up monitoring/alerting
- Configure log rotation
- Set up backups (database, configs)
- Document runbooks
- Test disaster recovery
- Security scan/audit
- Performance testing
π‘ Tips
- Use a domain name instead of IP for SSL
- Change default passwords immediately
- Enable HTTPS for production
- Monitor logs regularly
- Keep systems updated (dnf update)
- Backup regularly (postgres, configs)
- Test DAGs in dev first
- Use version control for DAG files
π Support
For issues:
- Check logs (nginx, Airflow, podman)
- Review documentation
- Test components individually
- Use AI Assistant for guidance
Status: Production-Ready β Security: Nginx Reverse Proxy β SSL: Ready to configure β Automation: Single-script deployment β