> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# DEPLOYMENT

# Metabind CMS Deployment Guide

## Environments

### Development

* **URL**: [https://dev.metabind.ai](https://dev.metabind.ai)
* **API**: [https://api-dev.metabind.ai](https://api-dev.metabind.ai)
* **WebSocket**: wss\://ws-api-dev.metabind.ai
* **CDN**: [https://cdn-dev.metabind.ai](https://cdn-dev.metabind.ai)
* **Branch**: `develop`
* **Deployment**: Automatic on merge

### Production

* **URL**: [https://www.metabind.ai](https://www.metabind.ai)
* **API**: [https://api.metabind.ai](https://api.metabind.ai)
* **WebSocket**: wss\://ws-api.metabind.ai
* **CDN**: [https://cdn.metabind.ai](https://cdn.metabind.ai)
* **Branch**: `main`
* **Deployment**: Manual approval required

## Deployment Process

### Development Deployment (Automatic)

1. Create feature branch from `develop`
2. Make changes and test locally
3. Create PR to `develop`
4. After review, merge PR
5. **Automatic deployment** to dev.metabind.ai

### Production Deployment (Manual Approval)

1. Ensure all changes are tested on dev environment
2. Create PR from `develop` to `main`
3. Review changes thoroughly
4. Merge PR to `main`
5. GitHub Actions will request **manual approval**
6. Go to Actions tab → Click on the workflow run → Review and approve
7. Deployment proceeds to [www.metabind.ai](http://www.metabind.ai)

### Release Creation (Optional)

For formal releases with version tags:

1. Go to Actions → "Create Release" workflow
2. Click "Run workflow"
3. Enter version (e.g., `v1.0.0`)
4. Check "pre-release" if applicable
5. This creates a release branch and draft release

## Infrastructure

### AWS Resources

**Web app (`apps/web`)**

* S3: `metabind-frontend-dev`, `metabind-frontend-prod`
* CloudFront: `E37V5H2J99LGBJ` (dev.metabind.ai), `EAMI96CJSLZDO` ([www.metabind.ai](http://www.metabind.ai))
* CloudFront Function: `metabind-spa-router-dev` / `metabind-spa-router-prod` (`scripts/cloudfront-spa-router-{dev,prod}.js`)

**Admin app (`apps/admin`)**

* S3: `metabind-admin-frontend-dev`, `metabind-admin-frontend-prod`
* CloudFront: `E2MNYOF85I3JOS` (admin-dev.metabind.ai), `EB5ZZU3F8KVDC` (admin.metabind.ai)

**Demos distribution (MET-1095, hosts `apps/mcpdemo` and any future demo SPAs)**

* S3: `metabind-demos-frontend-dev`, `metabind-demos-frontend-prod` *(prod not provisioned yet)*
* CloudFront: `E3MLU9J4RCFSFL` (demos-dev.metabind.ai), *prod TBD*
* CloudFront Function: `metabind-demos-router-dev` / `metabind-demos-router-prod` (`scripts/cloudfront-demos-router-{dev,prod}.js`) — generic path-prefix SPA router; rewrites `/<app>` and `/<app>/*` to `/<app>/index.html`. Adding a new demo does NOT require editing this function.
* Hosted demos:
  * `https://demos-dev.metabind.ai/mcpdemo/` — `apps/mcpdemo` (deployed)

**BindJS iframe renderer**

* S3: `composer-assets-dev-545009866099`, `composer-assets-prod-545009866099`
* CloudFront: `E328NBYMS2ZFH8` (dev), `E1QSR9ILBT29B6` (prod)

**Route53**: Managed DNS in zone `Z04180633NM341WZWTA7Z` (`metabind.ai`).

### Demos distribution — operating guide

#### Provisioning a NEW environment (one-time per env)

The demos distribution is created/maintained by `scripts/setup-demos-distribution.sh`. It's idempotent — re-running it is safe.

```bash theme={null}
# Dev
AWS_PROFILE=yap ./scripts/setup-demos-distribution.sh dev

# Prod (run only when first prod-ready demo is ready to ship)
AWS_PROFILE=yap ./scripts/setup-demos-distribution.sh prod
```

After a successful run the script prints the resulting `DISTRIBUTION_ID`, `BUCKET_NAME`, and `FUNCTION_NAME`. **For prod**, after the first run, paste the printed `DISTRIBUTION_ID` into:

* `package.json`: replace `__DEMOS_PROD_DIST_ID__` in the `deploy:prod:mcpdemo*` scripts.
* `scripts/deploy-demos-cloudfront-function.sh`: replace the empty `DISTRIBUTION_ID=""` in the prod branch.

The dev `DISTRIBUTION_ID` (`E3MLU9J4RCFSFL`) is already wired in.

#### Adding a NEW demo app

1. Build it with `base: '/<app-name>/'` in its Vite config (mirrors what `apps/mcpdemo/vite.config.ts` does).

2. Add deploy scripts to root `package.json` mirroring the mcpdemo pattern:

   ```json theme={null}
   "deploy:dev:<app>": "bash ./scripts/deploy-frontend-demo.sh ./apps/<app>/dist metabind-demos-frontend-dev E3MLU9J4RCFSFL <app>",
   "deploy:dev:<app>:local": "AWS_PROFILE=yap bash ./scripts/deploy-frontend-demo.sh ./apps/<app>/dist metabind-demos-frontend-dev E3MLU9J4RCFSFL <app>",
   "deploy:prod:<app>": "bash ./scripts/deploy-frontend-demo.sh ./apps/<app>/dist metabind-demos-frontend-prod __DEMOS_PROD_DIST_ID__ <app>",
   "deploy:prod:<app>:local": "AWS_PROFILE=yap bash ./scripts/deploy-frontend-demo.sh ./apps/<app>/dist metabind-demos-frontend-prod __DEMOS_PROD_DIST_ID__ <app>"
   ```

3. Build + deploy: `pnpm run deploy:dev:<app>:local`

4. Live at `https://demos-dev.metabind.ai/<app>/` — no infrastructure changes needed.

#### Updating the demos CloudFront Function

The function is generic and shouldn't need code changes. If it does:

1. Edit `scripts/cloudfront-demos-router-{dev,prod}.js`.
2. `AWS_PROFILE=yap ./scripts/deploy-demos-cloudfront-function.sh dev`
3. Same for prod when ready.

#### E2E validation

```bash theme={null}
AWS_PROFILE=yap ./scripts/test-met1095-e2e.sh dev
```

Asserts: bucket has the deployed demo, all URL shapes (no slash, trailing slash, sub-routes) resolve correctly, asset paths are content-typed correctly, HTTP redirects to HTTPS, TLS cert is the wildcard.

### Environment Variables

Environment-specific configs are set during build:

* `VITE_API_URL`: API endpoint
* `VITE_WS_URL`: WebSocket endpoint
* `VITE_CDN_URL`: CDN endpoint
* `VITE_ENV`: Environment name
* `VITE_USER_POOL_ID`: Cognito User Pool ID
* `VITE_USER_POOL_CLIENT_ID`: Cognito User Pool Client ID

## Local Development

### Setup

```bash theme={null}
# Install dependencies
pnpm install

# Copy environment file
cp .env.example .env.local

# Start development server
pnpm run dev
```

### Building Locally

```bash theme={null}
# Build for development
pnpm run build-app

# Build for production (with prod env vars)
VITE_API_URL=https://api.metabind.ai pnpm run build-app
```

### Manual Deployment

```bash theme={null}
# Deploy to dev (requires AWS credentials)
pnpm run deploy:dev:local

# Deploy to prod (requires AWS credentials)
pnpm run deploy:prod
```

## Security

### GitHub Secrets Required

* `AWS_ACCESS_KEY_ID`: AWS deployment credentials
* `AWS_SECRET_ACCESS_KEY`: AWS deployment credentials

### Production Environment Protection

* Requires manual approval from designated reviewers
* Configure in: Settings → Environments → production

## Rollback Procedure

### Quick Rollback

1. Go to GitHub Actions
2. Find the last successful deployment
3. Click "Re-run all jobs"
4. Approve deployment

### S3 Versioning Rollback

1. Go to AWS S3 Console
2. Navigate to the production bucket
3. Use "Show versions" to see previous deployments
4. Restore previous version if needed

## Monitoring

### CloudFront Cache

* Invalidations happen automatically on deploy
* Manual invalidation: `aws cloudfront create-invalidation --distribution-id EAMI96CJSLZDO --paths '/*'`

### Deployment Status

* Check GitHub Actions for deployment logs
* CloudFront distribution status in AWS Console
* Test endpoints after deployment

## Team Workflow

### Feature Development

1. Create feature branch from `develop`
2. Implement and test locally
3. Create PR to `develop`
4. Code review by team
5. Merge triggers auto-deploy to dev

### Production Release

1. Test thoroughly on dev environment
2. Create release PR from `develop` to `main`
3. Team reviews release notes
4. Merge PR (doesn't auto-deploy)
5. Designated approver triggers production deployment
6. Verify production deployment

## Important Notes

1. **Never commit** `.env.local` or any file with secrets
2. **Always test** on dev before releasing to prod
3. **CloudFront cache** takes \~5-10 minutes to fully propagate
4. **DNS changes** can take up to 48 hours (though usually much faster)
5. **Production deployments** should be done during low-traffic periods

## Troubleshooting

### Build Failures

* Check Node.js version (should be 20)
* Verify PNPM version matches workflows
* Clear node\_modules and pnpm store

### Deployment Failures

* Check AWS credentials are valid
* Verify S3 bucket permissions
* Check CloudFront distribution status

### Cache Issues

* Force CloudFront invalidation
* Clear browser cache
* Check cache headers in S3

For additional help, check the GitHub Actions logs or contact the team lead.
