This commit is contained in:
NuklearRabbit
2026-07-27 23:15:35 +02:00
parent 03c2608a35
commit f990c26014
18 changed files with 2439 additions and 938 deletions
+23
View File
@@ -0,0 +1,23 @@
# ForgeFlow 0.9.0
ForgeFlow 0.9.0 changes Unraid deployments from a Git-checkout-first workflow into a server-inventory-first workflow.
## Existing installations are now visible
Server Inventory collects a safe, selected subset of Docker, Compose and DockerMan metadata for both running and stopped containers. It recognizes Compose project names, working directories, active Compose files and services, mounts, ports, runtime state, image provenance and existing DockerMan templates. Environment values and other container secrets are not collected.
Exact repository provenance may be linked automatically. Name similarity is never treated as proof: uncertain workloads remain visible as suggestions and can be linked through the new manual wizard. The saved link preserves the workload identity rather than depending on the disposable container ID.
## Push bundle is the new default
New SSH/Unraid profiles use **Push bundle**. ForgeFlow creates a tar archive from the exact local Git commit, calculates its SHA-256 digest and uploads it over the already trusted desktop-to-Unraid SSH connection. Unraid therefore does not need a Git client, Gitea host-key entry or Gitea private key for this mode.
The server verifies the checksum and archive paths, rejects symlink payloads, preserves configured runtime paths, updates only ForgeFlow-managed files and validates the merged Compose model before starting services. The active SHA and managed-file manifest are promoted atomically only after the expected services are running. Failure restoration keeps the previous deployment truth and restores overwritten files and Compose metadata.
**Server-side Git** remains available as an explicit mode. Its Gitea access check is now reported separately from desktop SSH and Docker/Compose capabilities. **Monitor only** links an existing workload without granting ForgeFlow permission to deploy it.
## Safer adoption
Adopted workloads retain their existing Compose project, Compose files and service set. ForgeFlow no longer overrides their image or container name in the metadata overlay. Existing DockerMan templates are left untouched; generated templates are managed only for explicitly generated Compose profiles. `--force-recreate` and `--remove-orphans` are opt-in rather than defaults.
A deployment lock records the live shell process, and an old lock is removed only when it is sufficiently old and its owner no longer runs. Deployment output truncation now fails explicitly instead of allowing ForgeFlow to interpret an incomplete inventory or command result.
+66 -64
View File
@@ -1,6 +1,20 @@
# SSH / Unraid deployment
ForgeFlow deploys an exact Gitea commit directly to an Unraid server over pinned SSH.
ForgeFlow can inventory existing Unraid workloads and deploy an exact Git commit through one of three explicit modes.
## Deployment modes
### Push bundle — default
ForgeFlow creates an archive from the exact local commit and uploads it through the trusted desktop-to-Unraid SSH connection. The Unraid server needs Docker, Docker Compose, `tar` and a SHA-256 checksum tool. It does **not** need Git access or a Gitea key.
### Server-side Git — optional
Unraid fetches the exact commit from Gitea. This mode additionally requires Git, a trusted Gitea host key and a non-interactive Unraid-to-Gitea identity with repository access.
### Monitor only
ForgeFlow inventories and tracks the workload but refuses deploy and rollback operations until another mode is selected.
## Security model
@@ -8,88 +22,76 @@ ForgeFlow deploys an exact Gitea commit directly to an Unraid server over pinned
- Ed25519 private keys are preferred.
- Passwords and key passphrases use Electron safe storage.
- The first trusted connection records the SSH host-key fingerprint; later changes fail closed.
- Unraid-to-Gitea repository access is tested during every deployment preflight.
- ForgeFlow validates the selected private key before saving the server configuration.
- Desktop-to-Unraid authentication, Docker access, Compose availability and optional Unraid-to-Gitea access are reported as separate checks.
- Remote inventory collects selected labels, mounts, ports and runtime state; it does not collect container environment values.
- The renderer cannot submit arbitrary shell commands. Remote scripts are assembled from validated profile fields and transported as base64-encoded Bash input.
- Tracked server-side modifications block deployment and rollback.
- Incomplete SSH output is rejected rather than interpreted.
## Profile identity
## Server Inventory and manual linking
ForgeFlow separates names that users see from names Docker requires:
**Server Inventory** includes running and stopped containers, Compose projects, DockerMan installations and standalone containers even when `/mnt/user/appdata/<app>` is not a Git checkout.
An exact repository remote or trusted provenance label may be linked automatically. Similar names remain suggestions. For an uncertain workload, use **Link workload** and choose:
1. the repository;
2. Push bundle, Server-side Git or Monitor only;
3. the folder below the configured server base path.
The resulting profile preserves the detected Compose project name, Compose files, service set, container metadata and stable workload selector. Linking itself does not recreate a container or rewrite a DockerMan template.
## Compose identity
An adopted installation keeps the identity reported by Docker:
```text
Visible project/container: Portfolio
Server folder: Portfolio
Internal Compose project: portfolio
Internal Compose service: portfolio
Internal image: forgeflow/portfolio:production
Visible container: omniroute
Server folder: OmniRoute
Compose project: omniroute-production
Compose files: compose.yml, compose.unraid.yml
Compose services: api, worker
```
The internal Compose service must match the repository's service key and remain lowercase. The visible container can preserve branding and casing.
ForgeFlow adds `.forgeflow/compose.metadata.yml` as the final Compose overlay. For adopted workloads this overlay adds labels only; it does not replace the existing image or `container_name`.
## DockerMan WebUI, icon and shell
`--force-recreate` and `--remove-orphans` are disabled by default and can be enabled explicitly per profile. Multiple Compose files and services are retained and validated.
ForgeFlow writes `.forgeflow/compose.metadata.yml` and combines it with the repository or generated Compose file. The override supplies:
## DockerMan safety
```text
net.unraid.docker.managed=dockerman
net.unraid.docker.webui=http://[IP]:[PORT:<host-port>]/
net.unraid.docker.icon=<PNG URL or persistent Unraid path>
net.unraid.docker.shell=sh
```
Existing DockerMan templates under `/boot/config/plugins/dockerMan/templates-user` are never rewritten for adopted workloads. ForgeFlow manages a persistent DockerMan template only when all of the following are true:
Icon modes:
- the profile uses ForgeFlow-generated Compose;
- **Manage DockerMan template** is enabled;
- the workload was not adopted from the server.
- **Built-in high-contrast ITWorx mark** — default;
- **Upload local PNG** — copied to `/boot/config/plugins/dockerMan/images/<container>-icon.png`;
- **Use icon URL** — HTTP(S) PNG;
- **No custom icon**.
Metadata repair for an adopted application therefore updates the Compose metadata labels only and leaves the original Unraid template intact.
After metadata changes ForgeFlow recreates the container, writes `/boot/config/plugins/dockerMan/templates-user/my-<container>.xml`, removes known icon caches and invalidates DockerMan's volatile `docker.json` metadata cache. The Unraid Docker page may still need one browser refresh.
## Push bundle sequence
The deployment card reports whether WebUI and icon labels were confirmed through `docker inspect`. **Repair DockerMan integration** recreates an existing healthy container with labels, a persistent DockerMan template, icon cache refresh and WebUI metadata without creating a Git commit. **Open Web UI** uses the profile URL directly from the desktop.
1. Verify the clean local working tree, selected branch, upstream state and exact commit.
2. Verify the exact commit exists on the configured remote branch.
3. Test desktop-to-Unraid SSH, Docker, Compose, `tar`, checksum tooling and deployment storage.
4. Create the release with `git archive` from the exact commit.
5. Upload a temporary `.part` file through SFTP.
6. Verify the SHA-256 digest and reject unsafe paths or symbolic links.
7. Store a retained release manifest and back up files that ForgeFlow is about to manage.
8. Preserve `.forgeflow`, `.git` and configured runtime paths such as `.env`, `data`, `config`, `logs` and application-specific folders.
9. Update only files in the old or new ForgeFlow managed-file manifests; unrelated server files remain untouched.
10. Validate the merged Compose configuration.
11. Start the configured Compose project and verify every selected service has a running container and is not unhealthy.
12. Promote `current-sha`, status and managed-file manifests atomically.
13. Run the optional desktop healthcheck and persist runtime state.
## Existing application folder
If activation fails, ForgeFlow restores the backed-up files and previous Compose metadata, restarts the previous Compose state where possible and leaves the previous active SHA untouched.
For an existing folder:
## Server-side Git sequence
```text
Server folder: Portfolio
Remote path: /mnt/user/appdata/Portfolio
Compose file: docker-compose.yml
```
Server-side Git retains the exact-SHA flow for installations that deliberately keep a checkout on Unraid. Preflight runs `git ls-remote` from Unraid, rejects tracked server edits, verifies the configured origin and checks that the selected SHA belongs to the allowed remote branch. The active SHA is written only after Compose validation and service verification.
The project root must be a Git working tree. Untracked runtime paths such as `.env`, `appdata`, `data`, `logs`, `config` and `compose.override.yml` remain untouched by `git reset --hard`. Nested Git repositories are warnings and never deleted automatically.
## Interrupted operations and locks
Preflight inspects `.dockerignore` when a Dockerfile exists. It warns when `.git`, preserved runtime data or nested repositories would be sent into the build context.
## New application folder
The server clones the configured URL on the selected branch. The Unraid host therefore needs a non-interactive Gitea SSH identity. Preflight runs `git ls-remote --exit-code` from Unraid before deployment.
Use repository Compose for real applications. Generated Compose is intended only for a simple single-service Dockerfile application with basic port mapping.
## Deployment sequence
1. Verify clean local tree, allowed branch, upstream and ahead/behind state.
2. Verify the exact SHA exists on the allowed remote branch.
3. Verify Unraid can read the Gitea repository.
4. Inspect the server folder and refuse tracked server changes.
5. Clone when the folder is absent.
6. Fetch the branch and verify the exact SHA is an ancestor of `origin/<branch>`.
7. Save the previous SHA and reset to the requested SHA.
8. Write generated Compose when selected.
9. Write the DockerMan metadata override and persistent template fallback.
10. Validate the merged Compose model.
11. Run `docker compose up -d --build --remove-orphans --force-recreate`.
12. Clear relevant icon caches.
13. Inspect the visible container and write `.forgeflow/status.json`.
14. Run the configured desktop healthcheck.
15. Persist the live SHA, previous SHA, health, container and DockerMan state.
## Interrupted operation recovery
At startup and through **Reconcile**, ForgeFlow reads the live SHA, container running state, Docker health, labels and persistent template state. When a previously running operation already reached its exact requested SHA and the container is healthy, the operation becomes `success`. Operations that remain unresolved for more than 45 minutes become `failed` rather than staying indefinitely in deployment mode.
A push deployment creates `.forgeflow/deploy.lock` with a request ID, timestamp and shell PID. A lock older than two hours is removed only when its recorded process no longer exists. Startup and **Reconcile** compare the requested SHA with server state and container health; unresolved operations eventually become failed rather than remaining active indefinitely.
## Rollback
Rollback is accepted only for the exact SHA currently recorded as `previousSha`. ForgeFlow re-verifies that commit against Gitea, refuses tracked server changes, resets the same working tree, reapplies Compose and DockerMan metadata, reruns health checks and rotates the former live SHA into the new rollback target.
Rollback is accepted only for the exact `previousSha` recorded for the profile. Push bundle mode recreates that commit archive locally and uses the same checksum, backup, Compose validation and atomic promotion flow. Server-side Git mode verifies and checks out the exact previous commit through its Git workflow.