# 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. |