This commit is contained in:
Andras Bacsai 2023-05-24 15:25:08 +02:00
parent a0306f3951
commit 167379b0e0
23 changed files with 118 additions and 125 deletions

View File

@ -100,7 +100,7 @@ protected function getCommand(): string
$port = $this->activity->getExtraProperty('port'); $port = $this->activity->getExtraProperty('port');
$command = $this->activity->getExtraProperty('command'); $command = $this->activity->getExtraProperty('command');
return generateSshCommand($private_key_location, $server_ip, $user, $port, $command); return generate_ssh_command($private_key_location, $server_ip, $user, $port, $command);
} }
protected function handleOutput(string $type, string $output) protected function handleOutput(string $type, string $output)

View File

@ -11,7 +11,7 @@ class CheckProxySettingsInSync
public function __invoke(Server $server, bool $reset = false) public function __invoke(Server $server, bool $reset = false)
{ {
$proxy_path = config('coolify.proxy_config_path'); $proxy_path = config('coolify.proxy_config_path');
$output = instantRemoteProcess([ $output = instant_remote_process([
"cat $proxy_path/docker-compose.yml", "cat $proxy_path/docker-compose.yml",
], $server, false); ], $server, false);
if (is_null($output) || $reset) { if (is_null($output) || $reset) {
@ -23,7 +23,7 @@ public function __invoke(Server $server, bool $reset = false)
$server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value; $server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
$server->save(); $server->save();
if (is_null($output) || $reset) { if (is_null($output) || $reset) {
instantRemoteProcess([ instant_remote_process([
"mkdir -p $proxy_path", "mkdir -p $proxy_path",
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml", "echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
], $server); ], $server);

View File

@ -25,7 +25,7 @@ public function __invoke(Server $server): Activity
return "docker network ls --format '{{.Name}}' | grep '^$network$' >/dev/null 2>&1 || docker network create --attachable $network > /dev/null 2>&1"; return "docker network ls --format '{{.Name}}' | grep '^$network$' >/dev/null 2>&1 || docker network create --attachable $network > /dev/null 2>&1";
}); });
$configuration = instantRemoteProcess([ $configuration = instant_remote_process([
"cat $proxy_path/docker-compose.yml", "cat $proxy_path/docker-compose.yml",
], $server, false); ], $server, false);
if (is_null($configuration)) { if (is_null($configuration)) {
@ -40,7 +40,7 @@ public function __invoke(Server $server): Activity
$env_file_base64 = base64_encode( $env_file_base64 = base64_encode(
$this->getEnvContents() $this->getEnvContents()
); );
$activity = remoteProcess([ $activity = remote_process([
...$create_networks_command, ...$create_networks_command,
"echo 'Docker networks created...'", "echo 'Docker networks created...'",
"mkdir -p $proxy_path", "mkdir -p $proxy_path",

View File

@ -10,7 +10,7 @@ class InstallDocker
public function __invoke(Server $server) public function __invoke(Server $server)
{ {
$config = base64_encode('{ "live-restore": true }'); $config = base64_encode('{ "live-restore": true }');
$activity = remoteProcess([ $activity = remote_process([
"echo Installing Docker...", "echo Installing Docker...",
"curl https://releases.rancher.com/install-docker/23.0.sh | sh", "curl https://releases.rancher.com/install-docker/23.0.sh | sh",
"echo Configuring Docker...", "echo Configuring Docker...",

View File

@ -25,8 +25,8 @@ public function delete()
if ($this->destination->attachedTo()) { if ($this->destination->attachedTo()) {
return $this->emit('error', 'You must delete all resources before deleting this destination.'); return $this->emit('error', 'You must delete all resources before deleting this destination.');
} }
instantRemoteProcess(["docker network disconnect {$this->destination->network} coolify-proxy"], $this->destination->server, throwError: false); instant_remote_process(["docker network disconnect {$this->destination->network} coolify-proxy"], $this->destination->server, throwError: false);
instantRemoteProcess(['docker network rm -f ' . $this->destination->network], $this->destination->server); instant_remote_process(['docker network rm -f ' . $this->destination->network], $this->destination->server);
} }
$this->destination->delete(); $this->destination->delete();
return redirect()->route('dashboard'); return redirect()->route('dashboard');

View File

@ -45,8 +45,8 @@ public function submit()
return; return;
} }
$server = Server::find($this->server_id); $server = Server::find($this->server_id);
instantRemoteProcess(['docker network create --attachable ' . $this->network], $server, throwError: false); instant_remote_process(['docker network create --attachable ' . $this->network], $server, throwError: false);
instantRemoteProcess(["docker network connect $this->network coolify-proxy"], $server, throwError: false); instant_remote_process(["docker network connect $this->network coolify-proxy"], $server, throwError: false);
$docker = ModelsStandaloneDocker::create([ $docker = ModelsStandaloneDocker::create([
'name' => $this->name, 'name' => $this->name,

View File

@ -15,10 +15,10 @@ public function upgrade()
if (!$server) { if (!$server) {
return; return;
} }
instantRemoteProcess([ instant_remote_process([
"sleep 2" "sleep 2"
], $server); ], $server);
remoteProcess([ remote_process([
"sleep 10" "sleep 10"
], $server, ActivityTypes::INLINE->value); ], $server, ActivityTypes::INLINE->value);
$this->emit('updateInitiated'); $this->emit('updateInitiated');
@ -31,18 +31,18 @@ public function upgrade()
return; return;
} }
instantRemoteProcess([ instant_remote_process([
"curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml", "curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml",
"curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml", "curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml",
"curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production", "curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production",
"curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh", "curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh",
], $server); ], $server);
instantRemoteProcess([ instant_remote_process([
"docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull", "docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull",
], $server); ], $server);
remoteProcess([ remote_process([
"bash /data/coolify/source/upgrade.sh $latestVersion" "bash /data/coolify/source/upgrade.sh $latestVersion"
], $server, ActivityTypes::INLINE->value); ], $server, ActivityTypes::INLINE->value);

View File

@ -18,7 +18,7 @@ public function delete()
{ {
$destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first(); $destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
instantRemoteProcess(["docker rm -f {$this->application->uuid}"], $destination->server); instant_remote_process(["docker rm -f {$this->application->uuid}"], $destination->server);
$this->application->delete(); $this->application->delete();
return redirect()->route('project.resources', [ return redirect()->route('project.resources', [
'project_uuid' => $this->parameters['project_uuid'], 'project_uuid' => $this->parameters['project_uuid'],

View File

@ -42,13 +42,13 @@ public function loadImages()
{ {
try { try {
$image = $this->application->uuid; $image = $this->application->uuid;
$output = instantRemoteProcess([ $output = instant_remote_process([
"docker inspect --format='{{.Config.Image}}' {$this->application->uuid}", "docker inspect --format='{{.Config.Image}}' {$this->application->uuid}",
], $this->application->destination->server, throwError: false); ], $this->application->destination->server, throwError: false);
$current_tag = Str::of($output)->trim()->explode(":"); $current_tag = Str::of($output)->trim()->explode(":");
$this->current = data_get($current_tag, 1); $this->current = data_get($current_tag, 1);
$output = instantRemoteProcess([ $output = instant_remote_process([
"docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}'", "docker images --format '{{.Repository}}#{{.Tag}}#{{.CreatedAt}}'",
], $this->application->destination->server); ], $this->application->destination->server);
$this->images = Str::of($output)->trim()->explode("\n")->filter(function ($item) use ($image) { $this->images = Str::of($output)->trim()->explode("\n")->filter(function ($item) use ($image) {

View File

@ -26,7 +26,7 @@ public function runCommand()
{ {
try { try {
$this->validate(); $this->validate();
$activity = remoteProcess([$this->command], Server::where('uuid', $this->server)->first(), ActivityTypes::INLINE->value); $activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ActivityTypes::INLINE->value);
$this->emit('newMonitorActivity', $activity->id); $this->emit('newMonitorActivity', $activity->id);
} catch (\Exception $e) { } catch (\Exception $e) {
return general_error_handler($e); return general_error_handler($e);

View File

@ -36,7 +36,7 @@ public function installDocker()
public function validateServer() public function validateServer()
{ {
try { try {
$this->uptime = instantRemoteProcess(['uptime'], $this->server, false); $this->uptime = instant_remote_process(['uptime'], $this->server, false);
if (!$this->uptime) { if (!$this->uptime) {
$this->uptime = 'Server not reachable.'; $this->uptime = 'Server not reachable.';
throw new \Exception('Server not reachable.'); throw new \Exception('Server not reachable.');
@ -47,11 +47,11 @@ public function validateServer()
$this->emit('serverValidated'); $this->emit('serverValidated');
} }
} }
$this->dockerVersion = instantRemoteProcess(['docker version|head -2|grep -i version'], $this->server, false); $this->dockerVersion = instant_remote_process(['docker version|head -2|grep -i version'], $this->server, false);
if (!$this->dockerVersion) { if (!$this->dockerVersion) {
$this->dockerVersion = 'Not installed.'; $this->dockerVersion = 'Not installed.';
} }
$this->dockerComposeVersion = instantRemoteProcess(['docker compose version|head -2|grep -i version'], $this->server, false); $this->dockerComposeVersion = instant_remote_process(['docker compose version|head -2|grep -i version'], $this->server, false);
if (!$this->dockerComposeVersion) { if (!$this->dockerComposeVersion) {
$this->dockerComposeVersion = 'Not installed.'; $this->dockerComposeVersion = 'Not installed.';
} }

View File

@ -51,7 +51,7 @@ public function setProxy()
} }
public function stopProxy() public function stopProxy()
{ {
instantRemoteProcess([ instant_remote_process([
"docker rm -f coolify-proxy", "docker rm -f coolify-proxy",
], $this->server); ], $this->server);
$this->server->extra_attributes->proxy_status = 'exited'; $this->server->extra_attributes->proxy_status = 'exited';
@ -65,7 +65,7 @@ public function saveConfiguration()
$docker_compose_yml_base64 = base64_encode($this->proxy_settings); $docker_compose_yml_base64 = base64_encode($this->proxy_settings);
$this->server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value; $this->server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
$this->server->save(); $this->server->save();
instantRemoteProcess([ instant_remote_process([
"echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml", "echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
], $this->server); ], $this->server);
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@ -60,7 +60,7 @@ public function __construct(
$server = $this->destination->server; $server = $this->destination->server;
$private_key_location = savePrivateKeyForServer($server); $private_key_location = save_private_key_for_server($server);
$remoteProcessArgs = new CoolifyTaskArgs( $remoteProcessArgs = new CoolifyTaskArgs(
server_ip: $server->ip, server_ip: $server->ip,
@ -452,13 +452,13 @@ private function execute_now(
if ($isDebuggable && !$this->application->settings->is_debug) { if ($isDebuggable && !$this->application->settings->is_debug) {
$hideFromOutput = true; $hideFromOutput = true;
} }
$remoteProcess = resolve(RunRemoteProcess::class, [ $remote_process = resolve(RunRemoteProcess::class, [
'activity' => $this->activity, 'activity' => $this->activity,
'hideFromOutput' => $hideFromOutput, 'hideFromOutput' => $hideFromOutput,
'isFinished' => $isFinished, 'isFinished' => $isFinished,
'ignoreErrors' => $ignoreErrors, 'ignoreErrors' => $ignoreErrors,
]); ]);
$result = $remoteProcess(); $result = $remote_process();
if ($propertyName) { if ($propertyName) {
$this->activity->properties = $this->activity->properties->merge([ $this->activity->properties = $this->activity->properties->merge([
$propertyName => trim($result->output()), $propertyName => trim($result->output()),

View File

@ -47,7 +47,7 @@ protected function check_all_servers()
$not_found_applications = $applications; $not_found_applications = $applications;
$containers = collect(); $containers = collect();
foreach ($servers as $server) { foreach ($servers as $server) {
$output = instantRemoteProcess(['docker ps -a -q --format \'{{json .}}\''], $server); $output = instant_remote_process(['docker ps -a -q --format \'{{json .}}\''], $server);
$containers = $containers->concat(format_docker_command_output_to_json($output)); $containers = $containers->concat(format_docker_command_output_to_json($output));
} }
foreach ($containers as $container) { foreach ($containers as $container) {

View File

@ -29,7 +29,7 @@ public function handle(): void
{ {
try { try {
$application = Application::find($this->application_id)->first(); $application = Application::find($this->application_id)->first();
instantRemoteProcess(["docker rm -f {$application->uuid}"], $this->server); instant_remote_process(["docker rm -f {$application->uuid}"], $this->server);
$application->status = get_container_status(server: $application->destination->server, container_id: $application->uuid); $application->status = get_container_status(server: $application->destination->server, container_id: $application->uuid);
$application->save(); $application->save();
} catch (\Exception $e) { } catch (\Exception $e) {

View File

@ -19,18 +19,19 @@ class CoolifyTask implements ShouldQueue
*/ */
public function __construct( public function __construct(
public Activity $activity, public Activity $activity,
){} ) {
}
/** /**
* Execute the job. * Execute the job.
*/ */
public function handle(): void public function handle(): void
{ {
$remoteProcess = resolve(RunRemoteProcess::class, [ $remote_process = resolve(RunRemoteProcess::class, [
'activity' => $this->activity, 'activity' => $this->activity,
]); ]);
$remoteProcess(); $remote_process();
// @TODO: Remove file at $this->activity->getExtraProperty('private_key_location') after process is finished // @TODO: Remove file at $this->activity->getExtraProperty('private_key_location') after process is finished
} }
} }

View File

@ -46,10 +46,10 @@ public function handle(): void
if (!$server) { if (!$server) {
return; return;
} }
instantRemoteProcess([ instant_remote_process([
"sleep 2" "sleep 2"
], $server); ], $server);
remoteProcess([ remote_process([
"sleep 10" "sleep 10"
], $server, ActivityTypes::INLINE->value); ], $server, ActivityTypes::INLINE->value);
} else { } else {
@ -68,18 +68,18 @@ public function handle(): void
return; return;
} }
instantRemoteProcess([ instant_remote_process([
"curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml", "curl -fsSL $cdn/docker-compose.yml -o /data/coolify/source/docker-compose.yml",
"curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml", "curl -fsSL $cdn/docker-compose.prod.yml -o /data/coolify/source/docker-compose.prod.yml",
"curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production", "curl -fsSL $cdn/.env.production -o /data/coolify/source/.env.production",
"curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh", "curl -fsSL $cdn/upgrade.sh -o /data/coolify/source/upgrade.sh",
], $server); ], $server);
instantRemoteProcess([ instant_remote_process([
"docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull", "docker compose -f /data/coolify/source/docker-compose.yml -f /data/coolify/source/docker-compose.prod.yml pull",
], $server); ], $server);
remoteProcess([ remote_process([
"bash /data/coolify/source/upgrade.sh $latest_version" "bash /data/coolify/source/upgrade.sh $latest_version"
], $server, ActivityTypes::INLINE->value); ], $server, ActivityTypes::INLINE->value);
} }

View File

@ -31,7 +31,7 @@ public function handle(): void
try { try {
$servers = Server::all(); $servers = Server::all();
foreach ($servers as $server) { foreach ($servers as $server) {
instantRemoteProcess(['docker image prune -f'], $server); instant_remote_process(['docker image prune -f'], $server);
} }
} catch (\Exception $e) { } catch (\Exception $e) {
Log::error($e->getMessage()); Log::error($e->getMessage());

View File

@ -27,7 +27,7 @@ public function register(): void
public function boot(): void public function boot(): void
{ {
Queue::after(function (JobProcessed $event) { Queue::after(function (JobProcessed $event) {
// @TODO: Remove `coolify-builder` container after the remoteProcess job is finishged and remoteProcess->type == `deployment`. // @TODO: Remove `coolify-builder` container after the remote_process job is finishged and remote_process->type == `deployment`.
if ($event->job->resolveName() === CoolifyTask::class) { if ($event->job->resolveName() === CoolifyTask::class) {
} }
}); });

View File

@ -31,7 +31,7 @@ function format_docker_labels_to_json($rawOutput): Collection
function get_container_status(Server $server, string $container_id, bool $throwError = false) function get_container_status(Server $server, string $container_id, bool $throwError = false)
{ {
$container = instantRemoteProcess(["docker inspect --format '{{json .State}}' {$container_id}"], $server, $throwError); $container = instant_remote_process(["docker inspect --format '{{json .State}}' {$container_id}"], $server, $throwError);
if (!$container) { if (!$container) {
return 'exited'; return 'exited';
} }

View File

@ -1,5 +1,6 @@
<?php <?php
use App\Actions\CoolifyTask\PrepareCoolifyTask;
use App\Data\CoolifyTaskArgs; use App\Data\CoolifyTaskArgs;
use App\Models\Server; use App\Models\Server;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
@ -7,13 +8,12 @@
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use Spatie\Activitylog\Models\Activity; use Spatie\Activitylog\Models\Activity;
if (!function_exists('remoteProcess')) {
/** /**
* Run a Remote Process, which SSH's asynchronously into a machine to run the command(s). * Run a Remote Process, which SSH's asynchronously into a machine to run the command(s).
* @TODO Change 'root' to 'coolify' when it's able to run Docker commands without sudo * @TODO Change 'root' to 'coolify' when it's able to run Docker commands without sudo
* *
*/ */
function remoteProcess( function remote_process(
array $command, array $command,
Server $server, Server $server,
string $type, string $type,
@ -26,7 +26,7 @@ function remoteProcess(
// @TODO: Check if the user has access to this server // @TODO: Check if the user has access to this server
// checkTeam($server->team_id); // checkTeam($server->team_id);
$private_key_location = savePrivateKeyForServer($server); $private_key_location = save_private_key_for_server($server);
return resolve(PrepareCoolifyTask::class, [ return resolve(PrepareCoolifyTask::class, [
'remoteProcessArgs' => new CoolifyTaskArgs( 'remoteProcessArgs' => new CoolifyTaskArgs(
@ -43,19 +43,14 @@ function remoteProcess(
), ),
])(); ])();
} }
} function save_private_key_for_server(Server $server)
if (!function_exists('savePrivateKeyForServer')) {
function savePrivateKeyForServer(Server $server)
{ {
$temp_file = "id.root@{$server->ip}"; $temp_file = "id.root@{$server->ip}";
Storage::disk('ssh-keys')->put($temp_file, $server->privateKey->private_key); Storage::disk('ssh-keys')->put($temp_file, $server->privateKey->private_key);
return '/var/www/html/storage/app/ssh-keys/' . $temp_file; return '/var/www/html/storage/app/ssh-keys/' . $temp_file;
} }
}
if (!function_exists('generateSshCommand')) { function generate_ssh_command(string $private_key_location, string $server_ip, string $user, string $port, string $command, bool $isMux = true)
function generateSshCommand(string $private_key_location, string $server_ip, string $user, string $port, string $command, bool $isMux = true)
{ {
Storage::disk('local')->makeDirectory('.ssh'); Storage::disk('local')->makeDirectory('.ssh');
@ -80,14 +75,12 @@ function generateSshCommand(string $private_key_location, string $server_ip, str
return $ssh_command; return $ssh_command;
} }
}
if (!function_exists('instantRemoteProcess')) { function instant_remote_process(array $command, Server $server, $throwError = true)
function instantRemoteProcess(array $command, Server $server, $throwError = true)
{ {
$command_string = implode("\n", $command); $command_string = implode("\n", $command);
$private_key_location = savePrivateKeyForServer($server); $private_key_location = save_private_key_for_server($server);
$ssh_command = generateSshCommand($private_key_location, $server->ip, $server->user, $server->port, $command_string); $ssh_command = generate_ssh_command($private_key_location, $server->ip, $server->user, $server->port, $command_string);
$process = Process::run($ssh_command); $process = Process::run($ssh_command);
$output = trim($process->output()); $output = trim($process->output());
$exitCode = $process->exitCode(); $exitCode = $process->exitCode();
@ -99,4 +92,3 @@ function instantRemoteProcess(array $command, Server $server, $throwError = true
} }
return $output; return $output;
} }
}

View File

@ -33,28 +33,28 @@
$containerName = 'coolify_test_' . now()->format('Ymd_his'); $containerName = 'coolify_test_' . now()->format('Ymd_his');
$host = Server::where('name', 'testing-local-docker-container')->first(); $host = Server::where('name', 'testing-local-docker-container')->first();
remoteProcess([ remote_process([
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq) > /dev/null 2>&1" "docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq) > /dev/null 2>&1"
], $host); ], $host);
// Assert there's no containers start with coolify_test_* // Assert there's no containers start with coolify_test_*
$activity = remoteProcess([$areThereCoolifyTestContainers], $host); $activity = remote_process([$areThereCoolifyTestContainers], $host);
$tidyOutput = RunRemoteProcess::decodeOutput($activity); $tidyOutput = RunRemoteProcess::decodeOutput($activity);
$containers = format_docker_command_output_to_json($tidyOutput); $containers = format_docker_command_output_to_json($tidyOutput);
expect($containers)->toBeEmpty(); expect($containers)->toBeEmpty();
// start a container nginx -d --name = $containerName // start a container nginx -d --name = $containerName
$activity = remoteProcess(["docker run -d --rm --name {$containerName} nginx"], $host); $activity = remote_process(["docker run -d --rm --name {$containerName} nginx"], $host);
expect($activity->getExtraProperty('exitCode'))->toBe(0); expect($activity->getExtraProperty('exitCode'))->toBe(0);
// docker ps name = $container // docker ps name = $container
$activity = remoteProcess([$areThereCoolifyTestContainers], $host); $activity = remote_process([$areThereCoolifyTestContainers], $host);
$tidyOutput = RunRemoteProcess::decodeOutput($activity); $tidyOutput = RunRemoteProcess::decodeOutput($activity);
$containers = format_docker_command_output_to_json($tidyOutput); $containers = format_docker_command_output_to_json($tidyOutput);
expect($containers->where('Names', $containerName)->count())->toBe(1); expect($containers->where('Names', $containerName)->count())->toBe(1);
// Stop testing containers // Stop testing containers
$activity = remoteProcess([ $activity = remote_process([
"docker ps --filter='name={$coolifyNamePrefix}*' -aq && " . "docker ps --filter='name={$coolifyNamePrefix}*' -aq && " .
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq)" "docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq)"
], $host); ], $host);

View File

@ -17,7 +17,7 @@
$host = Server::where('name', 'testing-local-docker-container')->first(); $host = Server::where('name', 'testing-local-docker-container')->first();
$activity = remoteProcess([ $activity = remote_process([
'pwd', 'pwd',
'x=1; while [ $x -le 3 ]; do sleep 0.1 && echo "Welcome $x times" $(( x++ )); done', 'x=1; while [ $x -le 3 ]; do sleep 0.1 && echo "Welcome $x times" $(( x++ )); done',
], $host); ], $host);