Try the Live Demo | π Documentation | Quick Start | Features
This service provides a centralized UI and API similar to ArgoCD for managing Flux across multiple Kubernetes clusters.
This allows an easy to access and manage method to view, validate, and remediate FluxCD configurations on clusters at scale
The Flux Orchestrator consists of:
- Backend API (Go): RESTful API server that manages clusters and Flux resources
- Frontend UI (React/TypeScript): Modern web interface for visualization and management
- Database: PostgreSQL or MySQL for storing cluster configurations and cached resource states
- Kubernetes Integration: Direct integration with Kubernetes API for multi-cluster management
- Kubernetes cluster (central management cluster)
- PostgreSQL or MySQL database
- Go 1.21+ (for development)
- Node.js 18+ (for frontend development)
-
Clone the repository
git clone https://github.com/Forcebyte/flux-orchestrator.git cd flux-orchestrator -
Start a database
Option A: PostgreSQL
docker run -d \ --name postgres \ -e POSTGRES_DB=flux_orchestrator \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -p 5432:5432 \ postgres:15-alpine
Option B: MySQL
docker run -d \ --name mysql \ -e MYSQL_DATABASE=flux_orchestrator \ -e MYSQL_USER=flux \ -e MYSQL_PASSWORD=flux \ -e MYSQL_ROOT_PASSWORD=rootpass \ -p 3306:3306 \ mysql:8
-
Generate an encryption key
# Using Python python3 -c "import base64; import os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())" # Or using Go go run ./tools/generate-key/main.go
-
Start the backend
For PostgreSQL:
export DB_DRIVER=postgres export DB_HOST=localhost export DB_PORT=5432 export DB_USER=postgres export DB_PASSWORD=postgres export DB_NAME=flux_orchestrator export DB_SSLMODE=disable export PORT=8080 export ENCRYPTION_KEY="your-generated-key-here" go run backend/cmd/server/main.go
For MySQL:
export DB_DRIVER=mysql export DB_HOST=localhost export DB_PORT=3306 export DB_USER=flux export DB_PASSWORD=flux export DB_NAME=flux_orchestrator export PORT=8080 export ENCRYPTION_KEY="your-generated-key-here" go run backend/cmd/server/main.go
-
Start the frontend
cd frontend npm install npm run dev -
Access the UI Open http://localhost:3000 in your browser
The easiest way to deploy is using one of the pre-built images:
# Pull the latest image
docker pull ghcr.io/forcebyte/flux-orchestrator:latest
# Or use a specific version/branch
docker pull ghcr.io/forcebyte/flux-orchestrator:main-
Update the image and database configuration
Edit
deploy/kubernetes/manifests.yaml:- Update the image to use
ghcr.io/forcebyte/flux-orchestrator:latest - Configure database settings (PostgreSQL is included by default)
- Update database password in the Secret
- Update the image to use
-
Deploy to Kubernetes
kubectl apply -f deploy/kubernetes/manifests.yaml
This will create:
flux-orchestratornamespace- ServiceAccount with RBAC permissions
- PostgreSQL StatefulSet (or configure your own database)
- Flux Orchestrator Deployment
- LoadBalancer Service
-
Access the application
# Via port-forward kubectl port-forward -n flux-orchestrator svc/flux-orchestrator 8080:80 # Or get the LoadBalancer IP kubectl get svc -n flux-orchestrator flux-orchestrator
Open http://localhost:8080 in your browser
To use an external PostgreSQL or MySQL database instead of the bundled one:
- Remove the PostgreSQL StatefulSet from
deploy/kubernetes/manifests.yaml - Update the ConfigMap with your database connection details:
apiVersion: v1 kind: ConfigMap metadata: name: flux-orchestrator-config namespace: flux-orchestrator data: DB_DRIVER: "postgres" # or "mysql" DB_HOST: "your-db-host" DB_PORT: "5432" # or "3306" for MySQL DB_USER: "your-user" DB_NAME: "flux_orchestrator" DB_SSLMODE: "require" # for PostgreSQL PORT: "8080"
- Update the Secret with your database password
- Navigate to the "Clusters" page
- Click "+ Add Cluster"
- Provide:
- Cluster Name: A friendly name for your cluster
- Description: Optional description
- Kubeconfig: Paste the kubeconfig content for the cluster
- Click "Add Cluster"
The orchestrator will connect to the cluster and check its health status.
- Click on a cluster to view its Flux resources
- Resources are organized by type:
- Kustomizations
- HelmReleases
- GitRepositories
- HelmRepositories
- View status, last reconciliation time, and messages
- Single Resource: Click "Reconcile" button on any resource
- All Resources: Click "Sync All Resources" in cluster detail view
The dashboard provides an overview of all resources across all clusters:
- Total resource count
- Status breakdown (Ready/Not Ready/Unknown)
- Resources grouped by cluster
| Variable | Description | Default |
|---|---|---|
ENV |
Environment mode (development, dev, or production) |
production |
DB_DRIVER |
Database driver (postgres or mysql) |
postgres |
DB_HOST |
Database host | localhost |
DB_PORT |
Database port | 5432 |
DB_USER |
Database user | postgres |
DB_PASSWORD |
Database password | postgres |
DB_NAME |
Database name | flux_orchestrator |
DB_SSLMODE |
SSL mode (PostgreSQL only) | disable |
ENCRYPTION_KEY |
Fernet encryption key for kubeconfigs | (Required) |
PORT |
API server port | 8080 |
SCRAPE_IN_CLUSTER |
Enable in-cluster scraping | false |
IN_CLUSTER_NAME |
Name for in-cluster configuration | in-cluster |
IN_CLUSTER_DESCRIPTION |
Description for in-cluster | Local cluster... |
| Timeouts and Performance | ||
HTTP_READ_TIMEOUT_SECONDS |
HTTP server read timeout | 30 |
HTTP_WRITE_TIMEOUT_SECONDS |
HTTP server write timeout | 30 |
HTTP_IDLE_TIMEOUT_SECONDS |
HTTP server idle timeout | 120 |
SHUTDOWN_TIMEOUT_SECONDS |
Graceful shutdown timeout | 30 |
REQUEST_TIMEOUT_SECONDS |
Individual request timeout | 30 |
K8S_REQUEST_TIMEOUT_SECONDS |
Kubernetes API timeout | 30 |
DB_MAX_OPEN_CONNS |
Max open database connections | 25 |
DB_MAX_IDLE_CONNS |
Max idle database connections | 5 |
DB_CONN_MAX_LIFETIME_MINUTES |
Connection max lifetime | 5 |
| Webhook Notifications | ||
WEBHOOK_URLS |
Comma-separated webhook URLs | - |
| OAuth Configuration | ||
OAUTH_ENABLED |
Enable OAuth authentication | false |
OAUTH_PROVIDER |
OAuth provider (github or entra) |
- |
OAUTH_CLIENT_ID |
OAuth app client ID | - |
OAUTH_CLIENT_SECRET |
OAuth app client secret | - |
OAUTH_REDIRECT_URL |
OAuth callback URL | http://localhost:8080/api/v1/auth/callback |
OAUTH_SCOPES |
Comma-separated OAuth scopes | - |
OAUTH_ALLOWED_USERS |
Comma-separated allowed user emails (optional) | - |
The service exposes several health check endpoints:
/healthand/healthz: Basic health check (returns 200 OK)/readiness: Readiness probe that checks database connectivity and Kubernetes client/liveness: Liveness probe for Kubernetes (returns 200 OK)
These endpoints are useful for Kubernetes probes and load balancer health checks.
Structured Logging: The application uses zap for structured logging. Set ENV=development for human-readable logs.
Metrics: Prometheus metrics are exposed at /metrics and include:
- HTTP request counts and durations
- Cluster health status
- Flux resource counts by type and status
- Reconciliation counts and errors
- Sync worker performance
- Database query metrics
Request Tracing: All HTTP requests include a unique request_id in logs for tracing.
Flux Orchestrator supports optional OAuth authentication with GitHub and Microsoft Entra (Azure AD). When enabled, users must authenticate before accessing the application.
Quick Setup:
- Create OAuth App (GitHub or Azure AD)
- Configure Environment Variables:
OAUTH_ENABLED=true OAUTH_PROVIDER=github # or "entra" OAUTH_CLIENT_ID=your_client_id OAUTH_CLIENT_SECRET=your_client_secret OAUTH_REDIRECT_URL=http://localhost:8080/api/v1/auth/callback - Restart Application
For detailed setup instructions, see OAuth Authentication Guide.
Flux Orchestrator implements multiple layers of security:
Input Protection:
- Input validation middleware detecting SQL injection patterns
- Path traversal protection
- Command injection detection
- XSS pattern filtering
- Header length validation
HTTP Security Headers:
- Content-Security-Policy (CSP)
- HTTP Strict Transport Security (HSTS) in production
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- X-XSS-Protection
- Referrer-Policy
Request Protection:
- Configurable request timeouts
- Connection pooling limits
- Rate limiting via middleware
Dependency Security:
- Automated dependency updates via Dependabot
- Weekly security patch scanning
- Grouped minor/patch updates
All kubeconfig data is encrypted at rest using Fernet (AES-128-CBC with HMAC-SHA256) before being stored in the database. This ensures that even with direct database access, the kubeconfig contents cannot be read without the encryption key.
Setup:
- Generate an encryption key:
python3 -c "import base64; import os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())" - Set the
ENCRYPTION_KEYenvironment variable - Store the key securely (Kubernetes Secret, secrets manager, etc.)
For more details, see Encryption Guide.
Flux Orchestrator includes a comprehensive Role-Based Access Control system for managing user permissions:
Built-in Roles:
- Administrator: Full access to all resources, users, and settings
- Operator: Can manage clusters and resources but not users or system settings
- Viewer: Read-only access to all resources
Custom Roles: Create custom roles with specific permissions through the Settings > RBAC interface.
Permission Model:
cluster.*- Cluster management (create, read, update, delete)resource.*- Flux resource operations (read, reconcile, suspend, resume, update, delete)user.*- User managementrole.*- Role managementsetting.*- System settingsazure.*- Azure AKS integration
Configuration:
- Enable OAuth authentication (GitHub or Microsoft Entra)
- Users are automatically created on first login with "Viewer" role
- Administrators can assign roles through Settings > RBAC
- Configure role permissions to match your organization's needs
The orchestrator requires the following Kubernetes permissions:
- Read access to Flux CRDs (Kustomizations, HelmReleases, GitRepositories, etc.)
- Update/Patch access to trigger reconciliations
- List access to namespaces
See deploy/kubernetes/manifests.yaml for the complete RBAC configuration.
Flux Orchestrator can automatically discover and manage AKS clusters using Azure service principals. This provides seamless integration with your Azure infrastructure without manually exporting kubeconfig files.
-
Azure Service Principal with permissions:
- Azure Kubernetes Service Cluster User Role
- Reader role on subscription or resource groups
-
kubelogin installed on the server running Flux Orchestrator:
# Install kubelogin brew install Azure/kubelogin/kubelogin # macOS # OR download from: https://github.com/Azure/kubelogin/releases
-
Create a Service Principal:
az ad sp create-for-rbac --name flux-orchestrator-sp --role "Azure Kubernetes Service Cluster User Role" --scopes /subscriptions/{subscription-id} -
Note the credentials from the output:
appIdβ Client IDpasswordβ Client Secrettenantβ Tenant ID
-
Add Azure Subscription in the UI:
- Go to Settings β Azure AKS tab
- Click "Add Subscription"
- Enter your subscription details and service principal credentials
- Click "Test Connection" to verify
-
Discover and Sync Clusters:
- Click the π icon to discover AKS clusters
- Review the list of discovered clusters
- Click "Sync" to import all clusters
Clusters imported from Azure will be marked with a βοΈ badge and can be managed like any other cluster.
For detailed Azure integration documentation, see Azure AKS Integration.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE file for details
