Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

jack services

Manage databases, storage, and scheduled tasks for your project.

Usage

jack services [service] [action]

Available Services

ServiceDescription
dbSQLite database (D1)
storageObject storage (R2)
cronScheduled tasks

Database (D1)

Commands

jack services db                    # Show database info
jack services db create             # Create a new database
jack services db create --name xyz  # Create with specific name
jack services db list               # List all databases
jack services db execute "SQL"      # Run read-only SQL
jack services db execute "SQL" --write  # Run SQL that modifies data
jack services db export             # Export to .sql file
jack services db delete             # Delete database

Using in Code

After adding a database, it's available as env.DB:

export default {
  async fetch(request, env) {
    const users = await env.DB.prepare("SELECT * FROM users").all();
    return Response.json(users.results);
  }
}

For write operations:

await env.DB.prepare("INSERT INTO users (name, email) VALUES (?, ?)")
  .bind("Alice", "[email protected]")
  .run();

Storage (R2)

Commands

jack services storage               # Show bucket info
jack services storage create        # Create a new bucket
jack services storage create --name xyz  # Create with specific name
jack services storage list          # List all buckets
jack services storage info          # Show default bucket info
jack services storage info mybucket # Show specific bucket info
jack services storage delete name   # Delete a bucket

Using in Code

After adding storage, it's available as env.STORAGE:

export default {
  async fetch(request, env) {
    // Upload a file
    await env.STORAGE.put("hello.txt", "Hello World!");
 
    // Download a file
    const obj = await env.STORAGE.get("hello.txt");
    return new Response(obj?.body);
  }
}

Common operations:

// List objects
const list = await env.STORAGE.list({ prefix: "images/" });
 
// Delete an object
await env.STORAGE.delete("old-file.txt");
 
// Check if exists
const head = await env.STORAGE.head("file.txt");
if (head) {
  console.log("Size:", head.size);
}

Scheduled Tasks (Cron)

Cron schedules are only available for Jack Cloud (managed) projects. All times are UTC.

Commands

jack services cron list                   # List all schedules
jack services cron create "0 * * * *"     # Schedule hourly runs
jack services cron delete "0 * * * *"     # Remove a schedule
jack services cron test "*/15 * * * *"    # Validate and preview next runs

Minimum interval is 15 minutes. Maximum 5 schedules per project.

Handling cron requests in your worker

Jack Cloud invokes crons by sending POST /__scheduled to your worker's HTTP handler. You must add an explicit route for this. Cloudflare's native scheduled() export does not work with Jack Cloud — Jack uses HTTP, not the Workers scheduled event.

Hono example:

app.post('/__scheduled', async (c) => {
  const cron = c.req.header('X-Jack-Cron');
  await doWork(c.env);  // finish work before responding
  return c.json({ ok: true });
});

Plain worker example:

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (request.method === 'POST' && url.pathname === '/__scheduled') {
      await doWork(env);  // finish work before responding
      return Response.json({ ok: true });
    }
    // ... other routes
  }
};

The request includes these headers:

HeaderDescription
X-Jack-CronThe cron expression that triggered this run
X-Jack-TimestampUnix timestamp of the invocation
X-Jack-SignatureHMAC-SHA256 signature for verification

Checking cron health

Run jack services cron list to see each schedule's last run status and consecutive failure count. If your crons are returning errors, verify that your worker handles POST /__scheduled.

What Happens

When you add a service:

  1. Creates the resource in Jack Cloud (managed mode) or your Cloudflare account (BYO mode)
  2. Binds it to your project
  3. Updates your project configuration
  4. Redeploys with the new binding

Binding Names

ServiceFirst BindingSubsequent
DatabaseDBName in SCREAMING_SNAKE_CASE
StorageSTORAGEName in SCREAMING_SNAKE_CASE