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:

  1. AI Assistant - RAG-powered assistant
  2. Apache Airflow - Workflow orchestration with kcli/virsh
  3. Nginx Reverse Proxy - Secure single entry point
  4. Firewall Configuration - Proper security rules
  5. 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:

  1. Base infrastructure deployment
  2. Airflow workflow orchestration setup
  3. Nginx reverse proxy configuration
  4. Firewall security rules
  5. 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:

  1. Open browser: http://YOUR_SERVER_IP/
  2. Login: admin / admin
  3. Enable DAGs you want to run
  4. 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:

# 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"
  • airflow/NGINX-REVERSE-PROXY-SETUP.md - Detailed nginx guide
  • airflow/DEPLOYMENT-STATUS.md - Current deployment status
  • airflow/FIREWALL-SETUP.md - Firewall configuration
  • airflow/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

  1. Use a domain name instead of IP for SSL
  2. Change default passwords immediately
  3. Enable HTTPS for production
  4. Monitor logs regularly
  5. Keep systems updated (dnf update)
  6. Backup regularly (postgres, configs)
  7. Test DAGs in dev first
  8. Use version control for DAG files

πŸ“ž Support

For issues:

  1. Check logs (nginx, Airflow, podman)
  2. Review documentation
  3. Test components individually
  4. Use AI Assistant for guidance

Status: Production-Ready βœ… Security: Nginx Reverse Proxy βœ… SSL: Ready to configure βœ… Automation: Single-script deployment βœ