Skip to content

Deployment

Deploy your Cloudwerk application to Cloudflare’s global network with a single command.

Terminal window
pnpm deploy

This builds your application and deploys it to Cloudflare Workers.

Configure your deployment in wrangler.toml:

name = "my-cloudwerk-app"
main = ".cloudwerk/worker.js"
compatibility_date = "2024-01-01"
# Production environment
[env.production]
name = "my-cloudwerk-app"
routes = [
{ pattern = "example.com/*", zone_name = "example.com" }
]
# Staging environment
[env.staging]
name = "my-cloudwerk-app-staging"
routes = [
{ pattern = "staging.example.com/*", zone_name = "example.com" }
]
# D1 Database
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "your-database-id"
# KV Namespace
[[kv_namespaces]]
binding = "KV"
id = "your-kv-id"
# R2 Bucket
[[r2_buckets]]
binding = "R2"
bucket_name = "my-bucket"
# Environment variables
[vars]
ENVIRONMENT = "production"

Set secrets using Wrangler:

Terminal window
# Set a secret
wrangler secret put API_KEY
# Set for specific environment
wrangler secret put API_KEY --env staging

Local development with hot reload:

Terminal window
pnpm dev

Deploy to staging environment:

Terminal window
pnpm deploy --env staging

Deploy to production:

Terminal window
pnpm deploy --env production

Or simply:

Terminal window
pnpm deploy
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run tests
run: pnpm test
- name: Build
run: pnpm build
- name: Deploy to Staging
if: github.event_name == 'pull_request'
run: pnpm deploy --env staging
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- name: Deploy to Production
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: pnpm deploy --env production
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
# .gitlab-ci.yml
stages:
- test
- deploy
test:
stage: test
image: node:20
script:
- corepack enable
- pnpm install --frozen-lockfile
- pnpm test
deploy_staging:
stage: deploy
image: node:20
script:
- corepack enable
- pnpm install --frozen-lockfile
- pnpm deploy --env staging
environment:
name: staging
url: https://staging.example.com
only:
- merge_requests
deploy_production:
stage: deploy
image: node:20
script:
- corepack enable
- pnpm install --frozen-lockfile
- pnpm deploy --env production
environment:
name: production
url: https://example.com
only:
- main

Run migrations before deployment:

  1. Create migration files:

    Terminal window
    mkdir -p migrations
  2. Add migration to CI/CD:

    - name: Run Migrations
    run: wrangler d1 migrations apply my-database --remote
    env:
    CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
  3. Or run manually:

    Terminal window
    wrangler d1 migrations apply my-database --remote
  1. Add your domain to Cloudflare DNS

  2. Configure routes in wrangler.toml:

    routes = [
    { pattern = "api.example.com/*", zone_name = "example.com" }
    ]
  3. Deploy:

    Terminal window
    pnpm deploy
routes = [
{ pattern = "example.com/*", zone_name = "example.com" },
{ pattern = "www.example.com/*", zone_name = "example.com" },
{ pattern = "api.example.com/*", zone_name = "example.com" },
]
Terminal window
# List deployments
wrangler deployments list
# Rollback to previous version
wrangler rollback
Terminal window
# List versions
wrangler versions list
# Deploy specific version
wrangler versions deploy VERSION_ID

View real-time logs:

Terminal window
wrangler tail

Filter logs:

Terminal window
# Filter by status
wrangler tail --status error
# Filter by search term
wrangler tail --search "user-123"

View analytics in the Cloudflare dashboard:

  1. Go to Workers & Pages
  2. Select your worker
  3. View the Analytics tab

Keep your bundle small:

// cloudwerk.config.ts
import { defineConfig } from '@cloudwerk/core';
export default defineConfig({
build: {
minify: true,
treeshake: true,
},
});

Configure caching headers:

export async function loader({ context }: LoaderArgs) {
const data = await fetchData();
return {
data,
headers: {
'Cache-Control': 'public, max-age=3600',
},
};
}

Build fails:

Terminal window
# Clear cache and rebuild
rm -rf .cloudwerk
pnpm build

Deployment fails:

Terminal window
# Check authentication
wrangler whoami
# Verify configuration
wrangler deploy --dry-run

Runtime errors:

Terminal window
# Check logs
wrangler tail --status error