commit
bb927505fe
@ -218,12 +218,12 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$teamId = data_get($this->application, 'environment.project.team.id');
|
$teamId = data_get($this->application, 'environment.project.team.id');
|
||||||
$buildServers = Server::buildServers($teamId)->get();
|
$buildServers = Server::buildServers($teamId)->get();
|
||||||
if ($buildServers->count() === 0) {
|
if ($buildServers->count() === 0) {
|
||||||
$this->application_deployment_queue->addLogEntry("Build server feature activated, but no suitable build server found. Using the deployment server.");
|
$this->application_deployment_queue->addLogEntry("No suitable build server found. Using the deployment server.");
|
||||||
$this->build_server = $this->server;
|
$this->build_server = $this->server;
|
||||||
$this->original_server = $this->server;
|
$this->original_server = $this->server;
|
||||||
} else {
|
} else {
|
||||||
$this->application_deployment_queue->addLogEntry("Build server feature activated and found a suitable build server. Using it to build your application - if needed.");
|
|
||||||
$this->build_server = $buildServers->random();
|
$this->build_server = $buildServers->random();
|
||||||
|
$this->application_deployment_queue->addLogEntry("Found a suitable build server ({$this->build_server->name}).");
|
||||||
$this->original_server = $this->server;
|
$this->original_server = $this->server;
|
||||||
$this->use_build_server = true;
|
$this->use_build_server = true;
|
||||||
}
|
}
|
||||||
@ -427,13 +427,13 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
}
|
}
|
||||||
private function deploy_dockerfile_buildpack()
|
private function deploy_dockerfile_buildpack()
|
||||||
{
|
{
|
||||||
|
$this->application_deployment_queue->addLogEntry("Starting deployment of {$this->customRepository}:{$this->application->git_branch} to {$this->server->name}.");
|
||||||
if ($this->use_build_server) {
|
if ($this->use_build_server) {
|
||||||
$this->server = $this->build_server;
|
$this->server = $this->build_server;
|
||||||
}
|
}
|
||||||
if (data_get($this->application, 'dockerfile_location')) {
|
if (data_get($this->application, 'dockerfile_location')) {
|
||||||
$this->dockerfile_location = $this->application->dockerfile_location;
|
$this->dockerfile_location = $this->application->dockerfile_location;
|
||||||
}
|
}
|
||||||
$this->application_deployment_queue->addLogEntry("Starting deployment of {$this->customRepository}:{$this->application->git_branch} to {$this->server->name}.");
|
|
||||||
$this->prepare_builder_image();
|
$this->prepare_builder_image();
|
||||||
$this->check_git_if_build_needed();
|
$this->check_git_if_build_needed();
|
||||||
$this->set_base_dir();
|
$this->set_base_dir();
|
||||||
@ -528,9 +528,11 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->server = $this->original_server;
|
$this->server = $this->original_server;
|
||||||
}
|
}
|
||||||
$readme = generate_readme_file($this->application->name, $this->application_deployment_queue->updated_at);
|
$readme = generate_readme_file($this->application->name, $this->application_deployment_queue->updated_at);
|
||||||
$composeFileName = "$this->configuration_dir/docker-compose.yml";
|
if ($this->pull_request_id === 0) {
|
||||||
if ($this->pull_request_id !== 0) {
|
$composeFileName = "$this->configuration_dir/docker-compose.yml";
|
||||||
|
} else {
|
||||||
$composeFileName = "$this->configuration_dir/docker-compose-pr-{$this->pull_request_id}.yml";
|
$composeFileName = "$this->configuration_dir/docker-compose-pr-{$this->pull_request_id}.yml";
|
||||||
|
$this->docker_compose_location = "/docker-compose-pr-{$this->pull_request_id}.yml";
|
||||||
}
|
}
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[
|
[
|
||||||
@ -725,7 +727,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->write_deployment_configurations();
|
$this->write_deployment_configurations();
|
||||||
$this->server = $this->original_server;
|
$this->server = $this->original_server;
|
||||||
}
|
}
|
||||||
if (count($this->application->ports_mappings_array) > 0 || (bool) $this->application->settings->is_consistent_container_name_enabled) {
|
if (count($this->application->ports_mappings_array) > 0 || (bool) $this->application->settings->is_consistent_container_name_enabled || $this->application->pull_request_id !== 0) {
|
||||||
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
||||||
if (count($this->application->ports_mappings_array) > 0) {
|
if (count($this->application->ports_mappings_array) > 0) {
|
||||||
$this->application_deployment_queue->addLogEntry("Application has ports mapped to the host system, rolling update is not supported.");
|
$this->application_deployment_queue->addLogEntry("Application has ports mapped to the host system, rolling update is not supported.");
|
||||||
@ -733,6 +735,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
if ((bool) $this->application->settings->is_consistent_container_name_enabled) {
|
if ((bool) $this->application->settings->is_consistent_container_name_enabled) {
|
||||||
$this->application_deployment_queue->addLogEntry("Consistent container name feature enabled, rolling update is not supported.");
|
$this->application_deployment_queue->addLogEntry("Consistent container name feature enabled, rolling update is not supported.");
|
||||||
}
|
}
|
||||||
|
if ($this->application->pull_request_id !== 0) {
|
||||||
|
$this->application->settings->is_consistent_container_name_enabled = true;
|
||||||
|
$this->application_deployment_queue->addLogEntry("Pull request deployment, rolling update is not supported.");
|
||||||
|
}
|
||||||
$this->stop_running_container(force: true);
|
$this->stop_running_container(force: true);
|
||||||
$this->start_by_compose_file();
|
$this->start_by_compose_file();
|
||||||
} else {
|
} else {
|
||||||
@ -810,26 +816,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->add_build_env_variables_to_dockerfile();
|
$this->add_build_env_variables_to_dockerfile();
|
||||||
}
|
}
|
||||||
$this->build_image();
|
$this->build_image();
|
||||||
$this->stop_running_container();
|
$this->push_to_docker_registry();
|
||||||
if ($this->application->destination->server->isSwarm()) {
|
// $this->stop_running_container();
|
||||||
$this->push_to_docker_registry();
|
$this->rolling_update();
|
||||||
$this->execute_remote_command(
|
|
||||||
[
|
|
||||||
executeInDocker($this->deployment_uuid, "docker stack deploy --with-registry-auth -c {$this->workdir}{$this->docker_compose_location} {$this->application->uuid}-{$this->pull_request_id}")
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->application_deployment_queue->addLogEntry("Starting preview deployment.");
|
|
||||||
if ($this->use_build_server) {
|
|
||||||
$this->execute_remote_command(
|
|
||||||
["SOURCE_COMMIT={$this->commit} docker compose --project-directory {$this->configuration_dir} -f {$this->configuration_dir}{$this->docker_compose_location} up --build -d", "hidden" => true],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->execute_remote_command(
|
|
||||||
[executeInDocker($this->deployment_uuid, "SOURCE_COMMIT={$this->commit} docker compose --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} up --build -d"), "hidden" => true],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private function create_workdir()
|
private function create_workdir()
|
||||||
{
|
{
|
||||||
@ -1226,43 +1215,45 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
// ];
|
// ];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if ((bool)$this->application->settings->is_consistent_container_name_enabled) {
|
if ($this->application->pull_request_id === 0) {
|
||||||
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
|
if ((bool)$this->application->settings->is_consistent_container_name_enabled) {
|
||||||
if (count($custom_compose) > 0) {
|
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
|
||||||
$ipv4 = data_get($custom_compose, 'ip.0');
|
if (count($custom_compose) > 0) {
|
||||||
$ipv6 = data_get($custom_compose, 'ip6.0');
|
$ipv4 = data_get($custom_compose, 'ip.0');
|
||||||
data_forget($custom_compose, 'ip');
|
$ipv6 = data_get($custom_compose, 'ip6.0');
|
||||||
data_forget($custom_compose, 'ip6');
|
data_forget($custom_compose, 'ip');
|
||||||
if ($ipv4 || $ipv6) {
|
data_forget($custom_compose, 'ip6');
|
||||||
data_forget($docker_compose['services'][$this->application->uuid], 'networks');
|
if ($ipv4 || $ipv6) {
|
||||||
|
data_forget($docker_compose['services'][$this->container_name], 'networks');
|
||||||
|
}
|
||||||
|
if ($ipv4) {
|
||||||
|
$docker_compose['services'][$this->container_name]['networks'][$this->destination->network]['ipv4_address'] = $ipv4;
|
||||||
|
}
|
||||||
|
if ($ipv6) {
|
||||||
|
$docker_compose['services'][$this->container_name]['networks'][$this->destination->network]['ipv6_address'] = $ipv6;
|
||||||
|
}
|
||||||
|
$docker_compose['services'][$this->container_name] = array_merge_recursive($docker_compose['services'][$this->container_name], $custom_compose);
|
||||||
}
|
}
|
||||||
if ($ipv4) {
|
} else {
|
||||||
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv4_address'] = $ipv4;
|
$docker_compose['services'][$this->application->uuid] = $docker_compose['services'][$this->container_name];
|
||||||
|
data_forget($docker_compose, 'services.' . $this->container_name);
|
||||||
|
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
|
||||||
|
if (count($custom_compose) > 0) {
|
||||||
|
$ipv4 = data_get($custom_compose, 'ip.0');
|
||||||
|
$ipv6 = data_get($custom_compose, 'ip6.0');
|
||||||
|
data_forget($custom_compose, 'ip');
|
||||||
|
data_forget($custom_compose, 'ip6');
|
||||||
|
if ($ipv4 || $ipv6) {
|
||||||
|
data_forget($docker_compose['services'][$this->application->uuid], 'networks');
|
||||||
|
}
|
||||||
|
if ($ipv4) {
|
||||||
|
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv4_address'] = $ipv4;
|
||||||
|
}
|
||||||
|
if ($ipv6) {
|
||||||
|
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv6_address'] = $ipv6;
|
||||||
|
}
|
||||||
|
$docker_compose['services'][$this->application->uuid] = array_merge_recursive($docker_compose['services'][$this->application->uuid], $custom_compose);
|
||||||
}
|
}
|
||||||
if ($ipv6) {
|
|
||||||
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv6_address'] = $ipv6;
|
|
||||||
}
|
|
||||||
$docker_compose['services'][$this->container_name] = array_merge_recursive($docker_compose['services'][$this->container_name], $custom_compose);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$docker_compose['services'][$this->application->uuid] = $docker_compose['services'][$this->container_name];
|
|
||||||
data_forget($docker_compose, 'services.' . $this->container_name);
|
|
||||||
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
|
|
||||||
if (count($custom_compose) > 0) {
|
|
||||||
$ipv4 = data_get($custom_compose, 'ip.0');
|
|
||||||
$ipv6 = data_get($custom_compose, 'ip6.0');
|
|
||||||
data_forget($custom_compose, 'ip');
|
|
||||||
data_forget($custom_compose, 'ip6');
|
|
||||||
if ($ipv4 || $ipv6) {
|
|
||||||
data_forget($docker_compose['services'][$this->application->uuid], 'networks');
|
|
||||||
}
|
|
||||||
if ($ipv4) {
|
|
||||||
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv4_address'] = $ipv4;
|
|
||||||
}
|
|
||||||
if ($ipv6) {
|
|
||||||
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv6_address'] = $ipv6;
|
|
||||||
}
|
|
||||||
$docker_compose['services'][$this->application->uuid] = array_merge_recursive($docker_compose['services'][$this->application->uuid], $custom_compose);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,18 +1530,18 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
||||||
if ($this->pull_request_id === 0) {
|
if ($this->pull_request_id === 0) {
|
||||||
$containers = $containers->filter(function ($container) {
|
$containers = $containers->filter(function ($container) {
|
||||||
return data_get($container, 'Names') !== $this->container_name;
|
return data_get($container, 'Names') !== $this->container_name && data_get($container, 'Names') !== $this->container_name . '-pr-' . $this->pull_request_id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$containers->each(function ($container) {
|
$containers->each(function ($container) {
|
||||||
$containerName = data_get($container, 'Names');
|
$containerName = data_get($container, 'Names');
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $containerName >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
["docker rm -f $containerName >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
if ($this->application->settings->is_consistent_container_name_enabled) {
|
if ($this->application->settings->is_consistent_container_name_enabled) {
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1559,7 +1550,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
'status' => ApplicationDeploymentStatus::FAILED->value,
|
'status' => ApplicationDeploymentStatus::FAILED->value,
|
||||||
]);
|
]);
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1680,7 +1671,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
// 69420 means failed to push the image to the registry, so we don't need to remove the new version as it is the currently running one
|
// 69420 means failed to push the image to the registry, so we don't need to remove the new version as it is the currently running one
|
||||||
$this->application_deployment_queue->addLogEntry("Deployment failed. Removing the new version of your application.", 'stderr');
|
$this->application_deployment_queue->addLogEntry("Deployment failed. Removing the new version of your application.", 'stderr');
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true]
|
["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,9 @@ class ApplicationPullRequestUpdateJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
if ($this->application->is_public_repository()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ($this->status === ProcessStatus::CLOSED) {
|
if ($this->status === ProcessStatus::CLOSED) {
|
||||||
$this->delete_comment();
|
$this->delete_comment();
|
||||||
return;
|
return;
|
||||||
|
@ -10,7 +10,7 @@ class Configuration extends Component
|
|||||||
{
|
{
|
||||||
public Application $application;
|
public Application $application;
|
||||||
public $servers;
|
public $servers;
|
||||||
protected $listeners = ['build_pack_updated' => '$refresh'];
|
protected $listeners = ['buildPackUpdated' => '$refresh'];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
|
@ -182,7 +182,7 @@ class General extends Component
|
|||||||
$this->resetDefaultLabels(false);
|
$this->resetDefaultLabels(false);
|
||||||
}
|
}
|
||||||
$this->submit();
|
$this->submit();
|
||||||
$this->dispatch('build_pack_updated');
|
$this->dispatch('buildPackUpdated');
|
||||||
}
|
}
|
||||||
public function getWildcardDomain()
|
public function getWildcardDomain()
|
||||||
{
|
{
|
||||||
|
@ -17,9 +17,7 @@ class Configuration extends Component
|
|||||||
{
|
{
|
||||||
$userId = auth()->user()->id;
|
$userId = auth()->user()->id;
|
||||||
return [
|
return [
|
||||||
"echo-private:user.{$userId},ServiceStatusChanged" => 'checkStatus',
|
"echo-private:user.{$userId},ServiceStatusChanged" => 'check_status',
|
||||||
"refreshStacks",
|
|
||||||
"checkStatus",
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
public function render()
|
public function render()
|
||||||
@ -37,21 +35,10 @@ class Configuration extends Component
|
|||||||
$this->applications = $this->service->applications->sort();
|
$this->applications = $this->service->applications->sort();
|
||||||
$this->databases = $this->service->databases->sort();
|
$this->databases = $this->service->databases->sort();
|
||||||
}
|
}
|
||||||
public function checkStatus()
|
public function check_status()
|
||||||
{
|
{
|
||||||
dispatch_sync(new ContainerStatusJob($this->service->server));
|
dispatch_sync(new ContainerStatusJob($this->service->server));
|
||||||
$this->refreshStacks();
|
$this->dispatch('refresh')->self();
|
||||||
$this->dispatch('serviceStatusChanged');
|
$this->dispatch('serviceStatusChanged');
|
||||||
}
|
}
|
||||||
public function refreshStacks()
|
|
||||||
{
|
|
||||||
$this->applications = $this->service->applications->sort();
|
|
||||||
$this->applications->each(function ($application) {
|
|
||||||
$application->refresh();
|
|
||||||
});
|
|
||||||
$this->databases = $this->service->databases->sort();
|
|
||||||
$this->databases->each(function ($database) {
|
|
||||||
$database->refresh();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,20 @@ class Navbar extends Component
|
|||||||
public array $parameters;
|
public array $parameters;
|
||||||
public array $query;
|
public array $query;
|
||||||
public $isDeploymentProgress = false;
|
public $isDeploymentProgress = false;
|
||||||
|
public function getListeners()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"serviceStatusChanged"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
public function serviceStatusChanged()
|
||||||
|
{
|
||||||
|
$this->dispatch('refresh')->self();
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.project.service.navbar');
|
||||||
|
}
|
||||||
public function checkDeployments()
|
public function checkDeployments()
|
||||||
{
|
{
|
||||||
$activity = Activity::where('properties->type_uuid', $this->service->uuid)->latest()->first();
|
$activity = Activity::where('properties->type_uuid', $this->service->uuid)->latest()->first();
|
||||||
@ -28,26 +41,6 @@ class Navbar extends Component
|
|||||||
$this->isDeploymentProgress = false;
|
$this->isDeploymentProgress = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function getListeners()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
"serviceStatusChanged"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
public function serviceStatusChanged()
|
|
||||||
{
|
|
||||||
$this->service->refresh();
|
|
||||||
}
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('livewire.project.service.navbar');
|
|
||||||
}
|
|
||||||
public function check_status($showNotification = false)
|
|
||||||
{
|
|
||||||
dispatch_sync(new ContainerStatusJob($this->service->destination->server));
|
|
||||||
$this->service->refresh();
|
|
||||||
if ($showNotification) $this->dispatch('success', 'Service status updated.');
|
|
||||||
}
|
|
||||||
public function deploy()
|
public function deploy()
|
||||||
{
|
{
|
||||||
$this->checkDeployments();
|
$this->checkDeployments();
|
||||||
@ -62,7 +55,6 @@ class Navbar extends Component
|
|||||||
public function stop(bool $forceCleanup = false)
|
public function stop(bool $forceCleanup = false)
|
||||||
{
|
{
|
||||||
StopService::run($this->service);
|
StopService::run($this->service);
|
||||||
$this->service->refresh();
|
|
||||||
if ($forceCleanup) {
|
if ($forceCleanup) {
|
||||||
$this->dispatch('success', 'Containers cleaned up.');
|
$this->dispatch('success', 'Containers cleaned up.');
|
||||||
} else {
|
} else {
|
||||||
|
@ -65,6 +65,12 @@ class Application extends BaseModel
|
|||||||
return $this->belongsToMany(StandaloneDocker::class, 'additional_destinations')
|
return $this->belongsToMany(StandaloneDocker::class, 'additional_destinations')
|
||||||
->withPivot('server_id', 'status');
|
->withPivot('server_id', 'status');
|
||||||
}
|
}
|
||||||
|
public function is_public_repository(): bool {
|
||||||
|
if (data_get($this, 'source.is_public')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
public function is_github_based(): bool
|
public function is_github_based(): bool
|
||||||
{
|
{
|
||||||
if (data_get($this, 'source')) {
|
if (data_get($this, 'source')) {
|
||||||
|
@ -62,6 +62,9 @@ class Team extends Model implements SendsDiscord, SendsEmail
|
|||||||
}
|
}
|
||||||
static public function serverLimit()
|
static public function serverLimit()
|
||||||
{
|
{
|
||||||
|
if (currentTeam()->id === 0 && isDev()) {
|
||||||
|
return 9999999;
|
||||||
|
}
|
||||||
return Team::find(currentTeam()->id)->limits['serverLimit'];
|
return Team::find(currentTeam()->id)->limits['serverLimit'];
|
||||||
}
|
}
|
||||||
public function limits(): Attribute
|
public function limits(): Attribute
|
||||||
|
@ -7,7 +7,7 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
||||||
'release' => '4.0.0-beta.228',
|
'release' => '4.0.0-beta.229',
|
||||||
// When left empty or `null` the Laravel environment will be used
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.228';
|
return '4.0.0-beta.229';
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<h2>Advanced</h2>
|
<h2>Advanced</h2>
|
||||||
</div>
|
</div>
|
||||||
<div>Advanced configuration for your application.</div>
|
<div>Advanced configuration for your application.</div>
|
||||||
<div class="flex flex-col pt-4 ">
|
<div class="flex flex-col pt-4 w-96">
|
||||||
<h4>General</h4>
|
<h3>General</h3>
|
||||||
@if ($application->git_based())
|
@if ($application->git_based())
|
||||||
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
|
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
|
||||||
id="application.settings.is_auto_deploy_enabled" label="Auto Deploy" />
|
id="application.settings.is_auto_deploy_enabled" label="Auto Deploy" />
|
||||||
@ -20,50 +20,52 @@
|
|||||||
helper="The deployed container will have the same name ({{ $application->uuid }}). <span class='font-bold text-warning'>You will lose the rolling update feature!</span>"
|
helper="The deployed container will have the same name ({{ $application->uuid }}). <span class='font-bold text-warning'>You will lose the rolling update feature!</span>"
|
||||||
instantSave id="application.settings.is_consistent_container_name_enabled"
|
instantSave id="application.settings.is_consistent_container_name_enabled"
|
||||||
label="Consistent Container Names" />
|
label="Consistent Container Names" />
|
||||||
<h4>Logs</h4>
|
<h3>Logs</h3>
|
||||||
@if (!$application->settings->is_raw_compose_deployment_enabled)
|
@if (!$application->settings->is_raw_compose_deployment_enabled)
|
||||||
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
|
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
|
||||||
instantSave id="application.settings.is_log_drain_enabled" label="Drain Logs" />
|
instantSave id="application.settings.is_log_drain_enabled" label="Drain Logs" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($application->git_based())
|
@if ($application->git_based())
|
||||||
<h4>Git</h4>
|
<h3>Git</h3>
|
||||||
<x-forms.checkbox instantSave id="application.settings.is_git_submodules_enabled" label="Git Submodules"
|
<x-forms.checkbox instantSave id="application.settings.is_git_submodules_enabled" label="Submodules"
|
||||||
helper="Allow Git Submodules during build process." />
|
helper="Allow Git Submodules during build process." />
|
||||||
<x-forms.checkbox instantSave id="application.settings.is_git_lfs_enabled" label="Git LFS"
|
<x-forms.checkbox instantSave id="application.settings.is_git_lfs_enabled" label="LFS"
|
||||||
helper="Allow Git LFS during build process." />
|
helper="Allow Git LFS during build process." />
|
||||||
@endif
|
@endif
|
||||||
<h4>GPU</h4>
|
|
||||||
<form wire:submit="submit">
|
|
||||||
@if ($application->build_pack !== 'dockercompose')
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<x-forms.checkbox
|
|
||||||
helper="Enable GPU usage for this application. More info <a href='https://docs.docker.com/compose/gpu-support/' class='text-white underline' target='_blank'>here</a>."
|
|
||||||
instantSave id="application.settings.is_gpu_enabled" label="Attach GPU" />
|
|
||||||
@if ($application->settings->is_gpu_enabled)
|
|
||||||
<x-forms.button type="submiot">Save</x-forms.button>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@if ($application->settings->is_gpu_enabled)
|
|
||||||
<div class="flex flex-col w-full gap-2 p-2 xl:flex-row">
|
|
||||||
<x-forms.input label="GPU Driver" id="application.settings.gpu_driver"> </x-forms.input>
|
|
||||||
<x-forms.input label="GPU Count" placeholder="empty means use all GPUs"
|
|
||||||
id="application.settings.gpu_count"> </x-forms.input>
|
|
||||||
<x-forms.input label="GPU Device Ids" placeholder="0,2"
|
|
||||||
helper="Comma separated list of device ids. More info <a href='https://docs.docker.com/compose/gpu-support/#access-specific-devices' class='text-white underline' target='_blank'>here</a>."
|
|
||||||
id="application.settings.gpu_device_ids"> </x-forms.input>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="px-2">
|
|
||||||
<x-forms.textarea label="GPU Options" id="application.settings.gpu_options">
|
|
||||||
</x-forms.textarea>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</form>
|
|
||||||
{{-- <x-forms.checkbox disabled instantSave id="is_dual_cert" label="Dual Certs?" />
|
{{-- <x-forms.checkbox disabled instantSave id="is_dual_cert" label="Dual Certs?" />
|
||||||
<x-forms.checkbox disabled instantSave id="is_custom_ssl" label="Is Custom SSL?" />
|
<x-forms.checkbox disabled instantSave id="is_custom_ssl" label="Is Custom SSL?" />
|
||||||
<x-forms.checkbox disabled instantSave id="is_http2" label="Is Http2?" /> --}}
|
<x-forms.checkbox disabled instantSave id="is_http2" label="Is Http2?" /> --}}
|
||||||
</div>
|
</div>
|
||||||
|
<h3>GPU</h3>
|
||||||
|
<form wire:submit="submit">
|
||||||
|
@if ($application->build_pack !== 'dockercompose')
|
||||||
|
<div class="w-96">
|
||||||
|
<x-forms.checkbox
|
||||||
|
helper="Enable GPU usage for this application. More info <a href='https://docs.docker.com/compose/gpu-support/' class='text-white underline' target='_blank'>here</a>."
|
||||||
|
instantSave id="application.settings.is_gpu_enabled" label="Attach GPU" />
|
||||||
|
@if ($application->settings->is_gpu_enabled)
|
||||||
|
<h5>GPU Settings</h5>
|
||||||
|
|
||||||
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
@if ($application->settings->is_gpu_enabled)
|
||||||
|
<div class="flex flex-col w-full gap-2 p-2 xl:flex-row">
|
||||||
|
<x-forms.input label="GPU Driver" id="application.settings.gpu_driver"> </x-forms.input>
|
||||||
|
<x-forms.input label="GPU Count" placeholder="empty means use all GPUs"
|
||||||
|
id="application.settings.gpu_count"> </x-forms.input>
|
||||||
|
<x-forms.input label="GPU Device Ids" placeholder="0,2"
|
||||||
|
helper="Comma separated list of device ids. More info <a href='https://docs.docker.com/compose/gpu-support/#access-specific-devices' class='text-white underline' target='_blank'>here</a>."
|
||||||
|
id="application.settings.gpu_device_ids"> </x-forms.input>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="px-2">
|
||||||
|
<x-forms.textarea label="GPU Options" id="application.settings.gpu_options">
|
||||||
|
</x-forms.textarea>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
@if ($isConfigurationChanged && !is_null($application->config_hash) && !$application->isExited())
|
@if ($isConfigurationChanged && !is_null($application->config_hash) && !$application->isExited())
|
||||||
<div title="Configuration not applied to the running application. You need to redeploy.">
|
<div title="Configuration not applied to the running application. You need to redeploy.">
|
||||||
<svg class="w-6 h-6 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-6 h-6 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="currentColor" d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16"/>
|
<path fill="currentColor"
|
||||||
|
d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -100,11 +101,15 @@
|
|||||||
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
@if ($application->destination->server->isSwarm() || $application->additional_servers->count() > 0)
|
@if (
|
||||||
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image" />
|
$application->destination->server->isSwarm() ||
|
||||||
|
$application->additional_servers->count() > 0 ||
|
||||||
|
$application->settings->is_build_server_enabled)
|
||||||
|
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image"
|
||||||
|
placeholder="Required!" />
|
||||||
<x-forms.input id="application.docker_registry_image_tag"
|
<x-forms.input id="application.docker_registry_image_tag"
|
||||||
helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag."
|
helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag."
|
||||||
label="Docker Image Tag" />
|
placeholder="Empty means latest will be used." label="Docker Image Tag" />
|
||||||
@else
|
@else
|
||||||
<x-forms.input id="application.docker_registry_image_name"
|
<x-forms.input id="application.docker_registry_image_name"
|
||||||
helper="Empty means it won't push the image to a docker registry."
|
helper="Empty means it won't push the image to a docker registry."
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<nav wire:poll.30000ms="check_status">
|
<nav wire:poll.5000ms="check_status">
|
||||||
<x-resources.breadcrumbs :resource="$database" :parameters="$parameters" />
|
<x-resources.breadcrumbs :resource="$database" :parameters="$parameters" />
|
||||||
<x-databases.navbar :database="$database" :parameters="$parameters" />
|
<x-databases.navbar :database="$database" :parameters="$parameters" />
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
class="items-center justify-center box">+ Add New Resource</a>
|
class="items-center justify-center box">+ Add New Resource</a>
|
||||||
@else
|
@else
|
||||||
<div x-data="searchComponent()">
|
<div x-data="searchComponent()">
|
||||||
<x-forms.input placeholder="Search for name, fqdn..." class="w-full" x-model="search" />
|
<x-forms.input autofocus="true" placeholder="Search for name, fqdn..." class="w-full" x-model="search" />
|
||||||
<div class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
<div class="grid grid-cols-1 gap-4 pt-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||||
<template x-for="item in filteredApplications" :key="item.id">
|
<template x-for="item in filteredApplications" :key="item.id">
|
||||||
<span>
|
<span>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'service-stack' }" x-init="$wire.checkStatus">
|
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'service-stack' }" x-init="$wire.check_status" wire:poll.5000ms="check_status">
|
||||||
<livewire:project.service.navbar :service="$service" :parameters="$parameters" :query="$query" />
|
<livewire:project.service.navbar :service="$service" :parameters="$parameters" :query="$query" />
|
||||||
<div class="flex h-full pt-6">
|
<div class="flex h-full pt-6">
|
||||||
<div class="flex flex-col items-start gap-4 min-w-fit">
|
<div class="flex flex-col items-start gap-4 min-w-fit">
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<div>No tags yet</div>
|
<div class="py-1">No tags yet</div>
|
||||||
@endforelse
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
<form wire:submit='submit' class="flex items-end gap-2 pt-4">
|
<form wire:submit='submit' class="flex items-end gap-2 pt-4">
|
||||||
@ -23,8 +23,7 @@
|
|||||||
<x-forms.button type="submit">Add</x-forms.button>
|
<x-forms.button type="submit">Add</x-forms.button>
|
||||||
</form>
|
</form>
|
||||||
@if ($tags->count() > 0)
|
@if ($tags->count() > 0)
|
||||||
<h3 class="pt-4">Already defined tags</h3>
|
<h3 class="pt-4">Quickly Add</h3>
|
||||||
<div>Click to quickly add one.</div>
|
|
||||||
<div class="flex gap-2 pt-4">
|
<div class="flex gap-2 pt-4">
|
||||||
@foreach ($tags as $tag)
|
@foreach ($tags as $tag)
|
||||||
<x-forms.button wire:click="addTag('{{ $tag->id }}','{{ $tag->name }}')">
|
<x-forms.button wire:click="addTag('{{ $tag->id }}','{{ $tag->name }}')">
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.228"
|
"version": "4.0.0-beta.229"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user