Deployment
Vault uses Cloudflare for all deployments: Workers for the API, Pages for the web app, and Workers Assets for static sites.
Environments
| Environment | Purpose | Trigger |
|---|---|---|
| Staging | Testing | Push to main |
| Production | Live | Push to production |
URLs
| Package | Staging | Production |
|---|---|---|
| Web | vault-staging.pages.dev | vault.oxc.sh |
| API | vault-api-staging.workers.dev | vault-api.workers.dev |
| Docs | vault-docs-staging.oxc.dev | docs.vault.oxc.sh |
| CDN | — | vault-cdn.oxc.dev |
Deployment Commands
Web App
# Deploy to staging (automatic on main push)
pnpm --filter @pwm/web deploy:staging
# Deploy to production
pnpm --filter @pwm/web deploy:productionAPI
# Deploy to staging
pnpm --filter @pwm/api deploy:staging
# Deploy to production
pnpm --filter @pwm/api deploy:productionDocumentation
# Deploy to staging
pnpm --filter @pwm/docs deploy:staging
# Deploy to production
pnpm --filter @pwm/docs deploy:productionCDN
# Deploy static assets
pnpm --filter @pwm/cdn deploy:productionGit Workflow
Feature Development
# 1. Create feature branch
git checkout -b feature/OXC-123-description origin/main
# 2. Develop and commit
git commit -m "feat(OXC-123): add feature"
# 3. Push and create PR
git push -u origin feature/OXC-123-description
gh pr create
# 4. Merge triggers staging deploymentProduction Release
# 1. Ensure main is up to date
git checkout main
git rebase origin/main
# 2. Update CHANGELOG.md
git commit -m "docs: add CHANGELOG for vX.Y.Z"
# 3. Rebase production on main
git checkout production
git rebase main
# 4. Push to trigger production deployment
git push origin main
git push origin production --force-with-leaseWrangler Configuration
API (packages/api/wrangler.toml)
name = "vault-api"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[vars]
API_URL = "https://vault-api.workers.dev"
[[kv_namespaces]]
binding = "KV"
id = "abc123..."
[env.staging]
name = "vault-api-staging"
kv_namespaces = [
{ binding = "KV", id = "staging-kv-id" }
]
[env.production]
name = "vault-api-production"
kv_namespaces = [
{ binding = "KV", id = "production-kv-id" }
]Web (packages/web/wrangler.toml)
name = "vault-web"
pages_build_output_dir = "./dist"
[env.staging]
name = "vault-staging"
[env.production]
name = "vault-production"
routes = [{ pattern = "vault.oxc.sh", custom_domain = true }]Docs (packages/docs/wrangler.toml)
name = "vault-docs"
compatibility_date = "2025-12-18"
assets = { directory = "./docs/dist" }
[env.staging]
name = "vault-docs-staging"
routes = [{ pattern = "vault-docs-staging.oxc.dev", custom_domain = true }]
[env.production]
name = "vault-docs-production"
routes = [{ pattern = "docs.vault.oxc.sh", custom_domain = true }]Environment Variables
API Secrets
# Set secret for staging
wrangler secret put JWT_SECRET --env staging
# Set secret for production
wrangler secret put JWT_SECRET --env productionWeb Environment
Build-time variables in .env:
VITE_API_URL=https://vault-api.workers.dev
VITE_MOCK_AUTH=false
CI/CD Pipeline
GitHub Actions
name: Deploy
on:
push:
branches: [main, production]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v2
- name: Install
run: pnpm install
- name: Typecheck
run: pnpm typecheck
- name: Test
run: pnpm test
- name: Deploy to Staging
if: github.ref == 'refs/heads/main'
run: |
pnpm --filter @pwm/api deploy:staging
pnpm --filter @pwm/web deploy:staging
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- name: Deploy to Production
if: github.ref == 'refs/heads/production'
run: |
pnpm --filter @pwm/api deploy:production
pnpm --filter @pwm/web deploy:production
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}Rollback
Quick Rollback
# Rollback production to previous commit
git checkout production
git reset --hard HEAD~1
git push --force-with-leaseSpecific Version Rollback
# Find commit to rollback to
git log --oneline production
# Reset to specific commit
git checkout production
git reset --hard <commit-sha>
git push --force-with-leaseMonitoring
Cloudflare Dashboard
- Workers: Request counts, errors, latency
- KV: Storage usage, read/write ops
- Pages: Build status, deployment history
Logs
# Tail API logs
wrangler tail --env production
# Filter by status
wrangler tail --env production --status errorCustom Domains
Setup
- Add domain in Cloudflare DNS
- Configure
routesinwrangler.toml - Deploy with
--env production
SSL/TLS
Cloudflare provides automatic SSL for all custom domains.
Database Migrations
KV doesn't require migrations, but for schema changes:
- Deploy backward-compatible API first
- Run migration script
- Remove backward compatibility
// Example migration script
async function migrateVaults(env: Env) {
const list = await env.KV.list({ prefix: "vaults:" });
for (const key of list.keys) {
const vault = await env.KV.get(key.name, "json");
if (!vault.version) {
vault.version = 1;
await env.KV.put(key.name, JSON.stringify(vault));
}
}
}Related
- Contributing - Development workflow
- Project Structure - Package layout
- Testing - Running tests