fix(queues): run service restarts and proxy start/restart on the deployments queue

- On cloud, RestartService and RestartServiceApplication now run on the
  deployments queue instead of high.
- StartProxy and RestartProxyJob, and the remote processes they start,
  now run on the deployments queue.
- Self-hosted still uses the high queue.
- Tests cover the new routing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2026-10-04 00:11:12 +02:00
co-authored by Claude Opus 5.5
parent b081673c98
commit 80b8b219a2
6 changed files with 50 additions and 6 deletions
+7 -1
View File
@@ -8,12 +8,18 @@ use App\Events\ProxyStatusChangedUI;
use App\Models\Server;
use App\Services\ProxyPortParser;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Spatie\Activitylog\Models\Activity;
class StartProxy
{
use AsAction;
public function configureJob(JobDecorator $job): void
{
$job->onQueue(deployment_queue());
}
public function handle(Server $server, bool $async = true, bool $force = false, bool $restarting = false): string|Activity
{
$proxyType = $server->proxyType();
@@ -87,7 +93,7 @@ class StartProxy
}
if ($async) {
return remote_process($commands, $server, callEventOnFinish: 'ProxyStatusChanged', callEventData: $server->id);
return remote_process($commands, $server, callEventOnFinish: 'ProxyStatusChanged', callEventData: $server->id, queue: deployment_queue());
} else {
instant_remote_process($commands, $server);
+5 -1
View File
@@ -4,12 +4,16 @@ namespace App\Actions\Service;
use App\Models\Service;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\Decorators\JobDecorator;
class RestartService
{
use AsAction;
public string $jobQueue = 'high';
public function configureJob(JobDecorator $job): void
{
$job->onQueue(deployment_queue());
}
public function handle(Service $service, bool $pullLatestImages)
{
@@ -5,12 +5,16 @@ namespace App\Actions\Service;
use App\Models\ServiceApplication;
use App\Models\ServiceDatabase;
use Lorisleiva\Actions\Concerns\AsAction;
use Lorisleiva\Actions\Decorators\JobDecorator;
class RestartServiceApplication
{
use AsAction;
public string $jobQueue = 'high';
public function configureJob(JobDecorator $job): void
{
$job->onQueue(deployment_queue());
}
public function handle(ServiceApplication|ServiceDatabase $serviceApplication): void
{
+6 -2
View File
@@ -31,7 +31,10 @@ class RestartProxyJob implements ShouldBeEncrypted, ShouldQueue
return [(new WithoutOverlapping('restart-proxy-'.$this->server->uuid))->expireAfter(120)->dontRelease()];
}
public function __construct(public Server $server) {}
public function __construct(public Server $server)
{
$this->onQueue(deployment_queue());
}
public function handle()
{
@@ -56,7 +59,8 @@ class RestartProxyJob implements ShouldBeEncrypted, ShouldQueue
$commands,
$this->server,
callEventOnFinish: 'ProxyStatusChanged',
callEventData: $this->server->id
callEventData: $this->server->id,
queue: deployment_queue(),
);
// Store activity ID and notify UI immediately with it
+2 -1
View File
@@ -1021,7 +1021,8 @@ function isCloud(): bool
}
/**
* Resolve the queue used for application deployments, database starts and service starts.
* Resolve the queue used for application deployments and for database, service and proxy
* starts and restarts.
*
* On cloud these jobs run on a dedicated `deployments` queue so they can be drained by an
* isolated Horizon worker pool; self-hosted keeps them on the shared `high` queue. Routing
+25
View File
@@ -3,10 +3,15 @@
use App\Actions\Database\RestartDatabase;
use App\Actions\Database\StartDatabase;
use App\Actions\Database\StartDatabaseProxy;
use App\Actions\Proxy\StartProxy;
use App\Actions\Service\RestartService;
use App\Actions\Service\RestartServiceApplication;
use App\Actions\Service\StartService;
use App\Jobs\DatabaseBackupJob;
use App\Jobs\RestartProxyJob;
use App\Jobs\ScheduledJobManager;
use App\Models\ScheduledDatabaseBackup;
use App\Models\Server;
describe('deployment_queue helper', function () {
test('uses the high queue on self-hosted', function () {
@@ -46,6 +51,9 @@ describe('start action job routing', function () {
RestartDatabase::class,
StartDatabaseProxy::class,
StartService::class,
RestartService::class,
RestartServiceApplication::class,
StartProxy::class,
]);
test('routes to the high queue on self-hosted', function (string $actionClass) {
@@ -57,9 +65,26 @@ describe('start action job routing', function () {
RestartDatabase::class,
StartDatabaseProxy::class,
StartService::class,
RestartService::class,
RestartServiceApplication::class,
StartProxy::class,
]);
});
describe('proxy restart job routing', function () {
test('routes to the deployments queue on cloud', function () {
config(['constants.coolify.self_hosted' => false]);
expect((new RestartProxyJob(new Server))->queue)->toBe('deployments');
});
test('routes to the high queue on self-hosted', function () {
config(['constants.coolify.self_hosted' => true]);
expect((new RestartProxyJob(new Server))->queue)->toBe('high');
});
});
describe('scheduled job routing', function () {
test('scheduled jobs use the crons queue on cloud', function () {
config(['constants.coolify.self_hosted' => false]);