--- status: active owner: platform last_reviewed: 2026-09-29 supersedes: [] --- # Deployment guide — Venture Studio products **Phase 1 promotion workflow** (standardized scripts): ```bash cd ~/studio # Dev (alternate ports — never touches prod systemd) bash scripts/run-product-dev.sh start # Prod — canonical path (sync main + test-gate + deploy + smoke + health) # Prerequisite: PR develop→main merged, CI green bash scripts/promote-product.sh # Prod — lower-level (same gates, no automatic git pull; must already be on synced main) bash scripts/deploy-product.sh ``` **Pre-deploy gates (enforced by deploy-product.sh unless overridden):** | Gate | Command | Skip override | |------|---------|---------------| | Branch | `main` only | `ALLOW_PROD_DEPLOY=1` (emergency develop/hotfix) | | Git sync | local HEAD = `origin/main` | `SKIP_GIT_SYNC_CHECK=1` | | Test suite | `make test-gate` (~8–12 min) | `SKIP_TEST_GATE=1` | **Pre-merge gates (PR develop → main — not optional):** | Gate | Command | Blocks | |------|---------|--------| | CI parity | `make pre-merge` (~2–5 min) | VM/CI drift, corrupted lockfiles | | GitHub Actions | All workflows green on PR | Merge with broken CI | See [RELEASE_POLICY.md](./RELEASE_POLICY.md). **`make test-gate` alone does not authorize merge.** `make test` (fast, ~30s) is for CI and local iteration — **not sufficient alone before prod deploy**. | Product ID | Dev stack | Prod deploy | |------------|-----------|-------------| | `studio` | `:4003` UI · API `:9003` | `dashboard/.devops/deploy-prod.sh` | | `astra` | `:4101` UI | `astra-ai-cos/.devops/deploy-prod.sh` | | `careeros` | `:4102` UI | `careeros/.devops/deploy-prod.sh` | | `legal-copilot` | `:4104` UI | `legal-copilot/.devops/deploy-prod.sh` | | `deal-finder` | `:9105` / `:4105` | `deal-finder/.devops/deploy-prod.sh` | | `blueprint` | `:4209` UI (API dev `:9003`) | `utilities/blueprint/.devops/deploy-prod.sh` | | `retired` | `:9107` / `:4107` | `retired/.devops/deploy-prod.sh` | See `docs/operations/PORT_SCHEME.md` for the `4Hxx` dev UI convention. **Rules:** - **Canonical prod path:** merge to `main` → `bash scripts/promote-product.sh ` (sync main → test-gate → deploy). - Deploy only from `main`. Emergency non-main: `ALLOW_PROD_DEPLOY=1`. - **Push before deploy:** local `main` must match `origin/main` (unpushed commits will block deploy). - Run `make test-gate` before any prod deploy; `make test` alone is not enough. - Each product has `deploy-prod.sh`, `run-dev-stack.sh`, and `smoke-test.sh` under `.devops/`. - Canonical ports and health URLs: `products/registry.yaml`. ### Public `/dev/studio/` hub (duckdns) Single develop entry: **https://studio-venky.duckdns.org/dev/studio/** Nginx proxies on-demand Next.js stacks. **502 is expected** when that stack is not running. | URL | Start command | |-----|---------------| | https://studio-venky.duckdns.org/dev/studio/ | `bash scripts/run-product-dev.sh studio start` | | https://studio-venky.duckdns.org/dev/studio/utilities/blueprint/ | `bash scripts/run-product-dev.sh blueprint start` | | https://studio-venky.duckdns.org/dev/studio/astra/ | `bash scripts/run-product-dev.sh astra start` | | https://studio-venky.duckdns.org/dev/studio/careeros/ | `bash scripts/run-product-dev.sh careeros start` | | https://studio-venky.duckdns.org/dev/studio/legal/ | `bash scripts/run-product-dev.sh legal-copilot start` | | https://studio-venky.duckdns.org/dev/studio/deals/ | `bash scripts/run-product-dev.sh deal-finder start` | | | `bash scripts/run-product-dev.sh retired start` | Stop when done: `bash scripts/run-product-dev.sh studio stop` (same for other ids). --- Deploy scripts validate, build, restart services, and run smoke tests. **Always pull latest git first** on production. ```bash cd ~/studio git pull origin ``` ## Astra AI-CoS (primary product) ```bash cd ~/studio/products/saas/astra-ai-cos # Backend (Docker API on :8001) bash .devops/deploy-backend.sh # Frontend (Next on :3001, path /ai-cos/) bash .devops/deploy-frontend.sh ``` `deploy-frontend.sh` gates (when all deps present): 1. `validate-frontend.sh` — no hardcoded localhost, TypeScript build 2. Clean `next build` 3. `systemctl restart astra-frontend` 4. Runtime smoke (local + public URL) 5. Regression `smoke-test.sh` (164+ checks) 6. Visual smoke (Playwright, desktop + mobile) 7. E2E + accessibility smoke 8. Legal Copilot UI (if enabled) Checklist: [products/saas/astra-ai-cos/.devops/DEPLOYMENT_CHECKLIST.md](../../products/saas/astra-ai-cos/.devops/DEPLOYMENT_CHECKLIST.md) ## Astra Legal Copilot ```bash bash ~/studio/products/saas/legal-copilot/.devops/deploy.sh ``` Also deployed automatically as step 7/7 of Astra frontend deploy when legal subsystem is enabled. ## CareerOS ```bash cd ~/studio/products/saas/careeros bash .devops/deploy.sh # if present — see product README ``` ## Studio launcher ```bash bash ~/studio/dashboard/.devops/install-production.sh ``` ## Full stack after VM reboot ```bash ~/studio/scripts/start-venture-stack.sh ~/studio/scripts/status-venture-stack.sh ``` ## Nginx Astra has **no separate nginx site**. Public traffic reaches it through the canonical `studio-venky` router (`/astra/` → `127.0.0.1:3101`); the config lives with the dashboard (`dashboard/.devops/nginx-studio-venky.conf`, synced by `dashboard/.devops/sync-nginx.sh`). The former `.devops/nginx-astra-site.conf` and `.devops/sync-nginx.sh` were retired: the `astra-venky.duckdns.org` name has no DNS record and no TLS cert, so enabling that site made `nginx -t` fail and nginx could not be restarted. ## Migrations Astra (run after Postgres is up): ```bash cd ~/studio/products/saas/astra-ai-cos bash scripts/apply-all-migrations.sh # Or individual: bash scripts/run-044-migration.sh ``` ## Rollback - Backend: `bash .devops/rollback-backend.sh 1` (if backups enabled) - Frontend: redeploy previous git commit + `deploy-frontend.sh` ## Environment prerequisites - Secrets in `.env` files — [SECRETS_MANAGEMENT.md](./SECRETS_MANAGEMENT.md) - `playwright-core` in Astra frontend for visual/E2E smokes: `cd frontend && npm i -D playwright-core && npx playwright-core install chromium` ## Related - [SYSTEM_INVENTORY.md](./SYSTEM_INVENTORY.md) — ports and URLs - [DISASTER_RECOVERY.md](./DISASTER_RECOVERY.md) — new VM path