Release ForgeFlow 0.6.0
This commit is contained in:
@@ -1,112 +1,95 @@
|
||||
# SSH / Unraid deployment
|
||||
|
||||
ForgeFlow 0.4 can deploy an exact Gitea commit directly to an Unraid server over SSH.
|
||||
ForgeFlow deploys an exact Gitea commit directly to an Unraid server over pinned SSH.
|
||||
|
||||
## Security model
|
||||
|
||||
- Enter credentials only in the local ForgeFlow desktop window.
|
||||
- Prefer an Ed25519 private key over a password.
|
||||
- ForgeFlow stores passwords and private-key passphrases through Electron safe storage.
|
||||
- The first successful test records the SSH host-key fingerprint.
|
||||
- Later connections fail closed when that fingerprint changes.
|
||||
- Diagnostics redact the Gitea token, SSH password and private-key passphrase.
|
||||
- ForgeFlow never sends arbitrary commands entered through the renderer. Deployment commands are assembled from validated profile fields.
|
||||
- Credentials are entered only in the local ForgeFlow desktop application.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
## Configure the server
|
||||
## Profile identity
|
||||
|
||||
Open **Settings → SSH / Unraid servers → Add server**.
|
||||
|
||||
Typical Unraid values:
|
||||
ForgeFlow separates names that users see from names Docker requires:
|
||||
|
||||
```text
|
||||
Name: Unraid
|
||||
Host: 192.168.1.10
|
||||
Port: 22
|
||||
Username: root
|
||||
Base path: /mnt/user/appdata
|
||||
Auth: Private key
|
||||
Visible project/container: Portfolio
|
||||
Server folder: Portfolio
|
||||
Internal Compose project: portfolio
|
||||
Internal Compose service: portfolio
|
||||
Internal image: forgeflow/portfolio:production
|
||||
```
|
||||
|
||||
Save the server, then choose **Test & trust**. ForgeFlow verifies SSH, Git and Docker Compose and records the host-key fingerprint.
|
||||
The internal Compose service must match the repository's service key and remain lowercase. The visible container can preserve branding and casing.
|
||||
|
||||
## DockerMan WebUI, icon and shell
|
||||
|
||||
ForgeFlow writes `.forgeflow/compose.metadata.yml` and combines it with the repository or generated Compose file. The override supplies:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Icon modes:
|
||||
|
||||
- **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**.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Existing application folder
|
||||
|
||||
Create a deployment profile and choose **SSH / Unraid**.
|
||||
|
||||
For an existing folder:
|
||||
|
||||
```text
|
||||
Server folder: lumaops
|
||||
Remote path: /mnt/user/appdata/lumaops
|
||||
Server folder: Portfolio
|
||||
Remote path: /mnt/user/appdata/Portfolio
|
||||
Compose file: docker-compose.yml
|
||||
```
|
||||
|
||||
ForgeFlow inspects the folder before deployment. An existing deployment is adopted only when the project root is a Git working tree. Tracked server-side changes block deployment. Untracked runtime paths such as `.env`, `appdata`, `data`, `logs`, `config` and `compose.override.yml` remain untouched by `git reset --hard`.
|
||||
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.
|
||||
|
||||
Keep the root `.git` directory. It is used to verify the exact commit, update the working tree and roll back to the previous SHA.
|
||||
|
||||
Nested Git repositories are reported as warnings and are never removed automatically.
|
||||
|
||||
When a Dockerfile is present, preflight also inspects `.dockerignore`. It reports
|
||||
whether `.git` is excluded and warns when existing preserved runtime folders or
|
||||
nested repositories would still be sent as Docker build context. Fix those
|
||||
rules in the repository and commit them rather than changing only the live
|
||||
server copy.
|
||||
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
|
||||
|
||||
For a new project, ForgeFlow creates:
|
||||
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.
|
||||
|
||||
```text
|
||||
/mnt/user/appdata/<repository-name>
|
||||
```
|
||||
|
||||
The Unraid server clones the configured Git URL on the selected branch. The server therefore needs access to that repository, normally through an SSH deploy key or an existing trusted Gitea SSH identity.
|
||||
|
||||
Two Compose modes are available:
|
||||
|
||||
1. **Use repository Compose file** — recommended for real applications. Keep ports, volumes, devices, networks and Unraid labels version-controlled.
|
||||
2. **Generate basic ForgeFlow Compose** — suitable for a simple Dockerfile-based application. ForgeFlow asks for host port, container port, service/container name, Web UI URL and icon URL and writes `.forgeflow/compose.forgeflow.yml`.
|
||||
|
||||
Generated Compose deliberately stays minimal. Projects requiring USB devices, GPU access, custom networks, secrets or multiple services should provide their own Compose file.
|
||||
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 that the local repository is clean, on the allowed branch and fully synchronized with Gitea.
|
||||
2. Verify that the exact requested SHA exists on `origin/<branch>`.
|
||||
3. Verify the repository Compose file or Dockerfile locally.
|
||||
4. Connect through pinned SSH.
|
||||
5. Inspect the target folder.
|
||||
6. Refuse tracked server-only modifications.
|
||||
7. Clone when the folder does not exist.
|
||||
8. Fetch the configured branch without allowing interactive credential prompts.
|
||||
9. Verify again on the server that the requested full SHA belongs to `origin/<branch>`.
|
||||
10. Save the current SHA as the rollback target.
|
||||
11. Reset the working tree to the exact requested SHA.
|
||||
12. Validate the selected Compose file.
|
||||
13. Run `docker compose up -d --build --remove-orphans`.
|
||||
14. Store non-secret state under `.forgeflow/` and run the configured healthcheck.
|
||||
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.
|
||||
|
||||
## Folder names
|
||||
## Interrupted operation recovery
|
||||
|
||||
The default folder is the repository name. Existing deployments can keep another folder name by entering it explicitly in the profile. ForgeFlow does not rename populated application folders automatically because Docker paths, scripts and external integrations may depend on them.
|
||||
|
||||
A later controlled migration can align names after a successful backup and downtime window.
|
||||
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.
|
||||
|
||||
## Rollback
|
||||
|
||||
After a successful deployment, the previous SHA is stored in:
|
||||
|
||||
```text
|
||||
.forgeflow/previous-sha
|
||||
```
|
||||
|
||||
Rollback is accepted only for the exact SHA currently recorded as the previous
|
||||
deployment. ForgeFlow rechecks that SHA against the configured Gitea branch,
|
||||
refuses tracked server-side changes, resets the same working tree, runs Docker
|
||||
Compose again and repeats the healthcheck. The version that was live before the
|
||||
rollback becomes the new rollback target.
|
||||
|
||||
## Before the first real deployment
|
||||
|
||||
Back up the application folder and its persistent data. Run **Preflight** and resolve every failed check. Warnings, such as a nested Git repository, should be reviewed but do not automatically delete or modify anything.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user