373 lines
16 KiB
Markdown
373 lines
16 KiB
Markdown
# Faro: Docker Engine Management UI
|
|
|
|
> Living project plan. Add ideas to the backlog, record architectural choices in
|
|
> the decision log, and promote accepted work into a milestone.
|
|
|
|
## 1. Product vision
|
|
|
|
Faro is a small, self-hosted control plane for managing one or more Docker
|
|
Engines. It provides a clear web UI, an automation-friendly API, and CLI tools,
|
|
with special attention to easy deployment, reliable backups, and operational
|
|
visibility.
|
|
|
|
The initial product should be useful to an individual operator or a small team.
|
|
It is not intended to replace a full container orchestrator such as Kubernetes.
|
|
|
|
## 2. Product principles
|
|
|
|
- **Easy to deploy:** a single server binary and container image, with sensible
|
|
defaults and a documented Docker Compose installation.
|
|
- **API first:** every management operation available in the UI is exposed by a
|
|
stable, documented API and can be automated.
|
|
- **Safe by default:** destructive actions require explicit confirmation;
|
|
credentials and Docker access are narrowly scoped.
|
|
- **Recoverable:** configuration, metadata, and named volumes can be backed up,
|
|
verified, and restored through repeatable workflows.
|
|
- **Visible:** users can quickly understand engine health, resource usage,
|
|
container state, recent events, and job outcomes.
|
|
- **Small operational footprint:** avoid required external services for the
|
|
single-node installation.
|
|
|
|
## 3. Users and core journeys
|
|
|
|
### Primary users
|
|
|
|
- A self-hosting user managing one or more Docker hosts.
|
|
- A small operations team that needs shared visibility and controlled access.
|
|
- An automation author using the REST API or CLI.
|
|
|
|
### Core journeys
|
|
|
|
1. Deploy Faro with Docker Compose and complete first-run setup.
|
|
2. Register a local or remote Docker Engine and verify connectivity.
|
|
3. View engine, container, image, network, and volume status.
|
|
4. Start, stop, restart, inspect, and view logs for a container.
|
|
5. Create and restore a backup of Faro state and selected Docker volumes.
|
|
6. Diagnose failures through events, job history, logs, and health information.
|
|
7. Perform the same common operations using the CLI or API.
|
|
|
|
## 4. Initial scope
|
|
|
|
### MVP
|
|
|
|
- Single Faro server instance.
|
|
- Local Docker socket and remote Docker Engine connections over TLS/SSH.
|
|
- Engine list and health summary.
|
|
- Read-only inventory for containers, images, volumes, and networks.
|
|
- Container lifecycle operations and streaming logs.
|
|
- Engine event stream and basic CPU, memory, disk, and container metrics.
|
|
- Scheduled and on-demand backups of Faro state and selected named volumes.
|
|
- Local filesystem backup target, with a provider interface for object storage.
|
|
- Backup retention, integrity verification, and guided restore.
|
|
- REST API with an OpenAPI specification.
|
|
- CLI for engines, containers, backups, health, and authentication.
|
|
- Web UI built with Vue 3 and Vuetify0.
|
|
- Web UI page for listing containers from the Docker Engine API.
|
|
- Initial administrator account, API tokens, and a basic audit log.
|
|
- Docker image, Compose file, health check, and upgrade documentation.
|
|
|
|
### Later
|
|
|
|
- Multi-user roles and granular permissions.
|
|
- S3-compatible and other remote backup targets.
|
|
- Compose application/stack management.
|
|
- Image updates, registry management, and vulnerability information.
|
|
- Notifications and alert routing.
|
|
- High availability and multiple Faro server replicas.
|
|
- Agent-based engine connectivity for restricted networks.
|
|
- Swarm-specific management.
|
|
|
|
### Explicitly out of scope for the first release
|
|
|
|
- Kubernetes or non-Docker runtimes.
|
|
- A general-purpose terminal in the browser.
|
|
- Full orchestration or scheduling across engines.
|
|
- Building a container registry.
|
|
|
|
## 5. Proposed architecture
|
|
|
|
```text
|
|
Browser (Vue + Vuetify) CLI
|
|
| |
|
|
+------ HTTPS API ----+
|
|
|
|
|
Faro server (Go)
|
|
+-----------+------------+
|
|
| | |
|
|
SQLite Job runner Event/metric cache
|
|
|
|
|
Docker client layer
|
|
+---------+---------+
|
|
| |
|
|
Local socket Remote engines
|
|
(TLS or SSH)
|
|
```
|
|
|
|
### Backend
|
|
|
|
- Go service organized as a modular monolith.
|
|
- Versioned REST endpoints under `/api/v1`.
|
|
- OpenAPI is the API contract and drives documentation/client generation where
|
|
practical.
|
|
- Docker Engine SDK behind an internal interface so connectivity and tests can
|
|
use alternate implementations.
|
|
- SQLite for the default installation; keep persistence boundaries clean enough
|
|
to support PostgreSQL later if demand justifies it.
|
|
- Persistent job records for backups and other long-running operations.
|
|
- Server-Sent Events (SSE) for logs, events, job progress, and live status;
|
|
introduce WebSockets only if bidirectional streaming becomes necessary.
|
|
- Structured JSON logs and Prometheus-format application metrics.
|
|
- Embed the production frontend in the Go binary for a simple single-artifact
|
|
deployment; allow separate frontend/backend processes in development.
|
|
|
|
### Frontend
|
|
|
|
- Vue 3, TypeScript, Vite, Vuetify 3, Vue Router, and Pinia.
|
|
- Generated or typed API client based on OpenAPI.
|
|
- Primary views: overview, engines, engine detail, containers, container detail,
|
|
storage, backups, jobs, audit log, and settings.
|
|
- Responsive layout, keyboard-accessible actions, clear empty/error/loading
|
|
states, and a dark theme.
|
|
|
|
### CLI
|
|
|
|
- Go CLI shipped as a separate `faroctl` binary.
|
|
- Reuse generated API types/client rather than connecting directly to Docker.
|
|
- Human-readable tables by default; `--output json` for automation.
|
|
- Configuration profiles for server URL and credentials.
|
|
- Stable exit codes, non-interactive flags, and shell completions.
|
|
|
|
## 6. Key domain areas
|
|
|
|
### Engine connections
|
|
|
|
- Store engine name, endpoint type, labels, connection state, and last check.
|
|
- Support local Unix socket, TLS-protected TCP, and SSH connection strategies.
|
|
- Encrypt stored credentials at rest with a user-supplied master key.
|
|
- Never expose Docker credentials or raw private keys through API responses.
|
|
- Use timeouts, reconnect backoff, and explicit capability detection.
|
|
|
|
### Backups and restores
|
|
|
|
- Treat backups as durable jobs with progress, logs, status, and cancellation.
|
|
- Back up Faro's database/configuration separately from Docker volume data.
|
|
- Quiesce supported workloads with optional pre/post hooks; clearly label crash-
|
|
consistent backups when a workload is not paused.
|
|
- Stream volume archives without staging the full archive in memory.
|
|
- Produce a manifest containing versions, contents, timestamps, checksums, and
|
|
source engine identity.
|
|
- Verify checksums after creation and before restore.
|
|
- Apply retention by count and/or age, with a dry-run preview.
|
|
- Restore to an alternate volume name by default; overwriting an existing volume
|
|
requires explicit confirmation.
|
|
- Document recovery when the Faro service itself is unavailable.
|
|
|
|
### Visibility
|
|
|
|
- Engine availability and Docker version.
|
|
- Container state, health check, restart count, uptime, and resource usage.
|
|
- Host CPU, memory, filesystem, and Docker storage usage.
|
|
- Recent Docker events and Faro audit events.
|
|
- Backup/job duration, result, bytes processed, and last successful run.
|
|
- Correlation/request IDs across API errors, jobs, and structured logs.
|
|
|
|
### Security
|
|
|
|
- Document that access to the Docker socket is effectively host-level control.
|
|
- Run the server as a non-root user where the connection method permits it.
|
|
- Password hashing with a modern memory-hard algorithm; short-lived sessions and
|
|
revocable API tokens.
|
|
- CSRF protection for cookie-authenticated browser requests, strict CORS, secure
|
|
headers, request size limits, and rate limiting on authentication endpoints.
|
|
- Audit authentication, engine changes, lifecycle actions, backup restores, and
|
|
token changes without logging secrets.
|
|
- Pin minimal container base images and publish an SBOM and checksums for
|
|
releases.
|
|
|
|
## 7. API outline
|
|
|
|
The exact resources will be defined in OpenAPI before implementation. Candidate
|
|
resource groups:
|
|
|
|
- `/api/v1/session`, `/api/v1/tokens`
|
|
- `/api/v1/engines`
|
|
- `/api/v1/engines/{engineId}/containers`
|
|
- `/api/v1/engines/{engineId}/images`
|
|
- `/api/v1/engines/{engineId}/volumes`
|
|
- `/api/v1/engines/{engineId}/networks`
|
|
- `/api/v1/backup-targets`, `/api/v1/backup-policies`, `/api/v1/backups`
|
|
- `/api/v1/jobs`, `/api/v1/events`, `/api/v1/audit-events`
|
|
- `/api/v1/health`, `/api/v1/version`, `/metrics`
|
|
|
|
API conventions to decide early:
|
|
|
|
- Resource IDs, pagination, filtering, sorting, and timestamp format.
|
|
- Standard error envelope with a stable machine-readable error code.
|
|
- Idempotency behavior for mutating and long-running requests.
|
|
- Optimistic concurrency or preconditions for configuration changes.
|
|
- SSE event envelope, resume behavior, and connection limits.
|
|
- Compatibility and deprecation policy for `/api/v1`.
|
|
|
|
## 8. Delivery milestones
|
|
|
|
Each milestone should end with a runnable increment, documentation, and tests.
|
|
|
|
### M0 — Validate and scaffold
|
|
|
|
- [ ] Confirm target users and the exact MVP scope.
|
|
- [ ] Resolve the open decisions listed below.
|
|
- [ ] Write threat model for Docker access, credentials, and restores.
|
|
- [ ] Create repository layout for server, CLI, web app, API spec, and docs.
|
|
- [ ] Establish formatting, linting, unit tests, and CI.
|
|
- [ ] Add a development Compose environment and sample Docker Engine.
|
|
- [ ] Add a minimal end-to-end smoke test.
|
|
|
|
**Exit:** one command starts the development stack; CI builds and tests all
|
|
components.
|
|
|
|
### M1 — Engine connectivity and read-only inventory
|
|
|
|
- [ ] Implement configuration, database migrations, health, and version APIs.
|
|
- [ ] Add local socket engine registration and connectivity checks.
|
|
- [ ] Add remote TLS and/or SSH connectivity based on the M0 decision.
|
|
- [ ] Implement read-only container, image, volume, and network APIs.
|
|
- [ ] Build overview, engine list, and engine detail UI.
|
|
- [ ] Add equivalent `faroctl engine` and inventory commands.
|
|
- [ ] Add integration tests against supported Docker versions.
|
|
|
|
**Exit:** a user can register an engine and inspect its resources through the
|
|
web UI, CLI, and API.
|
|
|
|
### M2 — Container operations and live visibility
|
|
|
|
- [ ] Add start, stop, restart, and inspect operations with audit records.
|
|
- [ ] Add log streaming with bounded history and redaction guidance.
|
|
- [ ] Consume Docker events and expose an SSE stream.
|
|
- [ ] Collect and display basic engine/container resource metrics.
|
|
- [ ] Add operation confirmation, actionable errors, and reconnect states.
|
|
- [ ] Add permission and failure-path tests.
|
|
|
|
**Exit:** a user can safely operate and troubleshoot containers in near real
|
|
time.
|
|
|
|
### M3 — Backup and restore
|
|
|
|
- [ ] Implement persistent background jobs and progress streaming.
|
|
- [ ] Implement local filesystem target and backup manifests.
|
|
- [ ] Add named-volume backup, checksums, retention, and verification.
|
|
- [ ] Add scheduled backup policies with timezone handling.
|
|
- [ ] Add guided restore, collision protection, and restore validation.
|
|
- [ ] Back up and restore Faro's own state.
|
|
- [ ] Run documented disaster-recovery tests on clean infrastructure.
|
|
|
|
**Exit:** scheduled backups and tested restores work from the UI, CLI, and API.
|
|
|
|
### M4 — Authentication, hardening, and release
|
|
|
|
- [ ] Implement first-run admin setup, sessions, and API tokens.
|
|
- [ ] Encrypt stored engine credentials and define key rotation/recovery.
|
|
- [ ] Complete audit log UI/API and security controls.
|
|
- [ ] Add retention/cleanup for events, metrics, jobs, and audit data.
|
|
- [ ] Load-test event streams, logs, and representative engine counts.
|
|
- [ ] Build a minimal production image, Compose example, and upgrade flow.
|
|
- [ ] Publish operator, backup recovery, API, and CLI documentation.
|
|
- [ ] Add release automation, SBOM, checksums, and signed artifacts.
|
|
|
|
**Exit:** the first supported release can be installed, upgraded, monitored, and
|
|
recovered using published documentation.
|
|
|
|
## 9. Testing strategy
|
|
|
|
- Go unit tests for domain logic, validation, retention, and authorization.
|
|
- API contract tests against the OpenAPI schema.
|
|
- Integration tests using disposable Docker Engines and temporary volumes.
|
|
- Frontend component tests for important state and permission variants.
|
|
- Playwright end-to-end tests for the web UI, including setup, engine
|
|
registration, container operations, backup, and restore.
|
|
- Restore tests must compare checksums and application-level sample data.
|
|
- Compatibility matrix for supported Docker Engine and browser versions.
|
|
- Security checks for dependencies, container images, secrets, and common web
|
|
vulnerabilities.
|
|
|
|
## 10. Deployment and operations
|
|
|
|
Start with three supported modes:
|
|
|
|
1. Docker Compose with Faro connecting to the local Docker socket.
|
|
2. Docker Compose with Faro managing remote engines over TLS/SSH.
|
|
3. Standalone binaries for the server and CLI.
|
|
|
|
Required operational features:
|
|
|
|
- Environment variables and a configuration file, with documented precedence.
|
|
- Persistent data directory and an explicit master-key mechanism.
|
|
- Liveness and readiness endpoints.
|
|
- Graceful shutdown for HTTP streams and active jobs.
|
|
- Schema migration and downgrade/rollback guidance.
|
|
- Configurable structured logs and Prometheus metrics.
|
|
- Versioned release notes with breaking-change and backup warnings.
|
|
|
|
## 11. Open decisions
|
|
|
|
Record the result and rationale in the decision log.
|
|
|
|
- [ ] **D-001:** Confirm Vue 3 + Vuetify 3 (assuming “Vuetify0” was a typo).
|
|
- [ ] **D-002:** Choose the Go HTTP router and OpenAPI generation approach.
|
|
- [ ] **D-003:** Choose database access/migration libraries.
|
|
- [ ] **D-004:** Decide whether the MVP includes both TLS and SSH remote engines.
|
|
- [ ] **D-005:** Define the authentication bootstrap and master-key experience.
|
|
- [ ] **D-006:** Decide whether backups run directly through the Docker API or via
|
|
a short-lived helper container.
|
|
- [ ] **D-007:** Define supported Docker Engine versions and maximum tested scale.
|
|
- [ ] **D-008:** Define license and release/distribution channels.
|
|
- [ ] **D-009:** Choose a metrics retention model: live-only, local time series,
|
|
or integration with an external metrics system.
|
|
|
|
## 12. Success measures
|
|
|
|
Initial targets; adjust after a prototype and user feedback.
|
|
|
|
- A new user can deploy Faro and connect the local engine in under 10 minutes.
|
|
- Common UI operations are also possible through documented CLI/API commands.
|
|
- Engine disconnects and failed jobs are visible with an actionable reason.
|
|
- A backup can be verified and restored on a clean host using only documented
|
|
steps.
|
|
- The idle server has a small, measured CPU and memory footprint.
|
|
- Upgrades preserve configuration and include an explicit recovery path.
|
|
|
|
## 13. Risks and mitigations
|
|
|
|
| Risk | Mitigation |
|
|
| --- | --- |
|
|
| Docker access permits host compromise | Strong warnings, narrow connection options, authentication, audit, and deployment hardening |
|
|
| Volume backups are inconsistent | Pre/post hooks, optional pause, manifests, verification, and clearly stated consistency level |
|
|
| Remote connection setup is difficult | Connection wizard, validation endpoint, actionable diagnostics, TLS/SSH examples |
|
|
| Metrics storage increases product complexity | Start with bounded retention and an export endpoint; defer a full time-series system |
|
|
| UI, CLI, and API behavior diverge | API-first implementation and a shared generated client |
|
|
| Restore destroys existing data | Restore to a new name by default, preview changes, require explicit overwrite confirmation |
|
|
|
|
## 14. Decision log
|
|
|
|
Add one row whenever an open decision is resolved.
|
|
|
|
| ID | Date | Decision | Rationale | Status |
|
|
| --- | --- | --- | --- | --- |
|
|
| D-001 | TBD | Vue/Vuetify version | Awaiting confirmation | Proposed |
|
|
|
|
## 15. Backlog and idea inbox
|
|
|
|
Add unrefined ideas here without disrupting the milestones. Give each accepted
|
|
item an owner and promote it to a milestone when it is ready.
|
|
|
|
| ID | Idea | Why it matters | Priority | Owner | Status |
|
|
| --- | --- | --- | --- | --- | --- |
|
|
| I-001 | S3-compatible backup storage | Keeps backups off-host | Later | — | Idea |
|
|
| I-002 | Compose stack management | Groups related containers into applications | Later | — | Idea |
|
|
| I-003 | Notifications for engine/backup failures | Reduces time to detection | Later | — | Idea |
|
|
|
|
## 16. Change log
|
|
|
|
| Date | Change |
|
|
| --- | --- |
|
|
| 2026-08-06 | Initial project plan created. |
|