1- # CodeFlow Website Deployment Guide
1+ # CodeFlow Website Deployment Guide
22
3- This document describes the Next.js website and Azure deployment setup for codeflow.io.
3+ This document describes the Next.js website and Azure deployment setup for
4+ ` codeflow.celladoresystems.com ` .
5+
6+ > ** Canonical doc.** This is the single source of truth for website deployment.
7+ > ` website/docs/DEPLOYMENT.md ` is a pointer to this file — don't let the two
8+ > drift again; edit only this one.
49
510## Overview
611
712The CodeFlow Engine website is a Next.js application that provides:
813- ** Home Page** : Project promotion and key features
9- - ** Installation Guide** : Step-by-step installation instructions
14+ - ** Installation Guide** : Step-by-step installation instructions
1015- ** Download Page** : Links to various download methods (GitHub, PyPI, Docker)
1116
1217## Architecture
1318
1419### Technology Stack
1520
16- - ** Framework** : Next.js 16+ with App Router
17- - ** Styling** : Tailwind CSS 4
21+ - ** Framework** : Next.js (static export, ` output: "export" ` )
22+ - ** Styling** : Tailwind CSS
1823- ** Deployment** : Azure Static Web Apps
19- - ** CI/CD** : GitHub Actions
24+ - ** CI/CD** : GitHub Actions ( ` .github/workflows/deploy-website.yml ` )
2025
2126### Azure Resources
2227
23- All resources follow the naming convention: ` {env}-{resourcetype}-{region}-codeflow `
24-
25- #### Production Resources
26-
27- - ** Static Web App** : ` prod-stapp-san-codeflow `
28- - ** Resource Group** : ` prod-rg-san-codeflow `
29- - ** Location** : ` eastus2 ` (East US 2) - Static Web Apps are only available in: westus2, centralus, eastus2, westeurope, eastasia
30- - ** Custom Domain** : ` codeflow.io `
28+ Live resources (celladore-sub, recreated 2026-08-19 from the old
29+ phoenixvc-owned ` pvc-* ` resources — see
30+ ` orchestration/infrastructure/CEL_MIGRATION_PLAN.md ` for the full cutover
31+ history):
32+
33+ - ** Static Web App** : ` cel-prod-codeflow-swa `
34+ - ** Resource Group** : ` cel-prod-codeflow-rg `
35+ - ** Location** : ` eastus2 `
36+ - ** SKU** : Free tier (supports up to 2 custom domains — sufficient for this site)
37+ - ** Custom Domain** : ` codeflow.celladoresystems.com `
38+
39+ There is no CDN or Application Insights component provisioned for this site —
40+ only the Static Web App itself. If you need those, they'd have to be added
41+ first, not just documented.
42+
43+ ### Infrastructure as Code
44+
45+ The Terraform stack for this site lives at
46+ ` orchestration/infrastructure/terraform/website/ ` (this repo's canonical live
47+ Terraform for the website — see the root ` CLAUDE.md ` ). As of 2026-08-19 it has
48+ ** never been successfully applied** : no backend is configured (only
49+ ` backend.tf.example ` exists) and no state tracks the live resources, which
50+ were created out-of-band via ` az ` CLI. A first real ` terraform apply ` needs
51+ ` terraform import ` for the resource group and the Static Web App first, or it
52+ will try to create duplicates. See that stack's own ` README.md ` for the exact
53+ apply sequence and known gaps — don't treat it as already the deployment
54+ mechanism; the GitHub Actions workflow below is what actually ships the site
55+ today.
56+
57+ There is no ` infrastructure/bicep/ ` directory in this repo — ignore any prior
58+ references to Bicep-based deployment for this site.
3159
3260## Local Development
3361
@@ -43,113 +71,109 @@ Visit `http://localhost:3000` to view the site.
4371
4472### Automatic Deployment
4573
46- The website is automatically deployed when:
47- - Changes are pushed to the ` main ` branch in the ` website/ ` directory
74+ ` .github/workflows/deploy-website.yml ` deploys automatically when:
75+ - Changes are pushed to the ** ` master ` ** branch touching ` website/** ` or the
76+ workflow file itself
4877- The workflow is manually triggered via ` workflow_dispatch `
4978
50- ### Manual Deployment
79+ A pull request touching those paths runs a separate build-only validation job
80+ (no deploy).
5181
52- 1 . ** Build the site** :
53- ``` bash
54- cd website
55- npm run build
56- ```
82+ The deploy job builds with ` npm ci ` + ` npm run build ` , then uploads the static
83+ export in ` website/out ` via ` Azure/static-web-apps-deploy@v1 `
84+ (` skip_app_build: true ` — the action does not rebuild, it just uploads what
85+ the workflow already built).
5786
58- 2 . ** Deploy using Azure CLI** :
59- ``` bash
60- npm install -g @azure/static-web-apps-cli
61- swa deploy ./out --deployment-token < YOUR_TOKEN>
62- ```
63-
64- ### Infrastructure Deployment
65-
66- To deploy the Azure infrastructure:
87+ ### Manual Deployment
6788
6889``` bash
69- # Create resource group first (if it doesn't exist)
70- az group create \
71- --name prod-rg-san-codeflow \
72- --location " eastus2"
73-
74- # Deploy the Static Web App
75- az deployment group create \
76- --resource-group prod-rg-san-codeflow \
77- --template-file infrastructure/bicep/website.bicep \
78- --parameters @infrastructure/bicep/website-parameters.json
79- ```
90+ cd website
91+ npm run build
8092
81- ** Note:** The resource group must exist before deploying the Static Web App. The Static Web App will be created in the specified resource group.
93+ npm install -g @azure/static-web-apps-cli
94+ swa deploy ./out --deployment-token < YOUR_TOKEN>
95+ ```
8296
8397## Configuration
8498
85- ### Required GitHub Secrets
99+ ### Required GitHub Secret
86100
87- - ` AZURE_STATIC_WEB_APPS_API_TOKEN ` : Deployment token from Azure Static Web App
88- - ` AZURE_SUBSCRIPTION_ID ` : Azure subscription ID
89- - ` AZURE_CLIENT_ID ` : Service principal client ID (for infrastructure deployment)
90- - ` AZURE_CLIENT_SECRET ` : Service principal client secret
91- - ` AZURE_TENANT_ID ` : Azure AD tenant ID
101+ - ` AZURE_STATIC_WEB_APPS_API_TOKEN ` : deployment token for ` cel-prod-codeflow-swa ` .
102+ If unset, the deploy step is skipped and the workflow just confirms the
103+ build succeeded (see the "Skip deploy when token is missing" step).
92104
93105### Getting the Deployment Token
94106
95- After creating the Static Web App, retrieve the deployment token:
96-
97107``` bash
98108az staticwebapp secrets list \
99- --name prod-stapp-san- codeflow \
100- --resource-group prod-rg-san- codeflow \
109+ --name cel- prod-codeflow-swa \
110+ --resource-group cel- prod-codeflow-rg \
101111 --query " properties.apiKey" \
102112 --output tsv
103113```
104114
105- ## Custom Domain Setup
115+ ### Environment variables
106116
107- 1 . ** Deploy the infrastructure** (if not already done)
117+ There is no ` NEXT_PUBLIC_API_URL ` or other runtime env var wired into the
118+ site. ` APP_URL ` / ` API_URL ` are compile-time constants in
119+ ` website/app/config/constants.ts ` — edit that file directly and redeploy
120+ rather than looking for a ` .env.production ` .
108121
109- 2 . ** Get domain validation token** :
110- ``` bash
111- az staticwebapp hostname show \
112- --name prod-stapp-san-codeflow \
113- --resource-group prod-rg-san-codeflow \
114- --hostname codeflow.io
115- ```
116-
117- 3 . ** Add DNS TXT record** to your domain provider:
118- - Record type: TXT
119- - Name: ` asuid.codeflow.io ` (or as specified by Azure)
120- - Value: (validation token from step 2)
122+ ## Custom Domain Setup
121123
122- 4 . ** Wait for validation** (usually 5-10 minutes)
124+ The custom domain is already live. This is the sequence that was actually
125+ used, for reference if it ever needs to be redone:
123126
124- 5 . ** Add CNAME record** (if not automatically created):
125- - Record type: CNAME
126- - Name: ` codeflow.io ` (or ` www.codeflow.io ` )
127- - Value: ` {static-web-app-name}.azurestaticapps.net `
127+ 1 . ` celladore-org/infrastructure/dns ` (Cloudflare, zone ` celladoresystems.com ` )
128+ owns the ` codeflow.celladoresystems.com ` CNAME pointing at the Static Web
129+ App's default hostname. This repo does not own that DNS record.
130+ 2 . Once the CNAME resolves, bind the custom domain on the Static Web App:
131+ ``` bash
132+ az staticwebapp hostname set \
133+ --name cel-prod-codeflow-swa \
134+ --resource-group cel-prod-codeflow-rg \
135+ --hostname codeflow.celladoresystems.com
136+ ```
137+ 3 . Azure provisions the SSL certificate automatically (` cname-delegation `
138+ validation, no TXT record needed since DNS already points at the SWA
139+ default hostname).
140+ 4 . Verify:
141+ ``` bash
142+ az staticwebapp hostname show \
143+ --name cel-prod-codeflow-swa \
144+ --resource-group cel-prod-codeflow-rg \
145+ --hostname codeflow.celladoresystems.com
146+ ```
147+ or simply ` curl -I https://codeflow.celladoresystems.com/ ` and check for
148+ ` 200 ` with a valid cert.
128149
129150## Project Structure
130151
131152```
132153website/
133- ├── app/
134- │ ├── page.tsx # Home page
135- │ ├── installation/
136- │ │ └── page.tsx # Installation guide
137- │ ├── download/
138- │ │ └── page.tsx # Download page
139- │ ├── layout.tsx # Root layout
140- │ └── globals.css # Global styles
141- ├── public/ # Static assets
142- ├── next.config.ts # Next.js configuration
143- ├── package.json
144- └── README.md
145-
146- infrastructure/bicep/
147- ├── website.bicep # Azure infrastructure definition
148- ├── website-parameters.json # Deployment parameters
149- └── README-WEBSITE.md # Infrastructure documentation
154+ ├── app/
155+ │ ├── page.tsx # Home page
156+ │ ├── installation/
157+ │ │ └── page.tsx # Installation guide
158+ │ ├── download/
159+ │ │ └── page.tsx # Download page
160+ │ ├── config/
161+ │ │ └── constants.ts # APP_URL / API_URL etc. (compile-time)
162+ │ ├── layout.tsx # Root layout
163+ │ └── globals.css # Global styles
164+ ├── public/ # Static assets
165+ ├── next.config.ts # Next.js configuration
166+ ├── package.json
167+ └── README.md
168+
169+ orchestration/infrastructure/terraform/website/
170+ ├── main.tf # Resource group + Static Web App + custom domain
171+ ├── variables.tf
172+ ├── outputs.tf
173+ └── README.md # Apply sequence, known gaps (see above)
150174
151175.github/workflows/
152- └── deploy-website.yml # CI/CD pipeline
176+ └── deploy-website.yml # CI/CD pipeline
153177```
154178
155179## Next.js Configuration
@@ -171,41 +195,47 @@ This ensures compatibility with Azure Static Web Apps.
171195
172196## Monitoring
173197
174- - ** Azure Portal** : Monitor Static Web App metrics, logs, and performance
175- - ** GitHub Actions** : View deployment status and logs
176- - ** Custom Domain** : Monitor DNS and SSL certificate status
198+ - ** GitHub Actions** : deployment status and build logs
199+ - ** Azure Portal** : Static Web App overview for basic traffic/availability
200+ (no Application Insights component is provisioned — don't expect
201+ app-level telemetry beyond that)
202+ - ** Custom Domain** : DNS and SSL certificate status via
203+ ` az staticwebapp hostname show ` (see above)
177204
178205## Troubleshooting
179206
180207### Build Failures
181208
182- - Check Node.js version (requires 20+ )
209+ - Check Node.js version (workflow uses 20 )
183210- Verify all dependencies are installed
184211- Review build logs in GitHub Actions
185212
186213### Deployment Failures
187214
188- - Verify ` AZURE_STATIC_WEB_APPS_API_TOKEN ` is correct
189- - Check Azure Static Web App exists and is accessible
215+ - Verify ` AZURE_STATIC_WEB_APPS_API_TOKEN ` is set in repo secrets — if it's
216+ missing, the workflow silently skips the deploy step instead of failing
217+ - Check ` cel-prod-codeflow-swa ` exists and is accessible
190218- Review deployment logs in GitHub Actions
191219
192220### Custom Domain Issues
193221
194- - Verify DNS records are correct
195- - Check domain validation status in Azure Portal
196- - Ensure SSL certificate is provisioned (automatic for Static Web Apps)
197-
198- ## Cost Estimation
222+ - Verify the CNAME in ` celladore-org/infrastructure/dns ` still resolves
223+ - Check domain validation status in Azure Portal or via
224+ ` az staticwebapp hostname show `
225+ - A transient cert-mismatch right after DNS changes is expected — the CNAME
226+ can resolve before Azure finishes binding the custom domain
199227
200- - ** Static Web App (Standard)** : ~ $9/month
201- - ** Custom Domain** : Included
202- - ** Bandwidth** : 100 GB included, then $0.08/GB
228+ ## Cost
203229
204- Total estimated monthly cost: ~ $9-15 depending on traffic.
230+ Live SKU is ** Free tier** — no static-web-app hosting cost for this site at
231+ current traffic. If usage ever requires moving to Standard, re-check current
232+ Azure pricing before quoting a number here; don't assume a stale figure.
205233
206234## References
207235
208236- [ Next.js Documentation] ( https://nextjs.org/docs )
209237- [ Azure Static Web Apps Documentation] ( https://learn.microsoft.com/azure/static-web-apps/ )
210- - [ GitHub Actions for Azure] ( https://github.com/azure/login )
211-
238+ - ` orchestration/infrastructure/CEL_MIGRATION_PLAN.md ` — full cutover history
239+ (DNS, custom domain, and the celladore-sub recreate-and-cutover)
240+ - ` orchestration/infrastructure/terraform/website/README.md ` — Terraform apply
241+ sequence and known gaps
0 commit comments