Manual Deployment

This guide explains how to manually deploy the Link Shortener & Tracker to Cloudflare Workers using the terminal.

Tip: For a faster, automated setup, use the One-Click Deployment method.

Prerequisites

Initial Setup

1. Authenticate with Cloudflare

wrangler login

2. Create Required Resources

D1 Database

wrangler d1 create openshortlink-db

Copy the database_id from the output and save it for later.

KV Namespace

# Production namespace
wrangler kv:namespace create CACHE

# Preview namespace (for wrangler dev)
wrangler kv:namespace create CACHE --preview

Copy both the id (production) and preview_id from the output.

Analytics Engine

Analytics Engine is automatically available in your Cloudflare account. No setup needed.

3. Configure Environment Variables

For Local Development

  1. Copy the example file:
    cp .dev.vars.example .dev.vars
  2. Fill in your actual values in .dev.vars:
    DATABASE_ID=your-database-id-from-step-2
    KV_NAMESPACE_ID=your-kv-namespace-id
    KV_PREVIEW_ID=your-kv-preview-id
    CLOUDFLARE_ACCOUNT_ID=your-account-id
    CLOUDFLARE_API_TOKEN=your-api-token
  3. For SETUP_TOKEN, choose based on your security needs:
    • Production (Most Secure - Recommended):
      SETUP_TOKEN=$(openssl rand -hex 32)
    • Personal Use (Good Security): Use a strong password (min 20 chars, mix of uppercase, lowercase, numbers, special chars)
      SETUP_TOKEN=MyVeryStr0ng!P@ssw0rd#2024$Secure
    • Testing/Development (Basic Security):
      SETUP_TOKEN=$(uuidgen) # Or visit: https://www.uuidgenerator.net/

Note: .dev.vars is gitignored and only used for local development.

For Production Deployment

Update wrangler.toml with your resource IDs:

[[d1_databases]]
binding = "DB"
database_name = "openshortlink-db"
database_id = "your-database-id-from-step-2"

[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-namespace-id"
preview_id = "your-kv-preview-id"

Then set secrets for sensitive values:

# Generate and set setup token
wrangler secret put SETUP_TOKEN
# When prompted, paste a secure token. Choose based on your needs:
# Production: openssl rand -hex 32
# Personal Use: Strong password (20+ chars)
# Testing: uuidgen

# Set Cloudflare account ID
wrangler secret put CLOUDFLARE_ACCOUNT_ID
# Paste your account ID

# Set Cloudflare API token (if using Analytics Engine SQL API)
wrangler secret put CLOUDFLARE_API_TOKEN
# Paste your API token (needs "Account Analytics Read" permission)

Important: Secrets are encrypted and stored securely by Cloudflare. They persist across deployments.

4. Update wrangler.toml

Edit wrangler.toml and configure:

  1. Worker name: Change if needed
  2. D1 database_id: Update the database_id with your ID from step 2
  3. KV namespace IDs: Update id and preview_id with your IDs from step 2
  4. Routes: (Optional) Add your custom domains

Example configuration to add for routes:

# ... existing config ...
# Routes configuration
routes = [
  { pattern = "short.example.com/*", zone_name = "example.com" },
  { pattern = "go.example.com/*", zone_name = "example.com" }
]

Deployment

Local Development

# Install dependencies
npm install

# Run locally with hot reload
npm run dev

Access at: http://localhost:8787

Deploy to Production

# Deploy to Cloudflare Workers
npm run deploy

Or using wrangler directly:

wrangler deploy

First-Time Setup

After deployment, visit your worker URL to complete the initial setup:

  1. Navigate to https://your-worker.workers.dev/dashboard/setup
  2. Enter the SETUP_TOKEN you generated
  3. Create your first admin user

Troubleshooting

"Database not found" error

Make sure the database_id in wrangler.toml matches the ID from wrangler d1 list.

"KV namespace not found" error

Make sure the id in wrangler.toml matches the ID from wrangler kv:namespace list.

"Setup token invalid" error

The SETUP_TOKEN secret must match the token you're entering in the setup page. Regenerate if needed using wrangler secret put SETUP_TOKEN.

Security Best Practices

  1. Never commit .dev.vars - It's gitignored by default
  2. Rotate secrets regularly - Use wrangler secret put to update
  3. Use strong SETUP_TOKEN - Generate with openssl rand -hex 32
  4. Limit API token permissions - Only grant what's needed
  5. Use custom domains - Configure routes in wrangler.toml for production use

Cloudflare WAF Rules (Recommended)

For additional security, configure Cloudflare WAF (Web Application Firewall) rules to protect your dashboard and API endpoints.

IP Restriction
Restrict access to trusted IP addresses:

  1. Go to Cloudflare DashboardSecurityWAFCustom Rules
  2. Create a new rule:
    • Rule name: "Dashboard/API IP Restriction"
    • If: (http.request.uri.path starts with "/dashboard" or http.request.uri.path starts with "/api") and ip.src not in {1.2.3.4 5.6.7.8}
    • Then: Block

Geographic Restrictions
Block access from countries outside your allowed list:

  1. Create a new rule:
    • Rule name: "Dashboard Geo-Blocking"
    • If: (http.request.uri.path starts with "/dashboard" or http.request.uri.path starts with "/api") and ip.geoip.country not in {"US" "GB" "AU"}
    • Then: Block

Additional Rate Limiting
Enhance rate limiting beyond application-level protection:

  1. Go to SecurityWAFRate Limiting Rules
  2. Create a rule:
    • Rule name: "Dashboard Rate Limit"
    • If: http.request.uri.path starts with "/dashboard" or http.request.uri.path starts with "/api"
    • Requests: 100 requests per 10 minutes
    • Then: Block for 1 hour

Note: These Cloudflare rules work at the edge before requests reach your Worker, providing an additional security layer.

← Automatic Deployment Getting Started →