mirror of
https://github.com/tiennm99/coolify.git
synced 2026-04-17 19:21:36 +00:00
Refactor application general settings view for improved readability and maintainability
- Adjusted indentation and formatting for better code clarity. - Simplified conditional statements and removed unnecessary null checks. - Enhanced user interface elements for Docker Compose and Dockerfile configurations. - Improved handling of deployment commands and network settings. - Updated helper texts for better user guidance.
This commit is contained in:
@@ -558,8 +558,11 @@ class General extends Component
|
||||
$this->dispatch('refreshStorages');
|
||||
$this->dispatch('refreshEnvs');
|
||||
} catch (\Throwable $e) {
|
||||
$this->application->docker_compose_location = $this->initialDockerComposeLocation;
|
||||
$this->application->save();
|
||||
// Refresh model to get restored values from Application::loadComposeFile
|
||||
$this->application->refresh();
|
||||
// Sync restored values back to component properties for UI update
|
||||
|
||||
$this->syncData();
|
||||
|
||||
return handleError($e, $this);
|
||||
} finally {
|
||||
|
||||
@@ -1584,6 +1584,11 @@ class Application extends BaseModel
|
||||
try {
|
||||
$composeFileContent = instant_remote_process($commands, $this->destination->server);
|
||||
} catch (\Exception $e) {
|
||||
// Restore original values on failure only
|
||||
$this->docker_compose_location = $initialDockerComposeLocation;
|
||||
$this->base_directory = $initialBaseDirectory;
|
||||
$this->save();
|
||||
|
||||
if (str($e->getMessage())->contains('No such file')) {
|
||||
throw new \RuntimeException("Docker Compose file not found at: $workdir$composeFile<br><br>Check if you used the right extension (.yaml or .yml) in the compose file name.");
|
||||
}
|
||||
@@ -1595,9 +1600,7 @@ class Application extends BaseModel
|
||||
}
|
||||
throw new \RuntimeException($e->getMessage());
|
||||
} finally {
|
||||
$this->docker_compose_location = $initialDockerComposeLocation;
|
||||
$this->base_directory = $initialBaseDirectory;
|
||||
$this->save();
|
||||
// Cleanup only - restoration happens in catch block
|
||||
$commands = collect([
|
||||
"rm -rf /tmp/{$uuid}",
|
||||
]);
|
||||
@@ -1643,6 +1646,11 @@ class Application extends BaseModel
|
||||
'initialDockerComposeLocation' => $this->docker_compose_location,
|
||||
];
|
||||
} else {
|
||||
// Restore original values before throwing
|
||||
$this->docker_compose_location = $initialDockerComposeLocation;
|
||||
$this->base_directory = $initialBaseDirectory;
|
||||
$this->save();
|
||||
|
||||
throw new \RuntimeException("Docker Compose file not found at: $workdir$composeFile<br><br>Check if you used the right extension (.yaml or .yml) in the compose file name.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@
|
||||
@if (
|
||||
!is_null($parsedServices) &&
|
||||
count($parsedServices) > 0 &&
|
||||
!$application->settings->is_raw_compose_deployment_enabled
|
||||
)
|
||||
!$application->settings->is_raw_compose_deployment_enabled)
|
||||
<h3 class="pt-6">Domains</h3>
|
||||
@foreach (data_get($parsedServices, 'services') as $serviceName => $service)
|
||||
@if (!isDatabaseImage(data_get($service, 'image')))
|
||||
@@ -166,8 +165,9 @@
|
||||
</div>
|
||||
@if ($application->destination->server->isSwarm())
|
||||
@if ($application->build_pack !== 'dockerimage')
|
||||
<div>Docker Swarm requires the image to be available in a registry. More info <a class="underline"
|
||||
href="https://coolify.io/docs/knowledge-base/docker/registry" target="_blank">here</a>.</div>
|
||||
<div>Docker Swarm requires the image to be available in a registry. More info <a
|
||||
class="underline" href="https://coolify.io/docs/knowledge-base/docker/registry"
|
||||
target="_blank">here</a>.</div>
|
||||
@endif
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@@ -179,7 +179,8 @@
|
||||
helper="Enter a tag (e.g., 'latest', 'v1.2.3') or SHA256 hash (e.g., 'sha256-59e02939b1bf39f16c93138a28727aec520bb916da021180ae502c61626b3cf0')"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
@else
|
||||
<x-forms.input id="dockerRegistryImageName" label="Docker Image" x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input id="dockerRegistryImageName" label="Docker Image"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input id="dockerRegistryImageTag" label="Docker Image Tag or Hash"
|
||||
helper="Enter a tag (e.g., 'latest', 'v1.2.3') or SHA256 hash (e.g., 'sha256-59e02939b1bf39f16c93138a28727aec520bb916da021180ae502c61626b3cf0')"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
@@ -188,10 +189,9 @@
|
||||
@if (
|
||||
$application->destination->server->isSwarm() ||
|
||||
$application->additional_servers->count() > 0 ||
|
||||
$application->settings->is_build_server_enabled
|
||||
)
|
||||
<x-forms.input id="dockerRegistryImageName" required label="Docker Image" placeholder="Required!"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
$application->settings->is_build_server_enabled)
|
||||
<x-forms.input id="dockerRegistryImageName" required label="Docker Image"
|
||||
placeholder="Required!" x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input id="dockerRegistryImageTag"
|
||||
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."
|
||||
placeholder="Empty means latest will be used." label="Docker Image Tag"
|
||||
@@ -199,9 +199,10 @@
|
||||
@else
|
||||
<x-forms.input id="dockerRegistryImageName"
|
||||
helper="Empty means it won't push the image to a docker registry. Pre-tag the image with your registry url if you want to push it to a private registry (default: Dockerhub). <br><br>Example: ghcr.io/myimage"
|
||||
placeholder="Empty means it won't push the image to a docker registry." label="Docker Image"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input id="dockerRegistryImageTag" placeholder="Empty means only push commit sha tag."
|
||||
placeholder="Empty means it won't push the image to a docker registry."
|
||||
label="Docker Image" x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input id="dockerRegistryImageTag"
|
||||
placeholder="Empty means only push commit sha 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" x-bind:disabled="!canUpdate" />
|
||||
@endif
|
||||
@@ -236,10 +237,11 @@
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 pt-6 pb-10">
|
||||
@if ($buildPack === 'dockercompose')
|
||||
<div class="flex flex-col gap-2" @can('update', $application) x-init="$wire.dispatch('loadCompose', true)" @endcan>
|
||||
<div class="flex flex-col gap-2"
|
||||
@can('update', $application) x-init="$wire.dispatch('loadCompose', true)" @endcan>
|
||||
<div x-data="{
|
||||
baseDir: '{{ $application->base_directory }}',
|
||||
composeLocation: '{{ $application->docker_compose_location }}',
|
||||
baseDir: @entangle('baseDirectory'),
|
||||
composeLocation: @entangle('dockerComposeLocation'),
|
||||
normalizePath(path) {
|
||||
if (!path || path.trim() === '') return '/';
|
||||
path = path.trim();
|
||||
@@ -256,12 +258,14 @@
|
||||
this.composeLocation = this.normalizePath(this.composeLocation);
|
||||
}
|
||||
}" class="flex gap-2">
|
||||
<x-forms.input x-bind:disabled="shouldDisable()" placeholder="/" wire:model.defer="baseDirectory"
|
||||
label="Base Directory" helper="Directory to use as root. Useful for monorepos."
|
||||
x-model="baseDir" @blur="normalizeBaseDir()" />
|
||||
<x-forms.input x-bind:disabled="shouldDisable()" placeholder="/docker-compose.yaml"
|
||||
wire:model.defer="dockerComposeLocation" label="Docker Compose Location"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($application->base_directory . $application->docker_compose_location, '/') }}</span>"
|
||||
<x-forms.input x-bind:disabled="shouldDisable()" placeholder="/"
|
||||
label="Base Directory"
|
||||
helper="Directory to use as root. Useful for monorepos." x-model="baseDir"
|
||||
@blur="normalizeBaseDir()" />
|
||||
<x-forms.input x-bind:disabled="shouldDisable()"
|
||||
placeholder="/docker-compose.yaml"
|
||||
label="Docker Compose Location"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($baseDirectory . $dockerComposeLocation, '/') }}</span>"
|
||||
x-model="composeLocation" @blur="normalizeComposeLocation()" />
|
||||
</div>
|
||||
<div class="w-96">
|
||||
@@ -276,12 +280,12 @@
|
||||
know what are
|
||||
you doing.</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input x-bind:disabled="shouldDisable()" placeholder="docker compose build"
|
||||
id="dockerComposeCustomBuildCommand"
|
||||
<x-forms.input x-bind:disabled="shouldDisable()"
|
||||
placeholder="docker compose build" id="dockerComposeCustomBuildCommand"
|
||||
helper="The compose file path (<span class='dark:text-warning'>-f</span> flag) and environment variables (<span class='dark:text-warning'>--env-file</span> flag) are automatically injected based on your Base Directory and Docker Compose Location settings. You can override by providing your own <span class='dark:text-warning'>-f</span> or <span class='dark:text-warning'>--env-file</span> flags.<br><br>If you use this, you need to specify paths relatively and should use the same compose file in the custom command, otherwise the automatically configured labels / etc won't work.<br><br>Example usage: <span class='dark:text-warning'>docker compose build</span>"
|
||||
label="Custom Build Command" />
|
||||
<x-forms.input x-bind:disabled="shouldDisable()" placeholder="docker compose up -d"
|
||||
id="dockerComposeCustomStartCommand"
|
||||
<x-forms.input x-bind:disabled="shouldDisable()"
|
||||
placeholder="docker compose up -d" id="dockerComposeCustomStartCommand"
|
||||
helper="The compose file path (<span class='dark:text-warning'>-f</span> flag) and environment variables (<span class='dark:text-warning'>--env-file</span> flag) are automatically injected based on your Base Directory and Docker Compose Location settings. You can override by providing your own <span class='dark:text-warning'>-f</span> or <span class='dark:text-warning'>--env-file</span> flags.<br><br>If you use this, you need to specify paths relatively and should use the same compose file in the custom command, otherwise the automatically configured labels / etc won't work.<br><br>Example usage: <span class='dark:text-warning'>docker compose up -d</span>"
|
||||
label="Custom Start Command" />
|
||||
</div>
|
||||
@@ -328,26 +332,29 @@
|
||||
this.dockerfileLocation = this.normalizePath(this.dockerfileLocation);
|
||||
}
|
||||
}" class="flex flex-col gap-2 xl:flex-row">
|
||||
<x-forms.input placeholder="/" wire:model.defer="baseDirectory" label="Base Directory"
|
||||
helper="Directory to use as root. Useful for monorepos." x-bind:disabled="!canUpdate"
|
||||
x-model="baseDir" @blur="normalizeBaseDir()" />
|
||||
<x-forms.input placeholder="/" wire:model.defer="baseDirectory"
|
||||
label="Base Directory" helper="Directory to use as root. Useful for monorepos."
|
||||
x-bind:disabled="!canUpdate" x-model="baseDir" @blur="normalizeBaseDir()" />
|
||||
@if ($buildPack === 'dockerfile' && !$application->dockerfile)
|
||||
<x-forms.input placeholder="/Dockerfile" wire:model.defer="dockerfileLocation" label="Dockerfile Location"
|
||||
<x-forms.input placeholder="/Dockerfile" wire:model.defer="dockerfileLocation"
|
||||
label="Dockerfile Location"
|
||||
helper="It is calculated together with the Base Directory:<br><span class='dark:text-warning'>{{ Str::start($application->base_directory . $application->dockerfile_location, '/') }}</span>"
|
||||
x-bind:disabled="!canUpdate" x-model="dockerfileLocation" @blur="normalizeDockerfileLocation()" />
|
||||
x-bind:disabled="!canUpdate" x-model="dockerfileLocation"
|
||||
@blur="normalizeDockerfileLocation()" />
|
||||
@endif
|
||||
|
||||
@if ($buildPack === 'dockerfile')
|
||||
<x-forms.input id="dockerfileTargetBuild" label="Docker Build Stage Target"
|
||||
helper="Useful if you have multi-staged dockerfile." x-bind:disabled="!canUpdate" />
|
||||
helper="Useful if you have multi-staged dockerfile."
|
||||
x-bind:disabled="!canUpdate" />
|
||||
@endif
|
||||
@if ($application->could_set_build_commands())
|
||||
@if ($application->settings->is_static)
|
||||
<x-forms.input placeholder="/dist" id="publishDirectory" label="Publish Directory" required
|
||||
x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input placeholder="/dist" id="publishDirectory"
|
||||
label="Publish Directory" required x-bind:disabled="!canUpdate" />
|
||||
@else
|
||||
<x-forms.input placeholder="/" id="publishDirectory" label="Publish Directory"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input placeholder="/" id="publishDirectory"
|
||||
label="Publish Directory" x-bind:disabled="!canUpdate" />
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@@ -363,7 +370,8 @@
|
||||
<x-forms.input
|
||||
helper="You can add custom docker run options that will be used when your container is started.<br>Note: Not all options are supported, as they could mess up Coolify's automation and could cause bad experience for users.<br><br>Check the <a class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/docker/custom-commands'>docs.</a>"
|
||||
placeholder="--cap-add SYS_ADMIN --device=/dev/fuse --security-opt apparmor:unconfined --ulimit nofile=1024:1024 --tmpfs /run:rw,noexec,nosuid,size=65536k --hostname=myapp"
|
||||
id="customDockerRunOptions" label="Custom Docker Options" x-bind:disabled="!canUpdate" />
|
||||
id="customDockerRunOptions" label="Custom Docker Options"
|
||||
x-bind:disabled="!canUpdate" />
|
||||
|
||||
@if ($buildPack !== 'dockercompose')
|
||||
<div class="pt-2 w-96">
|
||||
@@ -381,7 +389,9 @@
|
||||
<div x-data="{ showRaw: true }">
|
||||
<div class="flex items-center gap-2">
|
||||
<h3>Docker Compose</h3>
|
||||
<x-forms.button x-show="!($application->settings->is_raw_compose_deployment_enabled)" @click.prevent="showRaw = !showRaw" x-text="showRaw ? 'Show Deployable Compose' : 'Show Raw Compose'"></x-forms.button>
|
||||
<x-forms.button x-show="!($application->settings->is_raw_compose_deployment_enabled)"
|
||||
@click.prevent="showRaw = !showRaw"
|
||||
x-text="showRaw ? 'Show Deployable Compose' : 'Show Raw Compose'"></x-forms.button>
|
||||
</div>
|
||||
@if ($application->settings->is_raw_compose_deployment_enabled)
|
||||
<x-forms.textarea rows="10" readonly id="dockerComposeRaw"
|
||||
@@ -391,13 +401,15 @@
|
||||
@else
|
||||
@if ((int) $application->compose_parsing_version >= 3)
|
||||
<div x-show="showRaw">
|
||||
<x-forms.textarea rows="10" readonly id="dockerComposeRaw" label="Docker Compose Content (raw)"
|
||||
<x-forms.textarea rows="10" readonly id="dockerComposeRaw"
|
||||
label="Docker Compose Content (raw)"
|
||||
helper="You need to modify the docker compose file in the git repository."
|
||||
monacoEditorLanguage="yaml" useMonacoEditor />
|
||||
</div>
|
||||
@endif
|
||||
<div x-show="showRaw === false">
|
||||
<x-forms.textarea rows="10" readonly id="dockerCompose" label="Docker Compose Content"
|
||||
<x-forms.textarea rows="10" readonly id="dockerCompose"
|
||||
label="Docker Compose Content"
|
||||
helper="You need to modify the docker compose file in the git repository."
|
||||
monacoEditorLanguage="yaml" useMonacoEditor />
|
||||
</div>
|
||||
@@ -405,7 +417,8 @@
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox label="Escape special characters in labels?"
|
||||
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."
|
||||
id="isContainerLabelEscapeEnabled" instantSave x-bind:disabled="!canUpdate"></x-forms.checkbox>
|
||||
id="isContainerLabelEscapeEnabled" instantSave
|
||||
x-bind:disabled="!canUpdate"></x-forms.checkbox>
|
||||
{{-- <x-forms.checkbox label="Readonly labels"
|
||||
helper="Labels are readonly by default. Readonly means that edits you do to the labels could be lost and Coolify will autogenerate the labels for you. If you want to edit the labels directly, disable this option. <br><br>Be careful, it could break the proxy configuration after you restart the container as Coolify will now NOT autogenerate the labels for you (ofc you can always reset the labels to the coolify defaults manually)."
|
||||
id="isContainerLabelReadonlyEnabled" instantSave></x-forms.checkbox> --}}
|
||||
@@ -413,8 +426,8 @@
|
||||
</div>
|
||||
@endif
|
||||
@if ($application->dockerfile)
|
||||
<x-forms.textarea label="Dockerfile" id="dockerfile" monacoEditorLanguage="dockerfile" useMonacoEditor
|
||||
rows="6" x-bind:disabled="!canUpdate"> </x-forms.textarea>
|
||||
<x-forms.textarea label="Dockerfile" id="dockerfile" monacoEditorLanguage="dockerfile"
|
||||
useMonacoEditor rows="6" x-bind:disabled="!canUpdate"> </x-forms.textarea>
|
||||
@endif
|
||||
@if ($buildPack !== 'dockercompose')
|
||||
<h3 class="pt-8">Network</h3>
|
||||
@@ -431,8 +444,10 @@
|
||||
<span class="font-semibold">PORT environment variable detected
|
||||
({{ $this->detectedPortInfo['port'] }})</span>
|
||||
<p class="mt-1">Your Ports Exposes field is empty. Consider setting it to
|
||||
<strong>{{ $this->detectedPortInfo['port'] }}</strong> to ensure the proxy routes traffic
|
||||
correctly.</p>
|
||||
<strong>{{ $this->detectedPortInfo['port'] }}</strong> to ensure the proxy routes
|
||||
traffic
|
||||
correctly.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@elseif (!$this->detectedPortInfo['matches'])
|
||||
@@ -446,8 +461,10 @@
|
||||
<div>
|
||||
<span class="font-semibold">PORT mismatch detected</span>
|
||||
<p class="mt-1">Your PORT environment variable is set to
|
||||
<strong>{{ $this->detectedPortInfo['port'] }}</strong>, but it's not in your Ports Exposes
|
||||
configuration. Ensure they match for proper proxy routing.</p>
|
||||
<strong>{{ $this->detectedPortInfo['port'] }}</strong>, but it's not in your Ports
|
||||
Exposes
|
||||
configuration. Ensure they match for proper proxy routing.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
@@ -460,7 +477,8 @@
|
||||
</svg>
|
||||
<div>
|
||||
<span class="font-semibold">PORT environment variable configured</span>
|
||||
<p class="mt-1">Your PORT environment variable ({{ $this->detectedPortInfo['port'] }}) matches
|
||||
<p class="mt-1">Your PORT environment variable
|
||||
({{ $this->detectedPortInfo['port'] }}) matches
|
||||
your Ports Exposes configuration.</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -468,7 +486,8 @@
|
||||
@endif
|
||||
<div class="flex flex-col gap-2 xl:flex-row">
|
||||
@if ($isStatic || $buildPack === 'static')
|
||||
<x-forms.input id="portsExposes" label="Ports Exposes" readonly x-bind:disabled="!canUpdate" />
|
||||
<x-forms.input id="portsExposes" label="Ports Exposes" readonly
|
||||
x-bind:disabled="!canUpdate" />
|
||||
@else
|
||||
@if ($application->settings->is_container_label_readonly_enabled === false)
|
||||
<x-forms.input placeholder="3000,3001" id="portsExposes" label="Ports Exposes" readonly
|
||||
@@ -512,8 +531,8 @@
|
||||
<x-forms.textarea readonly disabled label="Container Labels" rows="15" id="customLabels"
|
||||
monacoEditorLanguage="ini" useMonacoEditor x-bind:disabled="!canUpdate"></x-forms.textarea>
|
||||
@else
|
||||
<x-forms.textarea label="Container Labels" rows="15" id="customLabels" monacoEditorLanguage="ini"
|
||||
useMonacoEditor x-bind:disabled="!canUpdate"></x-forms.textarea>
|
||||
<x-forms.textarea label="Container Labels" rows="15" id="customLabels"
|
||||
monacoEditorLanguage="ini" useMonacoEditor x-bind:disabled="!canUpdate"></x-forms.textarea>
|
||||
@endif
|
||||
<div class="w-96">
|
||||
<x-forms.checkbox label="Readonly labels"
|
||||
@@ -522,7 +541,8 @@
|
||||
x-bind:disabled="!canUpdate"></x-forms.checkbox>
|
||||
<x-forms.checkbox label="Escape special characters in labels?"
|
||||
helper="By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$.<br><br>If you want to use env variables inside the labels, turn this off."
|
||||
id="isContainerLabelEscapeEnabled" instantSave x-bind:disabled="!canUpdate"></x-forms.checkbox>
|
||||
id="isContainerLabelEscapeEnabled" instantSave
|
||||
x-bind:disabled="!canUpdate"></x-forms.checkbox>
|
||||
</div>
|
||||
@can('update', $application)
|
||||
<x-modal-confirmation title="Confirm Labels Reset to Coolify Defaults?"
|
||||
@@ -561,8 +581,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<x-domain-conflict-modal :conflicts="$domainConflicts" :showModal="$showDomainConflictModal"
|
||||
confirmAction="confirmDomainUsage" />
|
||||
<x-domain-conflict-modal :conflicts="$domainConflicts" :showModal="$showDomainConflictModal" confirmAction="confirmDomainUsage" />
|
||||
|
||||
@script
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user