Files
floci-ui/README.md
T
Zakaria f1574b89df
CI / checks (pull_request) Successful in 26m4s
docs: regenerate the service matrix
Adds Cognito and the services the table had drifted behind on (ECS, Fargate, Lightsail, ElastiCache, MSK, Kinesis and others).
2026-10-23 12:12:40 -04:00

625 lines
23 KiB
Markdown

<p align="center">
<img src="docs/images/floci-black.svg#gh-light-mode-only" alt="Floci UI" width="460" />
<img src="docs/images/floci-white.svg#gh-dark-mode-only" alt="Floci UI" width="460" />
</p>
<p align="center">
<strong>Any Cloud. Locally.</strong><br />
A local-first, cloud-aware runtime console for Floci and compatible local cloud emulators.
</p>
<p align="center">
<a href="https://github.com/floci-io/floci-ui/releases/latest"><img src="https://img.shields.io/github/v/release/floci-io/floci-ui?label=latest%20release&color=blue" alt="Latest Release"></a>
<a href="https://github.com/floci-io/floci-ui/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/floci-io/floci-ui/ci.yml?branch=main&label=ci" alt="CI Status"></a>
<a href="https://hub.docker.com/r/floci/floci-ui"><img src="https://img.shields.io/docker/pulls/floci/floci-ui?label=docker%20pulls" alt="Docker Pulls"></a>
<a href="https://hub.docker.com/r/floci/floci-ui"><img src="https://img.shields.io/docker/image-size/floci/floci-ui/latest?label=image%20size" alt="Docker Image Size"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-green" alt="License: MIT"></a>
</p>
<p align="center">
<img src="docs/images/floci-ui-console.png" alt="Floci UI console" width="900" />
</p>
Floci UI is the web console for the Floci ecosystem. The current app is centered on a unified `Cloud Explorer` and a cloud-aware `Console Home`. It renders only real data returned by local runtimes and explicit placeholders for work that is not wired yet.
No fake resources, no demo rows, and no mock operational data are shown in normal mode.
## Quick Start
AWS-only stack:
```bash
docker compose up
```
Full multi-cloud stack:
```bash
docker compose --profile multicloud up
```
Open [http://localhost:4500](http://localhost:4500).
## Exposing To The Internet
Floci UI requires an administrator username, an Argon2id password hash, and a session secret. Copy `.env.example` to `.env`, generate the hash with `cd packages/api && bun run scripts/hash-password.ts '<password>'`, and generate a session secret with `openssl rand -base64 48`. Do not put plaintext passwords in `.env`.
Put only Floci UI behind Nginx Proxy Manager, terminating TLS there and forwarding to port `4500`. Keep `FLOCI_UI_SECURE_COOKIES=true` in that deployment. Bind Floci core (`4566`) to the Docker network or localhost only: it must not be publicly reachable, because the authenticated UI proxy is the intended access path. Configure Nginx Proxy Manager to pass `X-Forwarded-Proto` and `X-Forwarded-For`, and place Cloudflare or another edge proxy in front of it for public deployments. Set `FLOCI_UI_TRUSTED_PROXIES` to the proxy's IP or CIDR (comma-separated for several hops, e.g. Cloudflare's published ranges when it sits in front of Nginx Proxy Manager); `X-Forwarded-For` is ignored from any other peer, and without it sign-in throttling treats every visitor as the proxy.
Set `FLOCI_UI_AUTH_MODE=oidc` to use an OIDC provider such as Authentik. Configure `FLOCI_UI_OIDC_ISSUER`, `FLOCI_UI_OIDC_CLIENT_ID`, `FLOCI_UI_OIDC_CLIENT_SECRET`, and `FLOCI_UI_PUBLIC_BASE_URL`; the callback is `${FLOCI_UI_PUBLIC_BASE_URL}/api/auth/oidc/callback`. OIDC mode also requires an allow-list: `FLOCI_UI_OIDC_ALLOWED_GROUPS` (matched against the `groups` claim, read from UserInfo when the ID token omits it) and/or `FLOCI_UI_OIDC_ALLOWED_EMAILS` (verified emails only). Set `FLOCI_UI_OIDC_ALLOW_ALL_USERS=true` only if every user of the identity provider should have console access.
## What The UI Actually Exposes Today
The sidebar and Console Home are rendered from `GET /api/clouds/:cloud/services`,
so this table is derived from the service catalog and the adapter registry rather
than maintained by hand. Regenerate it after any change to either:
```bash
cd packages/api && bun run scripts/service-matrix.ts
```
| Group | Service | AWS | Azure | GCP |
|---|---|---|---|---|
| Compute | Compute | Yes (list, inspect, create, delete) | Yes (list, inspect, create, delete) | No |
| Compute | EKS / AKS / GKE | Yes (list, inspect) | Yes (list, inspect) | Yes (list, create, inspect, delete) |
| Compute | Serverless | Yes (list, create, update, inspect, delete) | Runtime gap | Yes (list, create, inspect, delete) |
| Compute | Containers / Cloud Run | No | No | Yes (list, create, delete, inspect) |
| Compute | ECS | Yes (list, create, delete, inspect) | No | No |
| Compute | Fargate | Yes (list, create, delete, inspect) | No | No |
| Compute | Lightsail | Yes (list, create, inspect, update, delete) | No | No |
| Developer Tools | CodeBuild | Yes (list, create, delete, inspect) | No | No |
| Developer Tools | CodePipeline | Yes (list, create, delete, inspect) | No | No |
| Developer Tools | CodeDeploy | Yes (list, create, delete, inspect) | No | No |
| Storage | Storage | Yes (list, create, delete, inspect) | Yes (list, create, delete, inspect) | Yes (list, create, delete, inspect) |
| Storage | ECR / Elastic Container Registry | Yes (list, create, delete, inspect) | No | No |
| Databases | Database | Yes (list, create, update, delete, inspect) | Yes (list, create, delete, inspect) | Yes (list, create, inspect, delete) |
| Databases | DynamoDB / Cosmos DB NoSQL / NoSQL | Yes (list, create, delete, inspect) | Yes (list, create, delete, inspect) | No |
| Databases | ElastiCache | Yes (list, create, delete, inspect) | No | No |
| Networking | Networking | Yes (list) | No | No |
| Networking | ELB / Load Balancing | Yes (list, create, update, delete, inspect) | No | No |
| Networking | ELB Target Groups / Target Groups | Yes (list, create, delete, inspect) | No | No |
| Integration | SQS / Messaging / Pub/Sub | Yes (list, create, inspect, delete) | Yes (list, create, delete, inspect) | Yes (list, create, inspect, delete) |
| Integration | API Gateway | Yes (list, create, delete, inspect) | No | No |
| Integration | SNS / Notifications | Yes (list, create, inspect, delete) | No | No |
| Integration | EventBridge / Events | Yes (list, create, delete, inspect) | No | No |
| Integration | SES Mailbox / Email | Yes (list, inspect) | No | No |
| Integration | Cloud Scheduler | No | No | Yes (list, create, delete, inspect) |
| Integration | Step Functions / Workflows | Yes (list, create, update, delete, inspect) | No | No |
| Analytics | MSK / Managed Streaming for Kafka | Yes (legacy page) | No | No |
| Analytics | MSK Connect / Managed Streaming for Kafka Connect | Yes (legacy page) | No | No |
| Analytics | Kinesis / Kinesis Data Streams | Yes (list, create, inspect, delete) | No | No |
| Provisioning | CloudFormation / Infrastructure as Code | Yes (list, create, update, delete, inspect) | No | No |
| Provisioning | AppConfig / Configuration | Yes (list, create, delete, inspect) | No | No |
| Security | Identity | Yes (list, create, delete, inspect) | No | No |
| Security | Cognito / User Directories | Yes (list, create, delete, inspect) | No | No |
| Security | Secrets Manager / Key Vault / Secret Manager | Yes (list, create, inspect, delete) | Yes (list, create, delete, inspect) | Yes (list, create, inspect, delete) |
| Security | KMS / Key Management | Yes (list, create, delete, inspect) | No | No |
| Security | Parameter Store | Yes (list, create, delete, inspect) | No | No |
| Observability | CloudWatch Logs / Logs | Yes (list, create, delete, inspect) | No | No |
Console Home is available for all three clouds.
Runtime gaps — an adapter exists but the local runtime does not implement it:
- Azure Serverless: the Floci-AZ runtime returns 501 NotImplemented for the Azure Functions endpoint.
Services marked `No` render as a disabled sidebar row whose tooltip carries the
server-supplied reason. Adding one is a catalog row in
`packages/api/src/cloud-spi/serviceCatalog.ts` plus an adapter — no frontend change.
<p align="center">
<img src="docs/images/floci-ui-console-azure.png" alt="Azure console home, showing services grouped by category with per-cloud naming and coming-soon reasons" width="900" />
</p>
Azure on the same build: the nav is grouped by category, `k8s Engine` is labelled
`AKS` for this provider, and every unavailable service carries a reason — Serverless
reads `coming soon` because the Floci-AZ runtime answers 501 for Azure Functions,
even though an adapter is registered.
## Current Capability Snapshot
<details>
<summary><strong>Storage</strong></summary>
Cloud Explorer storage is the most complete unified category today.
- AWS S3 buckets are normalized as `storage` resources with type `bucket`.
- Azure Blob containers are normalized as `storage` resources with type `container`.
- GCP Cloud Storage buckets are normalized as `storage` resources with type `bucket`.
- Shared resource table, shared inspector, runtime status strip, and schema-driven create/delete flows.
- Object/blob browser with prefix navigation.
- Upload, download, delete, copy, and create-folder-prefix actions.
- Azure folder markers are hidden and rendered as folders in the browser.
- Size and last-modified metadata are shown when returned by the runtime.
Current gaps:
- No bulk multi-select actions yet.
- No tag/policy/version management in the unified view.
- Folder creation is prefix-based, not a real filesystem directory.
</details>
<details>
<summary><strong>k8s Engine</strong></summary>
All three clouds, through the unified shell.
- AWS EKS and Azure AKS clusters can be listed and inspected.
- A selected EKS cluster lists its managed nodegroups and Fargate profiles.
- Create and delete managed nodegroups, including role, subnets, instance types, and scaling configuration.
- Create and delete Fargate profiles, including pod execution role, selectors, labels, and optional subnets.
- These nested EKS operations use the unified Cloud Proxy, not the legacy `/api/eks/*` routes.
- GCP GKE clusters can additionally be created and deleted.
- Cluster metadata, node groups, and related details are surfaced when returned by the runtime.
Current gaps:
- EKS and AKS are read-only. On AKS this is a runtime limit rather than a choice:
the shipped floci-az config runs AKS unmocked with no Docker socket to start k3s
with, so a created cluster never leaves `provisioningState: Failed`.
</details>
<details>
<summary><strong>Database</strong></summary>
Relational and document database workflows across providers:
- AWS RDS: list, inspect, create, update, and delete DB instances (PostgreSQL, MySQL, MariaDB) with provider defaults (class `db.t3.micro`, storage 20 GB, username `root`). Updates use generic `PATCH /api/clouds/:cloud/services/:service/resources/:id` mapping to `ModifyDBInstance` for password rotation, IAM authentication, DB subnet group, VPC security groups, option group, and auto minor version upgrade. Instance class, storage, engine, and version are omitted from edit operations because the current local Floci RDS emulator does not support modifying them.
- AWS RDS Snapshots: account-scoped Snapshots tab listing DB snapshots and supporting snapshot creation.
- Azure Cosmos DB NoSQL: database, container, and document workflows.
- AWS DynamoDB: table management, item browsing, and Add record.
- Azure SQL and PostgreSQL Flexible Server: instance management and SQL query editor.
- GCP Cloud SQL: list, inspect, create, and delete database instances.
Cosmos DB includes:
- List, create, and delete databases.
- List, create, and delete containers.
- Create, edit, and delete documents/items.
- SQL query editor for documents.
Choose **Explore data** beside a supported resource to open its dedicated workspace at
`/cloud-explorer/:cloud/:service/:resourceId/data`. DynamoDB records, Cosmos containers
and documents, and Azure SQL/PostgreSQL tables and query results use this workspace.
Cosmos container and SQL database/schema/table selections remain in the URL for bookmarks
and browser history. SQL credentials remain in memory and must be entered again after a reload.
**Back to** returns to the service's resource-management list.
Frontend regression tests use mocked `/api/*` responses and need no running emulator:
`pnpm --filter @floci/frontend exec playwright install chromium`, then
`pnpm --filter @floci/frontend test:e2e`.
Current gaps:
- AWS RDS snapshot creation: the Cloud Proxy operation is available, but the current Floci runtime does not implement `CreateDBSnapshot` (returns a typed 501 `operation_not_implemented`). Snapshot listing returns a valid empty list.
- AWS RDS instance stop/start operations are not implemented in the current local Floci runtime.
</details>
<details>
<summary><strong>Compute</strong></summary>
AWS only, through the unified shell plus AWS-specific panels where the workflow is too rich for a flat generic form.
- List EC2 instances and AMIs as normalized resources.
- Launch instances.
- Start, stop, reboot, and terminate instances.
- Create AMIs.
- Edit tags.
- View console output.
Current gaps:
- No Azure VM or GCP compute adapter yet.
- Compute creation still uses an AWS-specific panel because it needs dependent selectors.
</details>
<details>
<summary><strong>Networking</strong></summary>
AWS only, through the unified shell plus an AWS-specific networking panel.
- VPC list and inspect through the unified resource table.
- VPC creation and delete, the VPC wizard, subnets, security groups, internet
gateways, NAT gateways, route tables, and Elastic IP workflows — all in the
Networking panel.
Current gaps:
- No Azure VNet or GCP VPC adapter yet.
- Create and delete are advertised as `partial` in the unified schema and are
handled by the Networking panel, because they need dependent selectors that a
flat generic form cannot express.
- Advanced multi-cloud networking normalization is still pending.
</details>
<details>
<summary><strong>Identity</strong></summary>
AWS only, through the generic identity service category.
- List and inspect IAM users.
- Create and delete IAM users.
- IAM user paths are supported during creation.
Current gaps:
- Roles, groups, policies, access keys, and other advanced IAM workflows are not exposed yet.
- No Azure or GCP identity adapter yet.
</details>
<details>
<summary><strong>API Gateway</strong></summary>
AWS only, through the generic apigateway service category.
- List and inspect REST APIs.
- Create and delete REST APIs.
Current gaps:
- Resources, methods, deployments, and stages are not yet exposed.
- No Azure or GCP API Gateway adapter yet.
</details>
<details>
<summary><strong>Email / SES Mailbox</strong></summary>
AWS SES email capture through the unified Cloud Explorer.
- Lists emails actually captured by Floci SES.
- Filters by subject, sender, and recipient.
- Inspects sender, recipients, timestamp, and message type.
- Displays HTML in a sandboxed preview, text bodies, and captured raw MIME data.
- Clears the captured inbox after an explicit confirmation.
Manual verification with the AWS CLI:
```bash
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
aws ses send-email \
--endpoint-url http://localhost:4566 \
--from sender@example.test \
--destination 'ToAddresses=recipient@example.test' \
--message 'Subject={Data="Floci SES test",Charset=utf-8},Body={Text={Data="Plain-text test email.",Charset=utf-8},Html={Data="<h1>Hello from Floci</h1><p>This should render in the SES preview.</p>",Charset=utf-8}}'
```
The email is captured by the local Floci runtime; it is not delivered externally. Open
`/cloud-explorer/aws/email` and refresh the mailbox to inspect its Preview, Text, and
Raw views. You can also inspect the captured messages directly with:
```bash
curl http://localhost:4566/_aws/ses
```
Current gaps:
- Sending a test email from the UI is not wired yet; applications continue to send through their AWS SES SDK.
- SES identities, templates, bulk email, configuration sets, and suppression lists are not exposed yet.
- No Azure or GCP email adapter yet.
</details>
<details>
<summary><strong>Serverless</strong></summary>
AWS and GCP, both through the unified shell.
- AWS Lambda and GCP Cloud Functions list, create, inspect, and delete.
- AWS Lambda invoke is wired, including the tailed execution log and handler errors.
- Lambda creation packages inline code into a real deployment archive.
- The navigation entry appears for any cloud with a registered adapter.
Current gaps:
- Azure Functions is registered but the Floci-AZ runtime answers 501 NotImplemented,
so it reports `coming_soon` with that reason rather than appearing available.
- GCP Cloud Functions invoke is not wired yet; the capability is advertised as
`coming_soon` instead of being silently missing.
- Old AWS Lambda page is gone; all future work should stay in the unified model.
</details>
<details>
<summary><strong>Containers</strong></summary>
GCP Cloud Run, through the unified shell.
- List, inspect, deploy, and delete Cloud Run services.
- Image, container port, URL, traffic split, and generation are surfaced.
- Deploying really starts a container: the runtime launches the requested image.
Readiness is reported honestly. A deploy settles at `PENDING` and then becomes
`SUCCEEDED` or `FAILED`; the runtime's own explanation is kept in
`metadata.terminalMessage`. The usual cause of `FAILED` is a container that does
not listen on the port given by `$PORT` (8080 by default) — `nginx:alpine`
listens on 80 and fails for exactly that reason, so the create form says so.
Current gaps:
- No AWS ECS or Azure Container Apps adapter yet.
- No revision history, traffic splitting, or scaling controls.
- Deleting a service while it is still `PENDING` can race the create; deleting a
settled service is durable.
</details>
<details>
<summary><strong>Secrets Manager</strong></summary>
This is the only dedicated AWS page still outside Cloud Explorer.
- List secrets.
- Inspect metadata.
- Reveal current value on demand.
- Create secrets.
- Update values.
- Delete secrets, including force delete.
Current gaps:
- Not migrated into the Cloud Explorer contract yet.
- No Azure or GCP secret adapter yet.
</details>
## Product Direction
Floci UI is evolving toward a metadata-driven, cloud-aware console where one web app can render multiple local runtimes through the same shell.
The guiding rules are:
- The UI does not know clouds.
- The proxy does not know internal implementations.
- The SPI defines the contracts.
- The adapters perform the translation.
- The runtimes execute the real behavior.
## Architecture
![Floci Unified UI Multi-Cloud Architecture](docs/images/floci-unified-ui-architecture.png)
Short implementation notes live in [docs/implementation-notes.md](docs/implementation-notes.md).
## Project Structure
```text
packages/
api/
src/
cloud-spi/
registry/
adapter-aws/
adapter-azure/
adapter-gcp/
routes/
service/
frontend/
src/
api/
components/
features/
pages/
```
High-level runtime flow:
```text
Browser
-> frontend (React/Vite)
-> /api/clouds/*
-> Cloud Adapter Registry
-> provider adapter
-> local runtime
```
## Setup
### Docker Compose
Default compose stack:
- `floci-ui` on `http://localhost:4500`
- `floci-api` on `http://localhost:4501`
- `floci` on `http://localhost:4566`
Start AWS-only:
```bash
docker compose up
```
Start AWS + Azure + GCP:
```bash
docker compose --profile multicloud up
```
Convenience targets:
```bash
make up
make up-multicloud
make down
make logs
```
### Manual Local Development
Prerequisites:
- Node.js 20+
- pnpm 9+
- Bun
- A running local runtime: Floci core, and optionally Floci-AZ / Floci-GCP
Install dependencies:
```bash
pnpm install
```
Configure the API environment:
```bash
cp .env.example packages/api/.env
```
Important: the API runs from `packages/api` and loads environment variables from `packages/api/.env`.
Start Floci AWS Core with Docker:
```bash
docker run -d --name floci \
-p 4566:4566 \
-v /var/run/docker.sock:/var/run/docker.sock \
-e FLOCI_DEFAULT_REGION=us-east-1 \
-u root \
floci/floci:latest
```
Or from a local clone:
```bash
git clone https://github.com/floci-io/floci.git ../floci
cd ../floci
./mvnw clean quarkus:dev
```
Optional local runtimes:
- Floci-AZ on `http://localhost:4577`
- Floci-GCP on `http://localhost:4588`
Start the UI stack:
```bash
pnpm dev
```
That starts:
- frontend on `http://localhost:4500`
- API on `http://localhost:4501`
Split commands:
```bash
pnpm dev:api
pnpm dev:web
```
## Environment
Default API environment values:
```bash
FLOCI_ENDPOINT=http://localhost:4566
FLOCI_AZURE_ENDPOINT=http://localhost:4577
FLOCI_AZURE_ACCOUNT_NAME=devstoreaccount1
FLOCI_GCP_ENDPOINT=http://localhost:4588
FLOCI_GCP_PROJECT=floci-local
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
PORT=4501
```
`VITE_MOCK_MODE=false` is kept in `.env.example`, but the current app is intended to run against real local runtimes.
## Verification
```bash
pnpm lint
pnpm type-check
pnpm test
pnpm build
```
## Troubleshooting
### `http proxy error` or `ECONNREFUSED` on `/api/*`
The frontend is up, but the API is not reachable on `http://localhost:4501`.
Check:
```bash
pnpm dev:api
curl http://localhost:4501/api/clouds
```
### `EADDRINUSE` on port `4501`
Another API process is already running. Stop it first or kill the process holding port `4501`.
### Runtime shows `Not connected` or `Runtime unavailable`
Check the runtime directly:
```bash
curl http://localhost:4566/_floci/health
curl http://localhost:4577/_floci/health
curl http://localhost:4588/_floci-gcp/health
curl http://localhost:4501/api/clouds/aws/status
curl http://localhost:4501/api/clouds/azure/status
curl http://localhost:4501/api/clouds/gcp/status
```
### A single service shows as unavailable while the cloud is connected
Cloud status reflects the runtime; each service is probed separately. Ask which
service is failing and why:
```bash
curl http://localhost:4501/api/clouds/azure/status?services=all
curl http://localhost:4501/api/clouds/azure/services/serverless/status
```
`errorCode` distinguishes the cases: `operation_not_implemented` means the local
runtime does not implement that service, `runtime_unavailable` means it cannot be
reached, and `operation_not_supported` means no adapter is registered.
### Credentials or endpoint mismatch
For AWS local development, keep API credentials aligned with the runtime:
```bash
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
```
## Contributing
When adding new UI surface:
- Prefer the Cloud Explorer and Cloud Proxy model over new legacy pages.
- Reuse the SPI contracts before creating provider-specific response shapes.
- Keep placeholders explicit instead of inventing fake data.
- Update this README when the visible UI surface changes.
## Community Projects
Floci UI is the first-party console, but it is not the only one. The community builds
consoles for Floci too:
- [floci-dash](https://github.com/ofsazib/floci-dash) — an AWS-Console-style dashboard
for the Floci AWS runtime built on Cloudscape Design. It ships as a single Docker image
and includes an EC2 web terminal. It targets the AWS runtime only, while Floci UI also
covers Azure and GCP, so pick whichever fits your stack.
Building something for Floci? Open a PR to add it here.
## License
[MIT](LICENSE) — part of the [Floci](https://floci.io) ecosystem.