Agent Skills: Fly.io SDK Patterns

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/flyio-sdk-patterns

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/flyio-pack/skills/flyio-sdk-patterns

Skill Files

Browse the full folder contents for flyio-sdk-patterns.

Download Skill

Loading file tree…

plugins/saas-packs/flyio-pack/skills/flyio-sdk-patterns/SKILL.md

Skill Metadata

Name
flyio-sdk-patterns
Description
|

Fly.io SDK Patterns

Overview

Production-ready patterns for the Fly.io Machines REST API at https://api.machines.dev. Typed client, machine lifecycle management, wait-for-state patterns, and multi-region orchestration.

Instructions

Pattern 1: Typed Machines API Client

const FLY_API = 'https://api.machines.dev';

interface FlyMachine {
  id: string;
  name: string;
  state: 'created' | 'starting' | 'started' | 'stopping' | 'stopped' | 'destroying' | 'destroyed';
  region: string;
  config: {
    image: string;
    guest: { cpu_kind: string; cpus: number; memory_mb: number };
    services: Array<{ ports: Array<{ port: number; handlers: string[] }>; internal_port: number }>;
    env: Record<string, string>;
  };
}

class FlyClient {
  private headers: Record<string, string>;

  constructor(private appName: string, token: string) {
    this.headers = { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' };
  }

  async listMachines(): Promise<FlyMachine[]> {
    const res = await fetch(`${FLY_API}/v1/apps/${this.appName}/machines`, { headers: this.headers });
    return res.json();
  }

  async createMachine(config: FlyMachine['config'], region: string): Promise<FlyMachine> {
    const res = await fetch(`${FLY_API}/v1/apps/${this.appName}/machines`, {
      method: 'POST', headers: this.headers,
      body: JSON.stringify({ region, config }),
    });
    return res.json();
  }

  async stopMachine(id: string): Promise<void> {
    await fetch(`${FLY_API}/v1/apps/${this.appName}/machines/${id}/stop`, {
      method: 'POST', headers: this.headers,
    });
  }

  async waitForState(id: string, state: string, timeout = 30): Promise<void> {
    await fetch(
      `${FLY_API}/v1/apps/${this.appName}/machines/${id}/wait?state=${state}&timeout=${timeout}`,
      { headers: this.headers },
    );
  }
}

Pattern 2: Multi-Region Deployment

async function deployToRegions(client: FlyClient, regions: string[], config: FlyMachine['config']) {
  const machines = await Promise.all(
    regions.map(async region => {
      const machine = await client.createMachine(config, region);
      await client.waitForState(machine.id, 'started');
      console.log(`Machine ${machine.id} started in ${region}`);
      return machine;
    })
  );
  return machines;
}

// Deploy to 3 regions
await deployToRegions(client, ['iad', 'lhr', 'nrt'], {
  image: 'registry.fly.io/my-app:latest',
  guest: { cpu_kind: 'shared', cpus: 1, memory_mb: 256 },
  services: [{ ports: [{ port: 443, handlers: ['tls', 'http'] }], internal_port: 3000 }],
  env: { NODE_ENV: 'production' },
});

Pattern 3: Blue-Green Deploy via API

async function blueGreenDeploy(client: FlyClient, newImage: string) {
  const oldMachines = await client.listMachines();

  // Create new machines with updated image
  const newMachines = await Promise.all(
    oldMachines.map(m => client.createMachine(
      { ...m.config, image: newImage },
      m.region,
    ))
  );

  // Wait for all new machines to be healthy
  await Promise.all(newMachines.map(m => client.waitForState(m.id, 'started')));

  // Stop old machines
  await Promise.all(oldMachines.map(m => client.stopMachine(m.id)));
  console.log(`Blue-green: ${newMachines.length} new, ${oldMachines.length} stopped`);
}

Resources

Next Steps

Apply patterns in flyio-core-workflow-a for real-world usage.