jack services
Manage databases, storage, and scheduled tasks for your project.
Usage
jack services [service] [action]Available Services
| Service | Description |
|---|---|
db | SQLite database (D1) |
storage | Object storage (R2) |
cron | Scheduled 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 databaseUsing 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 bucketUsing 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 runsMinimum 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:
| Header | Description |
|---|---|
X-Jack-Cron | The cron expression that triggered this run |
X-Jack-Timestamp | Unix timestamp of the invocation |
X-Jack-Signature | HMAC-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:
- Creates the resource in Jack Cloud (managed mode) or your Cloudflare account (BYO mode)
- Binds it to your project
- Updates your project configuration
- Redeploys with the new binding
Binding Names
| Service | First Binding | Subsequent |
|---|---|---|
| Database | DB | Name in SCREAMING_SNAKE_CASE |
| Storage | STORAGE | Name in SCREAMING_SNAKE_CASE |