feat(resources): add cross-server resource migration (dev-only) (#11165)

This commit is contained in:
Andras Bacsai
2026-08-07 23:01:31 +02:00
committed by GitHub
parent d83ba627cd
commit c15e3b35fd
15 changed files with 1354 additions and 7 deletions
@@ -4361,6 +4361,54 @@ class ApplicationsController extends Controller
return moveResourceToEnvironment($request, $application, 'Application', $teamId);
}
#[OA\Post(
summary: 'Migrate to Server',
description: 'Migrate an application to another destination/server owned by the authenticated team. Stops the application, optionally transfers persistent volume data when both servers are managed by Coolify, and updates database records. Redeploy after migration completes.',
path: '/applications/{uuid}/migrate',
operationId: 'migrate-application-by-uuid',
security: [['bearerAuth' => []]],
tags: ['Applications'],
parameters: [
new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'UUID of the application.', schema: new OA\Schema(type: 'string')),
],
requestBody: new OA\RequestBody(
required: true,
content: new OA\JsonContent(
required: ['destination_uuid'],
properties: [
new OA\Property(property: 'destination_uuid', type: 'string', description: 'UUID of the target destination.'),
new OA\Property(property: 'migrate_volumes', type: 'boolean', default: true, description: 'Whether to transfer persistent volume data when migrating across servers.'),
]
)
),
responses: [
new OA\Response(response: 200, description: 'Application migration started or completed.'),
new OA\Response(response: 400, ref: '#/components/responses/400'),
new OA\Response(response: 401, ref: '#/components/responses/401'),
new OA\Response(response: 404, ref: '#/components/responses/404'),
new OA\Response(response: 422, ref: '#/components/responses/422'),
]
)]
public function migrate_by_uuid(Request $request): JsonResponse
{
$teamId = getTeamIdFromToken();
if (is_null($teamId)) {
return invalidTokenResponse();
}
$uuid = $request->route('uuid');
if (! $uuid) {
return response()->json(['message' => 'UUID is required.'], 400);
}
$application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
if (! $application) {
return response()->json(['message' => 'Application not found.'], 404);
}
$this->authorize('update', $application);
return migrateResourceToDestination($request, $application, 'Application', $teamId);
}
private function validateDataApplications(Request $request, Server $server)
{
$teamId = getTeamIdFromToken();