laravel/forge-sdk
Laravel Forge SDK for PHP. Manage Forge API v2 resources with an expressive interface: organizations, servers, sites, recipes, and more. Supports paginated results via CursorPaginator. Requires an organization slug for all endpoints.
Installation:
composer require laravel/forge-sdk
Add your Forge API token to your .env or configuration:
FORGE_API_TOKEN=your_api_token_here
First Use Case: Initialize the SDK and fetch your organizations:
$forge = new Laravel\Forge\Forge(config('forge.api_token'));
$organizations = $forge->organizations();
$organizationSlug = $organizations[0]->slug; // Use the first org's slug
Quick Action: List servers in your first organization:
$servers = $forge->servers($organizationSlug);
foreach ($servers as $server) {
echo $server->name . "\n";
}
CursorPaginator for handling large datasets efficiently.$server = $forge->createServer($orgSlug, [
'provider' => \Laravel\Forge\ServerProviders::DIGITAL_OCEAN,
'credential_id' => 1,
'name' => 'production-app',
'type' => 'app',
'size' => '02',
'region' => 'nyc3',
]);
$server->waitForProvisioning(); // Explicit wait (optional)
$site = $forge->createSite($orgSlug, $server->id, [
'domain' => 'example.com',
'type' => 'php',
'ssl' => true,
]);
$forge->updateSiteEnvironment($orgSlug, $server->id, $site->id, [
'APP_ENV' => 'production',
'DB_HOST' => 'localhost',
]);
$forge->createWebhook($orgSlug, $server->id, $site->id, [
'url' => 'https://github.com/your/repo',
'branch' => 'main',
]);
$forge->createHorizon($orgSlug, $server->id, $site->id, [
'queue' => 'default',
'supervisor' => true,
]);
Environment Configuration:
Store the Forge API token in Laravel’s config/forge.php:
return [
'api_token' => env('FORGE_API_TOKEN'),
];
Then inject the SDK via the service container:
$forge = app(Laravel\Forge\Forge::class);
Artisan Commands: Create a custom command to manage Forge resources:
use Laravel\Forge\Forge;
class ForgeDeployCommand extends Command {
protected $forge;
public function __construct(Forge $forge) {
parent::__construct();
$this->forge = $forge;
}
public function handle() {
$site = $this->forge->createSite(...);
$this->info("Site deployed: {$site->domain}");
}
}
Event Listeners:
Trigger actions after Laravel events (e.g., Deployed):
public function handle(Deployed $event) {
$forge = app(Forge::class);
$forge->createPushToDeploy($orgSlug, $serverId, $siteId, [
'branch' => $event->branch,
]);
}
API Rate Limiting:
Handle TooManyRequestsException by implementing retry logic:
try {
$forge->createSite(...);
} catch (\Laravel\Forge\Exceptions\TooManyRequestsException $e) {
sleep($e->retryAfter);
retry();
}
Organization Slug Requirement:
organizationSlug in API v2 endpoints (e.g., servers()).$organizationSlug first via $forge->organizations().Async Operation Timeouts:
createSite) may exceed the default 30-second timeout.$forge->setTimeout(120)->createSite(...); // 2-minute timeout
Pagination Handling:
servers() returns all results in one call.lazy() for large datasets or toArray() to snapshot a page:
foreach ($forge->servers($orgSlug)->lazy() as $server) { ... }
Resource Ownership:
$databases = $forge->databases($orgSlug, $serverId);
if ($databases->isNotEmpty()) {
$forge->deleteDatabase($orgSlug, $serverId, $database->id);
}
API Token Security:
.env and config/forge.php:
FORGE_API_TOKEN=your_token_here
Enable Debug Mode:
$forge = new Forge(config('forge.api_token'), [
'debug' => true, // Logs API requests/responses
]);
Check HTTP Status Codes:
try-catch to handle exceptions:
try {
$forge->createServer(...);
} catch (\Laravel\Forge\Exceptions\ForgeException $e) {
if ($e->response->status() === 400) {
$this->error($e->response->body());
}
}
Inspect Raw Responses:
$response = $forge->getClient()->get('/api/v2/organizations');
$this->info($response->getBody());
Custom Resource Models:
Extend the SDK’s resource classes (e.g., Server) to add methods:
class CustomServer extends \Laravel\Forge\Resources\Server {
public function isProduction() {
return str_contains($this->name, 'prod');
}
}
Override the SDK’s factory to use your class:
$forge->setResourceFactory(function () {
return new CustomServer();
});
Webhook Validation: Validate Forge webhook payloads in your Laravel app:
public function handleWebhook(Request $request) {
$payload = $request->json()->all();
$forge = app(Forge::class);
$site = $forge->organizationSite($orgSlug, $payload['site_id']);
if ($site->domain !== $payload['domain']) {
abort(403, 'Invalid webhook');
}
}
Batch Operations:
Use Laravel’s collect() to batch operations (e.g., update multiple sites):
$sites = $forge->organizationSites($orgSlug);
$sites->each(function ($site) {
$forge->updateSiteEnvironment($orgSlug, $serverId, $site->id, [
'APP_ENV' => 'production',
]);
});
Testing: Mock the Forge SDK in tests:
$forgeMock = Mockery::mock(Laravel\Forge\Forge::class);
$forgeMock->shouldReceive('createSite')
->once()
->andReturn(new \Laravel\Forge\Resources\Site(['id' => 1, 'domain' => 'test.com']));
$this->app->instance(Laravel\Forge\Forge::class, $forgeMock);
How can I help you explore Laravel packages today?