mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-21 06:11:27 -07:00
update skills
This commit is contained in:
187
.agents/skills/cloudflare-deploy/references/containers/api.md
Normal file
187
.agents/skills/cloudflare-deploy/references/containers/api.md
Normal file
@@ -0,0 +1,187 @@
|
||||
## Container Class API
|
||||
|
||||
```typescript
|
||||
import { Container } from "@cloudflare/containers";
|
||||
|
||||
export class MyContainer extends Container {
|
||||
defaultPort = 8080;
|
||||
requiredPorts = [8080];
|
||||
sleepAfter = "30m";
|
||||
enableInternet = true;
|
||||
pingEndpoint = "/health";
|
||||
envVars = {};
|
||||
entrypoint = [];
|
||||
|
||||
onStart() { /* container started */ }
|
||||
onStop() { /* container stopping */ }
|
||||
onError(error: Error) { /* container error */ }
|
||||
onActivityExpired(): boolean { /* timeout, return true to stay alive */ }
|
||||
async alarm() { /* scheduled task */ }
|
||||
}
|
||||
```
|
||||
|
||||
## Routing
|
||||
|
||||
**getByName(id)** - Named instance for session affinity, per-user state
|
||||
**getRandom()** - Random instance for load balancing stateless services
|
||||
|
||||
```typescript
|
||||
const container = env.MY_CONTAINER.getByName("user-123");
|
||||
const container = env.MY_CONTAINER.getRandom();
|
||||
```
|
||||
|
||||
## Startup Methods
|
||||
|
||||
### start() - Basic start (8s timeout)
|
||||
|
||||
```typescript
|
||||
await container.start();
|
||||
await container.start({ envVars: { KEY: "value" } });
|
||||
```
|
||||
|
||||
Returns when **process starts**, NOT when ports ready. Use for fire-and-forget.
|
||||
|
||||
### startAndWaitForPorts() - Recommended (20s timeout)
|
||||
|
||||
```typescript
|
||||
await container.startAndWaitForPorts(); // Uses requiredPorts
|
||||
await container.startAndWaitForPorts({ ports: [8080, 9090] });
|
||||
await container.startAndWaitForPorts({
|
||||
ports: [8080],
|
||||
startOptions: { envVars: { KEY: "value" } }
|
||||
});
|
||||
```
|
||||
|
||||
Returns when **ports listening**. Use before HTTP/TCP requests.
|
||||
|
||||
**Port resolution:** explicit ports → requiredPorts → defaultPort → port 33
|
||||
|
||||
### waitForPort() - Wait for specific port
|
||||
|
||||
```typescript
|
||||
await container.waitForPort(8080);
|
||||
await container.waitForPort(8080, { timeout: 30000 });
|
||||
```
|
||||
|
||||
## Communication
|
||||
|
||||
### fetch() - HTTP with WebSocket support
|
||||
|
||||
```typescript
|
||||
// ✅ Supports WebSocket upgrades
|
||||
const response = await container.fetch(request);
|
||||
const response = await container.fetch("http://container/api", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ data: "value" })
|
||||
});
|
||||
```
|
||||
|
||||
**Use for:** All HTTP, especially WebSocket.
|
||||
|
||||
### containerFetch() - HTTP only (no WebSocket)
|
||||
|
||||
```typescript
|
||||
// ❌ No WebSocket support
|
||||
const response = await container.containerFetch(request);
|
||||
```
|
||||
|
||||
**⚠️ Critical:** Use `fetch()` for WebSocket, not `containerFetch()`.
|
||||
|
||||
### TCP Connections
|
||||
|
||||
```typescript
|
||||
const port = this.ctx.container.getTcpPort(8080);
|
||||
const conn = port.connect();
|
||||
await conn.opened;
|
||||
|
||||
if (request.body) await request.body.pipeTo(conn.writable);
|
||||
return new Response(conn.readable);
|
||||
```
|
||||
|
||||
### switchPort() - Change default port
|
||||
|
||||
```typescript
|
||||
this.switchPort(8081); // Subsequent fetch() uses this port
|
||||
```
|
||||
|
||||
## Lifecycle Hooks
|
||||
|
||||
### onStart()
|
||||
|
||||
Called when container process starts (ports may not be ready). Runs in `blockConcurrencyWhile` - no concurrent requests.
|
||||
|
||||
```typescript
|
||||
onStart() {
|
||||
console.log("Container starting");
|
||||
}
|
||||
```
|
||||
|
||||
### onStop()
|
||||
|
||||
Called when SIGTERM received. 15 minutes until SIGKILL. Use for graceful shutdown.
|
||||
|
||||
```typescript
|
||||
onStop() {
|
||||
// Save state, close connections, flush logs
|
||||
}
|
||||
```
|
||||
|
||||
### onError()
|
||||
|
||||
Called when container crashes or fails to start.
|
||||
|
||||
```typescript
|
||||
onError(error: Error) {
|
||||
console.error("Container error:", error);
|
||||
}
|
||||
```
|
||||
|
||||
### onActivityExpired()
|
||||
|
||||
Called when `sleepAfter` timeout reached. Return `true` to stay alive, `false` to stop.
|
||||
|
||||
```typescript
|
||||
onActivityExpired(): boolean {
|
||||
if (this.hasActiveConnections()) return true; // Keep alive
|
||||
return false; // OK to stop
|
||||
}
|
||||
```
|
||||
|
||||
## Scheduling
|
||||
|
||||
```typescript
|
||||
export class ScheduledContainer extends Container {
|
||||
async fetch(request: Request) {
|
||||
await this.schedule(Date.now() + 60000); // 1 minute
|
||||
await this.schedule("2026-01-28T00:00:00Z"); // ISO string
|
||||
return new Response("Scheduled");
|
||||
}
|
||||
|
||||
async alarm() {
|
||||
// Called when schedule fires (SQLite-backed, survives restarts)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**⚠️ Don't override `alarm()` directly when using `schedule()` helper.**
|
||||
|
||||
## State Inspection
|
||||
|
||||
### External state check
|
||||
|
||||
```typescript
|
||||
const state = await container.getState();
|
||||
// state.status: "starting" | "running" | "stopping" | "stopped"
|
||||
```
|
||||
|
||||
### Internal state check
|
||||
|
||||
```typescript
|
||||
export class MyContainer extends Container {
|
||||
async fetch(request: Request) {
|
||||
if (this.ctx.container.running) { ... }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**⚠️ Use `getState()` for external checks, `ctx.container.running` for internal.**
|
||||
Reference in New Issue
Block a user