From 21bca24cee84cf18d9fd9520f262d0627888889e Mon Sep 17 00:00:00 2001 From: david kiania Date: Wed, 10 Jun 2026 15:31:07 +0300 Subject: [PATCH 1/2] docs: Forgejo->Coolify automatic-deploy runbook (HTML) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs/webhook-auto-deploy.html — step-by-step for push->webhook->Coolify->Traefik auto-deploy: Coolify Gitea webhook URL/secret, the Forgejo webhook, verifying deliveries, the staging/prod model, and a troubleshooting table (Auto Deploy under Advanced, port 80, branch, domain typo, secret). Not served (Dockerfile copies only src/); repo reference doc. Co-Authored-By: Claude Opus 4.8 --- docs/webhook-auto-deploy.html | 173 ++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 docs/webhook-auto-deploy.html diff --git a/docs/webhook-auto-deploy.html b/docs/webhook-auto-deploy.html new file mode 100644 index 0000000..ae10154 --- /dev/null +++ b/docs/webhook-auto-deploy.html @@ -0,0 +1,173 @@ + + + + + +Automatic Deploys — Forgejo → Coolify (FleetOps / FleetNow) + + + +
+
+ + FLEETOPS +
+

Operations runbook · Automatic deploys via Forgejo → Coolify webhooks

+ +

Automatic deploys: push → live

+

+ Every Coolify app (FleetOps + FleetNow, staging & prod) deploys automatically on a + git push. The chain is: +

+
git push  →  Forgejo webhook  →  Coolify rebuilds the app whose branch matches  →  Traefik serves the new container
+

+ Each Coolify application tracks one branch. A push to that branch fires the webhook; + Coolify rebuilds only the app(s) bound to the pushed branch. So staging pushes + deploy the *.fivetitude.com apps, and main merges deploy the + *.rahamafresh.com (prod) apps. +

+ +
+ Prerequisites on the Coolify app before the webhook will do anything: +
    +
  • Auto Deploy = ON — under Configuration → Advanced → Auto Deploy + (not General). The webhook can return 2xx but Coolify ignores it if this is off.
  • +
  • Branch set correctly (staging vs main).
  • +
  • Ports Exposes = 80 (both FleetOps/Caddy and FleetNow/nginx listen on 80).
  • +
  • Domain spelled correctly and attached.
  • +
+
+ +

Part A — Get the webhook URL + secret from Coolify

+
+
    +
  1. Open the application in Coolify.
  2. +
  3. Confirm Configuration → Advanced → Auto Deploy is ON.
  4. +
  5. Go to the app's Webhooks tab → Manual Git Webhooks → + the Gitea section (Forgejo is Gitea-compatible).
  6. +
  7. Copy the Webhook URL (e.g. + https://<coolify-domain>/webhooks/source/gitea/events/manual) + and the Webhook Secret.
  8. +
+
+ +

Part B — Add the webhook in Forgejo

+
+
    +
  1. Open the repo → Settings → Webhooks → Add Webhook → Forgejo/Gitea.
  2. +
  3. Fill in: + + + + + + + + + +
    FieldValue
    Target URLthe Coolify Webhook URL (Part A)
    HTTP MethodPOST
    POST Content Typeapplication/json
    Secretthe Coolify Webhook Secret (must match exactly)
    Trigger OnPush Events (or Custom → Push only)
    Branch filterthe app's branch (staging or main) — optional but tidy
    Activechecked
    +
  4. +
  5. Click Add Webhook.
  6. +
+
+ +

Part C — Verify the delivery

+
+
    +
  1. In Forgejo, go to repo → Settings → Webhooks. Each webhook shows a status dot: + green = last delivery OK, red = failed.
  2. +
  3. Click the webhook to open its page, then click Test Delivery (top-right).
  4. +
  5. Scroll to Recent Deliveries. Click a delivery row to expand it → + open the Response tab → the HTTP status is there. + 2xx = good.
  6. +
  7. Confirm a deployment started in the Coolify app's Deployments list.
  8. +
  9. Real test: push a trivial change to the branch and confirm only the matching app redeploys.
  10. +
+
+ +

Multiple environments (staging + prod)

+

+ There is one Coolify app per environment, each on its own branch, and + each app has its own webhook secret. Add a separate Forgejo webhook per app + (same repo), each with its own URL/secret and branch filter: +

+ + + + + + +
AppDomainBranch
FleetOps stagingfleetops.fivetitude.comstaging
FleetOps prodfleetops.rahamafresh.commain
FleetNow stagingfleetnow.fivetitude.comstaging
FleetNow prodfleetnow.rahamafresh.commain
+

Promotion: feature → staging (auto-deploys staging) → main (auto-deploys prod).

+ +

Troubleshooting

+ + + + + + + + +
SymptomCause & fix
Delivery 2xx but no deployAuto Deploy off. Turn it on at Configuration → Advanced → Auto Deploy.
Delivery 401 / 403Secret mismatch — re-copy the Coolify secret into the Forgejo webhook's Secret field.
Delivery 404 / 502 on the webhookWrong Target URL, or Coolify unreachable.
Site returns 502Coolify "Ports Exposes" ≠ container port. Set it to 80 and redeploy.
Site returns 503 / self-signed certNo healthy backend yet, or the domain doesn't match the Traefik rule (often a domain typo). Fix the domain and redeploy.
Deploys, but it's the wrong codeWrong branch. Set the app's Branch (e.g. staging) in the Source config, Save, then redeploy (Force rebuild).
+ +
+ Never point a prod app at a non-prod branch. The prod apps + (*.rahamafresh.com) must stay on main. Pointing one at staging + would push unreviewed code to the client's live site. +
+ +
+ FleetOps · Fireside Communications fleet stack. See also + docs/STAGING_FLEETOPS_ARCHITECTURE.md in the tracksolid repo for the full topology. +
+
+ + From 2611212fcd62a62793d809e28894859cd2a6dafa Mon Sep 17 00:00:00 2001 From: david kiania Date: Thu, 11 Jun 2026 14:19:56 +0300 Subject: [PATCH 2/2] feat(ui): add Logistics/Tickets tabbed navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Wrap the existing analytics dashboard as the Logistics tab - Add a scaffolded Tickets tab (per-tab KPIs, recent-tickets + by-status cards, informative empty state) - Shared header KPI strip swaps per tab; tickets load lazily on first open - Ticket data source left as a dashboard_api integration point — no S3 credentials embedded in the static SPA Co-Authored-By: Claude Opus 4.8 --- src/index.html | 95 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/src/index.html b/src/index.html index 9a3c041..c8f55a4 100644 --- a/src/index.html +++ b/src/index.html @@ -46,7 +46,7 @@ } .app { display: grid; min-height: 100vh; - grid-template-rows: auto auto 1fr; /* header · filter bar · content */ + grid-template-rows: auto 1fr; /* header · content (tabs/filters live inside each view) */ } /* ── Top bar (mirrors FleetNow) ──────────────────────────────────────── */ @@ -83,6 +83,23 @@ .clock .label { font-size: 9.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; } .clock b { font-weight: 600; } + /* ── Tab nav (segmented control) ─────────────────────────────────────── */ + .tabs { + display: flex; gap: 4px; background: var(--bg); + border: 1px solid var(--border); border-radius: 8px; padding: 3px; + } + .tab { + background: transparent; color: var(--muted); border: 0; border-radius: 6px; + padding: 6px 14px; font-size: 12.5px; font-weight: 700; letter-spacing: .3px; + cursor: pointer; white-space: nowrap; + } + .tab:hover { color: var(--text); } + .tab.active { background: var(--accent); color: #1a1009; } + + /* ── Tabbed views ────────────────────────────────────────────────────── */ + .view { display: none; } + .view.active { display: block; } + /* ── Filter bar ──────────────────────────────────────────────────────── */ .filterbar { padding: 10px 18px; background: var(--panel-2); @@ -163,11 +180,17 @@
FLEETOPS
+
EAT
+
+
@@ -213,6 +236,31 @@
Loading…
+
+ +
+
+
+ +
+ +
+

Recent tickets

+
Loading…
+
+ +
+

By status

+
Loading…
+
+
+
+