Skip to main content

SEO Readiness Portal Cloud Migration — 2026-06-01

SEO Readiness Portal Cloud Migration — 2026-06-01

Date: 2026-06-01 Owner: john Verdict: DONE

Live state verified (2026-06-01 05:31 UTC)

  • curl -sI https://seo-tools.alai.no/api/health → HTTP 302 to alai-no.cloudflareaccess.com/cdn-cgi/access/login/... (CF Access enforced, no anonymous access)
  • curl -sI https://seo-readiness-alai.azurewebsites.net/api/health → HTTP 403 x-ms-forbidden-ip: 46.46.245.169 (Azure origin lock to Cloudflare IPs)

No traffic to John local host: cloudflared route for seo-tools.alai.no and seo-tools.snowit.ba set to http_status:503.

Architecture (now)

Browser → Cloudflare Access (seo-tools.alai.no, alai-no team) → Cloudflare proxied DNS → Azure App Service Linux container seo-readiness-alai (Sweden Central, rg rg-seo-readiness-prod, asp asp-seo-readiness-prod B1) → Next.js standalone in alairegistry.azurecr.io/seo-readiness-portal:20260531-cloud (digest sha256:16c8a40a...) → persistent /home/data/workspace.json

App access mode: SEO_PORTAL_ACCESS_MODE=cf-access, trusted header CF-Access-Authenticated-User-Email, allowed domains snowit.ba,alai.no, extra allowed [email protected].

Evidence

  • Deploy summary: /tmp/alai/seo-readiness-cloud-migration-20260531/cloud-deploy-summary.md
  • Local-disabled proof: /tmp/alai/seo-readiness-cloud-migration-20260531/local-disabled-evidence.txt
  • Azure build + deploy: azure-build.log, azure-webapp-deploy.log, azure-hostname-corrected.log, azure-role-settings.log
  • Origin lock: azure-access-restrict-cloudflare.log, azure-access-restrict-smoke.log
  • DNS upsert: cf-dns-upsert.log
  • Public smoke: public-cloud-smoke.log
  • Origin smoke: azure-smoke.log
  • Authenticated UAT ([email protected], end-to-end: partners → add client → intake → audit → report → markdown export): uat-alem/seo-cloud-uat-result.json + 8 PNG screenshots uat-alem/01-cf-login.png08-export.png
  • Lesson memo: lesson-seo-cloud-origin-lock-20260531.md

Docs corrected (no localhost as final target)

  • DEPLOYMENT-CLOUD.md L7 — explicit "must not be served from John/local localhost"
  • DEPLOYMENT-INTERNAL.md L7, L26, L102 — Docker steps marked local-dev only; cloud origin required for production; explicit "Do not route seo-tools.* to http://127.0.0.1:* or any localhost address"
  • README.md L130 — "Azure App Service Linux container origin, not John/local localhost"
  • BUILD-BLUEPRINT.md L54, L70 — Azure runbook section + CEO correction recorded

Rollback

If Azure origin needs rollback:

  1. Revert Web App container image: az webapp config container set -g rg-seo-readiness-prod -n seo-readiness-alai --container-image-name alairegistry.azurecr.io/seo-readiness-portal:<previous-tag>
  2. CF Access policy and DNS remain unchanged; no public bypass introduced.
  3. Do NOT re-enable cloudflared local route — that violates the CEO correction.

Open follow-ups (separate MCs, not blockers)

  • Postgres swap for /home/data/workspace.json (durable multi-user storage) — pre-req for external product use.
  • seo-tools.snowit.ba DNS/zone provisioning (currently 503).
  • Bind Azure custom hostname TLS managed cert (currently CF terminates).

CEO scope check

  • "Move off John/local host to real cloud" → DONE (Azure App Service)
  • "Cloudflare Access trusted-header preserved" → DONE (SEO_PORTAL_ACCESS_MODE=cf-access)
  • "No public unauthenticated access" → DONE (302 to CF Access login on unauth)
  • "Custom domain toward seo-tools.alai.no" → DONE (CNAME + asuid TXT + Azure binding)
  • "Concrete deploy URL/origin" → DONE (seo-readiness-alai.azurewebsites.net behind seo-tools.alai.no)
  • "UAT evidence" → DONE (alem-authenticated screen-recorded flow)
  • "Rollback" → documented above
  • "Fix docs that recommend local host" → DONE (4 docs updated)

MC / evidence references

  • MC task: #102653
  • Local closure artifact: /tmp/alai/seo-readiness-cloud-migration-20260531/CLOSURE-102653.md
  • Cloud deploy summary: /tmp/alai/seo-readiness-cloud-migration-20260531/cloud-deploy-summary.md
  • Authenticated UAT result: /tmp/alai/seo-readiness-cloud-migration-20260531/uat-alem/seo-cloud-uat-result.json
  • Origin restriction smoke: /tmp/alai/seo-readiness-cloud-migration-20260531/azure-access-restrict-smoke.log
  • P2P verifier PASS: mesh-thr-50503688-7de8-489c-96ca-3d7d1a165dc2

See Also — Agent Runbook

The canonical end-to-end workflow runbook (intake to John deep-report, anti-pitfalls, trigger checklist):