fix(proxy): proxy restart does not work on domain
- When you restart the proxy on an instance domain, the proxy stops and is removed, but never restarted. So you loose access over the domain and have to go in over IP and Port. This is because we are doing the restart directly in the UI instead of in the background via a job, and the proxy is serving the UI domain.
This commit is contained in:
56
app/Actions/Proxy/StopProxy.php
Normal file
56
app/Actions/Proxy/StopProxy.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Actions\Proxy;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Process\InvokedProcess;
|
||||||
|
use Illuminate\Support\Facades\Process;
|
||||||
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
|
class StopProxy
|
||||||
|
{
|
||||||
|
use AsAction;
|
||||||
|
|
||||||
|
public function handle(Server $server, bool $forceStop = true)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$containerName = $server->isSwarm() ? 'coolify-proxy_traefik' : 'coolify-proxy';
|
||||||
|
$timeout = 30;
|
||||||
|
|
||||||
|
$process = $this->stopContainer($containerName, $timeout);
|
||||||
|
|
||||||
|
$startTime = Carbon::now()->getTimestamp();
|
||||||
|
while ($process->running()) {
|
||||||
|
if (Carbon::now()->getTimestamp() - $startTime >= $timeout) {
|
||||||
|
$this->forceStopContainer($containerName, $server);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->removeContainer($containerName, $server);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e);
|
||||||
|
} finally {
|
||||||
|
$server->proxy->force_stop = $forceStop;
|
||||||
|
$server->proxy->status = 'exited';
|
||||||
|
$server->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stopContainer(string $containerName, int $timeout): InvokedProcess
|
||||||
|
{
|
||||||
|
return Process::timeout($timeout)->start("docker stop --time=$timeout $containerName");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function forceStopContainer(string $containerName, Server $server)
|
||||||
|
{
|
||||||
|
instant_remote_process(["docker kill $containerName"], $server, throwError: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function removeContainer(string $containerName, Server $server)
|
||||||
|
{
|
||||||
|
instant_remote_process(["docker rm -f $containerName"], $server, throwError: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
app/Jobs/RestartProxyJob.php
Normal file
46
app/Jobs/RestartProxyJob.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\Actions\Proxy\CheckProxy;
|
||||||
|
use App\Actions\Proxy\StartProxy;
|
||||||
|
use App\Actions\Proxy\StopProxy;
|
||||||
|
use App\Models\Server;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class RestartProxyJob implements ShouldBeEncrypted, ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
public $tries = 1;
|
||||||
|
|
||||||
|
public $timeout = 60;
|
||||||
|
|
||||||
|
public function middleware(): array
|
||||||
|
{
|
||||||
|
return [(new WithoutOverlapping($this->server->uuid))->dontRelease()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(public Server $server) {}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
StopProxy::run($this->server);
|
||||||
|
|
||||||
|
$this->server->proxy->force_stop = false;
|
||||||
|
$this->server->save();
|
||||||
|
StartProxy::run($this->server, force: true);
|
||||||
|
|
||||||
|
CheckProxy::run($this->server, true);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,10 @@ namespace App\Livewire\Server\Proxy;
|
|||||||
|
|
||||||
use App\Actions\Proxy\CheckProxy;
|
use App\Actions\Proxy\CheckProxy;
|
||||||
use App\Actions\Proxy\StartProxy;
|
use App\Actions\Proxy\StartProxy;
|
||||||
|
use App\Actions\Proxy\StopProxy;
|
||||||
use App\Events\ProxyStatusChanged;
|
use App\Events\ProxyStatusChanged;
|
||||||
|
use App\Jobs\RestartProxyJob;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Process\InvokedProcess;
|
|
||||||
use Illuminate\Support\Facades\Process;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Deploy extends Component
|
class Deploy extends Component
|
||||||
@@ -65,6 +64,7 @@ class Deploy extends Component
|
|||||||
public function restart()
|
public function restart()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
RestartProxyJob::dispatch($this->server);
|
||||||
$this->dispatch('checkProxy');
|
$this->dispatch('checkProxy');
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
@@ -97,43 +97,10 @@ class Deploy extends Component
|
|||||||
public function stop(bool $forceStop = true)
|
public function stop(bool $forceStop = true)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$containerName = $this->server->isSwarm() ? 'coolify-proxy_traefik' : 'coolify-proxy';
|
StopProxy::run($this->server, $forceStop);
|
||||||
$timeout = 30;
|
$this->dispatch('proxyStatusUpdated');
|
||||||
|
|
||||||
$process = $this->stopContainer($containerName, $timeout);
|
|
||||||
|
|
||||||
$startTime = Carbon::now()->getTimestamp();
|
|
||||||
while ($process->running()) {
|
|
||||||
if (Carbon::now()->getTimestamp() - $startTime >= $timeout) {
|
|
||||||
$this->forceStopContainer($containerName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->removeContainer($containerName);
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
} finally {
|
|
||||||
$this->server->proxy->force_stop = $forceStop;
|
|
||||||
$this->server->proxy->status = 'exited';
|
|
||||||
$this->server->save();
|
|
||||||
$this->dispatch('proxyStatusUpdated');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function stopContainer(string $containerName, int $timeout): InvokedProcess
|
|
||||||
{
|
|
||||||
return Process::timeout($timeout)->start("docker stop --time=$timeout $containerName");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function forceStopContainer(string $containerName)
|
|
||||||
{
|
|
||||||
instant_remote_process(["docker kill $containerName"], $this->server, throwError: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removeContainer(string $containerName)
|
|
||||||
{
|
|
||||||
instant_remote_process(["docker rm -f $containerName"], $this->server, throwError: false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user