diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php
index 6f58c71e6..12411d3fd 100644
--- a/app/Http/Controllers/ApplicationController.php
+++ b/app/Http/Controllers/ApplicationController.php
@@ -10,23 +10,6 @@ class ApplicationController extends Controller
{
use AuthorizesRequests, ValidatesRequests;
- public function configuration()
- {
- $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
- if (!$project) {
- return redirect()->route('dashboard');
- }
- $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
- if (!$environment) {
- return redirect()->route('dashboard');
- }
- $application = $environment->applications->where('uuid', request()->route('application_uuid'))->first();
- if (!$application) {
- return redirect()->route('dashboard');
- }
- return view('project.application.configuration', ['application' => $application]);
- }
-
public function deployments()
{
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
diff --git a/app/Http/Livewire/Project/Application/Configuration.php b/app/Http/Livewire/Project/Application/Configuration.php
new file mode 100644
index 000000000..7cb2939f2
--- /dev/null
+++ b/app/Http/Livewire/Project/Application/Configuration.php
@@ -0,0 +1,39 @@
+load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
+ if (!$project) {
+ return redirect()->route('dashboard');
+ }
+ $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
+ if (!$environment) {
+ return redirect()->route('dashboard');
+ }
+ $application = $environment->applications->where('uuid', request()->route('application_uuid'))->first();
+ if (!$application) {
+ return redirect()->route('dashboard');
+ }
+ $this->application = $application;
+ $mainServer = $application->destination->server;
+ $servers = Server::ownedByCurrentTeam()->get();
+ $this->servers = $servers->filter(function ($server) use ($mainServer) {
+ return $server->id != $mainServer->id;
+ });
+ }
+ public function render()
+ {
+ return view('livewire.project.application.configuration');
+ }
+}
diff --git a/app/Http/Livewire/Project/Shared/Destination.php b/app/Http/Livewire/Project/Shared/Destination.php
index 3bdb48af6..a946c013f 100644
--- a/app/Http/Livewire/Project/Shared/Destination.php
+++ b/app/Http/Livewire/Project/Shared/Destination.php
@@ -6,5 +6,7 @@ use Livewire\Component;
class Destination extends Component
{
- public $destination;
+ public $resource;
+ public $servers = [];
+ public $additionalServers = [];
}
diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php
index 99aecba86..77c8bd13f 100644
--- a/app/Jobs/ApplicationDeploymentJob.php
+++ b/app/Jobs/ApplicationDeploymentJob.php
@@ -55,6 +55,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private GithubApp|GitlabApp|string $source = 'other';
private StandaloneDocker|SwarmDocker $destination;
private Server $server;
+ private Server $mainServer;
private ?ApplicationPreview $preview = null;
private ?string $git_type = null;
@@ -111,7 +112,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->source = $source->getMorphClass()::where('id', $this->application->source->id)->first();
}
$this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
- $this->server = $this->destination->server;
+ $this->server = $this->mainServer = $this->destination->server;
$this->serverUser = $this->server->user;
$this->basedir = "/artifacts/{$this->deployment_uuid}";
$this->workdir = "{$this->basedir}" . rtrim($this->application->base_directory, '/');
@@ -181,10 +182,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->buildTarget = " --target {$this->application->dockerfile_target_build} ";
}
- // Get user home directory
- $this->serverUserHomeDir = instant_remote_process(["echo \$HOME"], $this->server);
- $this->dockerConfigFileExists = instant_remote_process(["test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'"], $this->server);
-
// Check custom port
preg_match('/(?<=:)\d+(?=\/)/', $this->application->git_repository, $matches);
if (count($matches) === 1) {
@@ -400,19 +397,19 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
]);
}
}
- private function save_environment_variables()
- {
- $envs = collect([]);
- foreach ($this->application->environment_variables as $env) {
- $envs->push($env->key . '=' . $env->value);
- }
- $envs_base64 = base64_encode($envs->implode("\n"));
- $this->execute_remote_command(
- [
- executeInDocker($this->deployment_uuid, "echo '$envs_base64' | base64 -d > $this->workdir/.env")
- ],
- );
- }
+ // private function save_environment_variables()
+ // {
+ // $envs = collect([]);
+ // foreach ($this->application->environment_variables as $env) {
+ // $envs->push($env->key . '=' . $env->value);
+ // }
+ // $envs_base64 = base64_encode($envs->implode("\n"));
+ // $this->execute_remote_command(
+ // [
+ // executeInDocker($this->deployment_uuid, "echo '$envs_base64' | base64 -d > $this->workdir/.env")
+ // ],
+ // );
+ // }
private function deploy_simple_dockerfile()
{
$dockerfile_base64 = base64_encode($this->application->dockerfile);
@@ -471,7 +468,12 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->generate_build_env_variables();
$this->add_build_env_variables_to_dockerfile();
$this->build_image();
- $this->rolling_update();
+ // if ($this->application->additional_destinations) {
+ // $this->push_to_docker_registry();
+ // $this->deploy_to_additional_destinations();
+ // } else {
+ $this->rolling_update();
+ // }
}
private function deploy_nixpacks_buildpack()
{
@@ -629,12 +631,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private function prepare_builder_image()
{
$helperImage = config('coolify.helper_image');
+ // Get user home directory
+ $this->serverUserHomeDir = instant_remote_process(["echo \$HOME"], $this->server);
+ $this->dockerConfigFileExists = instant_remote_process(["test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'"], $this->server);
+
if ($this->dockerConfigFileExists === 'OK') {
$runCommand = "docker run -d --network {$this->destination->network} -v /:/host --name {$this->deployment_uuid} --rm -v {$this->serverUserHomeDir}/.docker/config.json:/root/.docker/config.json:ro -v /var/run/docker.sock:/var/run/docker.sock {$helperImage}";
} else {
$runCommand = "docker run -d --network {$this->destination->network} -v /:/host --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock {$helperImage}";
}
-
$this->execute_remote_command(
[
"echo -n 'Preparing container with helper image: $helperImage.'",
@@ -648,7 +653,31 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
],
);
}
-
+ private function deploy_to_additional_destinations()
+ {
+ $destination_ids = collect(str($this->application->additional_destinations)->explode(','));
+ foreach ($destination_ids as $destination_id) {
+ $destination = StandaloneDocker::find($destination_id);
+ $server = $destination->server;
+ if ($server->team_id !== $this->mainServer->team_id) {
+ $this->execute_remote_command(
+ [
+ "echo -n 'Skipping deployment to {$server->name}. Not in the same team?!'",
+ ],
+ );
+ continue;
+ }
+ $this->server = $server;
+ $this->execute_remote_command(
+ [
+ "echo -n 'Deploying to {$this->server->name}.'",
+ ],
+ );
+ $this->prepare_builder_image();
+ $this->generate_image_names();
+ $this->rolling_update();
+ }
+ }
private function set_base_dir()
{
$this->execute_remote_command(
diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php
index 34678b18a..a45bebf8e 100644
--- a/app/Jobs/ContainerStatusJob.php
+++ b/app/Jobs/ContainerStatusJob.php
@@ -37,7 +37,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
public function handle(): void
{
- ray("checking container statuses for {$this->server->id}");
+ // ray("checking container statuses for {$this->server->id}");
try {
if (!$this->server->isServerReady()) {
return;
diff --git a/app/Models/Application.php b/app/Models/Application.php
index cb3d85f94..f049351e2 100644
--- a/app/Models/Application.php
+++ b/app/Models/Application.php
@@ -225,7 +225,8 @@ class Application extends BaseModel
return $this->morphTo();
}
- public function isDeploymentInprogress() {
+ public function isDeploymentInprogress()
+ {
$deployments = ApplicationDeploymentQueue::where('application_id', $this->id)->where('status', 'in_progress')->count();
if ($deployments > 0) {
return true;
@@ -300,8 +301,9 @@ class Application extends BaseModel
}
return false;
}
- public function isLogDrainEnabled() {
- return data_get($this, 'settings.is_log_drain_enabled', false);
+ public function isLogDrainEnabled()
+ {
+ return data_get($this, 'settings.is_log_drain_enabled', false);
}
public function isConfigurationChanged($save = false)
{
diff --git a/app/Models/Server.php b/app/Models/Server.php
index 7b34278e7..0d57cea55 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -332,7 +332,6 @@ class Server extends BaseModel
}
$uptime = instant_remote_process(['uptime'], $this, false);
- ray($uptime);
if (!$uptime) {
$this->settings()->update([
'is_reachable' => false,
@@ -345,7 +344,6 @@ class Server extends BaseModel
$this->update([
'unreachable_count' => 0,
]);
- ray($this);
}
if (data_get($this, 'unreachable_notification_sent') === true) {
diff --git a/database/migrations/2023_11_21_121920_add_additional_destinations_to_apps.php b/database/migrations/2023_11_21_121920_add_additional_destinations_to_apps.php
new file mode 100644
index 000000000..4852007b4
--- /dev/null
+++ b/database/migrations/2023_11_21_121920_add_additional_destinations_to_apps.php
@@ -0,0 +1,28 @@
+string('additional_destinations')->nullable()->after('destination');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('applications', function (Blueprint $table) {
+ $table->dropColumn('additional_destinations');
+ });
+ }
+};
diff --git a/resources/views/project/application/configuration.blade.php b/resources/views/livewire/project/application/configuration.blade.php
similarity index 97%
rename from resources/views/project/application/configuration.blade.php
rename to resources/views/livewire/project/application/configuration.blade.php
index d6eb25c10..7f2efbc5a 100644
--- a/resources/views/project/application/configuration.blade.php
+++ b/resources/views/livewire/project/application/configuration.blade.php
@@ -1,4 +1,4 @@
-Configuration