feat: able to deploy docker images
This commit is contained in:
@@ -49,6 +49,8 @@ class General extends Component
|
|||||||
'application.ports_exposes' => 'required',
|
'application.ports_exposes' => 'required',
|
||||||
'application.ports_mappings' => 'nullable',
|
'application.ports_mappings' => 'nullable',
|
||||||
'application.dockerfile' => 'nullable',
|
'application.dockerfile' => 'nullable',
|
||||||
|
'application.docker_registry_image_name' => 'nullable',
|
||||||
|
'application.docker_registry_image_tag' => 'nullable',
|
||||||
];
|
];
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'application.name' => 'name',
|
'application.name' => 'name',
|
||||||
@@ -67,6 +69,8 @@ class General extends Component
|
|||||||
'application.ports_exposes' => 'Ports exposes',
|
'application.ports_exposes' => 'Ports exposes',
|
||||||
'application.ports_mappings' => 'Ports mappings',
|
'application.ports_mappings' => 'Ports mappings',
|
||||||
'application.dockerfile' => 'Dockerfile',
|
'application.dockerfile' => 'Dockerfile',
|
||||||
|
'application.docker_registry_image_name' => 'Docker registry image name',
|
||||||
|
'application.docker_registry_image_tag' => 'Docker registry image tag',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -26,7 +26,11 @@ class DockerImage extends Component
|
|||||||
'dockerImage' => 'required'
|
'dockerImage' => 'required'
|
||||||
]);
|
]);
|
||||||
$image = Str::of($this->dockerImage)->before(':');
|
$image = Str::of($this->dockerImage)->before(':');
|
||||||
$tag = Str::of($this->dockerImage)->after(':') ?: 'latest';
|
if (Str::of($this->dockerImage)->contains(':')) {
|
||||||
|
$tag = Str::of($this->dockerImage)->after(':');
|
||||||
|
} else {
|
||||||
|
$tag = 'latest';
|
||||||
|
}
|
||||||
$destination_uuid = $this->query['destination'];
|
$destination_uuid = $this->query['destination'];
|
||||||
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
|
||||||
if (!$destination) {
|
if (!$destination) {
|
||||||
@@ -39,6 +43,7 @@ class DockerImage extends Component
|
|||||||
|
|
||||||
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
|
||||||
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();
|
||||||
|
ray($image,$tag);
|
||||||
$application = Application::create([
|
$application = Application::create([
|
||||||
'name' => 'docker-image-' . new Cuid2(7),
|
'name' => 'docker-image-' . new Cuid2(7),
|
||||||
'repository_project_id' => 0,
|
'repository_project_id' => 0,
|
||||||
|
@@ -45,6 +45,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
private string $commit;
|
private string $commit;
|
||||||
private bool $force_rebuild;
|
private bool $force_rebuild;
|
||||||
|
|
||||||
|
private ?string $dockerImage = null;
|
||||||
|
private ?string $dockerImageTag = null;
|
||||||
|
|
||||||
private GithubApp|GitlabApp|string $source = 'other';
|
private GithubApp|GitlabApp|string $source = 'other';
|
||||||
private StandaloneDocker|SwarmDocker $destination;
|
private StandaloneDocker|SwarmDocker $destination;
|
||||||
private Server $server;
|
private Server $server;
|
||||||
@@ -135,6 +138,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
try {
|
try {
|
||||||
if ($this->application->dockerfile) {
|
if ($this->application->dockerfile) {
|
||||||
$this->deploy_simple_dockerfile();
|
$this->deploy_simple_dockerfile();
|
||||||
|
} else if ($this->application->build_pack === 'dockerimage') {
|
||||||
|
$this->deploy_dockerimage();
|
||||||
} else {
|
} else {
|
||||||
if ($this->pull_request_id !== 0) {
|
if ($this->pull_request_id !== 0) {
|
||||||
$this->deploy_pull_request();
|
$this->deploy_pull_request();
|
||||||
@@ -245,6 +250,21 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->rolling_update();
|
$this->rolling_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function deploy_dockerimage()
|
||||||
|
{
|
||||||
|
$this->dockerImage = $this->application->docker_registry_image_name;
|
||||||
|
$this->dockerImageTag = $this->application->docker_registry_image_tag;
|
||||||
|
ray("echo 'Starting deployment of {$this->dockerImage}:{$this->dockerImageTag}.'");
|
||||||
|
$this->execute_remote_command(
|
||||||
|
[
|
||||||
|
"echo 'Starting deployment of {$this->dockerImage}:{$this->dockerImageTag}.'"
|
||||||
|
],
|
||||||
|
);
|
||||||
|
$this->production_image_name = Str::lower("{$this->dockerImage}:{$this->dockerImageTag}");
|
||||||
|
$this->prepare_builder_image();
|
||||||
|
$this->generate_compose_file();
|
||||||
|
$this->rolling_update();
|
||||||
|
}
|
||||||
private function deploy()
|
private function deploy()
|
||||||
{
|
{
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
@@ -398,7 +418,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function set_base_dir() {
|
private function set_base_dir()
|
||||||
|
{
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[
|
[
|
||||||
"echo -n 'Setting base directory to {$this->workdir}.'"
|
"echo -n 'Setting base directory to {$this->workdir}.'"
|
||||||
@@ -671,7 +692,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
|
|
||||||
private function generate_healthcheck_commands()
|
private function generate_healthcheck_commands()
|
||||||
{
|
{
|
||||||
if ($this->application->dockerfile || $this->application->build_pack === 'dockerfile') {
|
if ($this->application->dockerfile || $this->application->build_pack === 'dockerfile' || $this->application->build_pack === 'dockerimage') {
|
||||||
// TODO: disabled HC because there are several ways to hc a simple docker image, hard to figure out a good way. Like some docker images (pocketbase) does not have curl.
|
// TODO: disabled HC because there are several ways to hc a simple docker image, hard to figure out a good way. Like some docker images (pocketbase) does not have curl.
|
||||||
return 'exit 0';
|
return 'exit 0';
|
||||||
}
|
}
|
||||||
|
@@ -259,13 +259,14 @@ class Application extends BaseModel
|
|||||||
if ($this->dockerfile) {
|
if ($this->dockerfile) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ($this->build_pack === 'dockerimage'){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public function isHealthcheckDisabled(): bool
|
public function isHealthcheckDisabled(): bool
|
||||||
{
|
{
|
||||||
if (data_get($this, 'dockerfile') || data_get($this, 'build_pack') === 'dockerfile' || data_get($this, 'health_check_enabled') === false) {
|
if (data_get($this, 'dockerfile') || data_get($this, 'build_pack') === 'dockerfile' || data_get($this, 'health_check_enabled') === false) {
|
||||||
ray('dockerfile');
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
<x-applications.advanced :application="$application" />
|
<x-applications.advanced :application="$application" />
|
||||||
|
|
||||||
@if ($application->status !== 'exited')
|
@if ($application->status !== 'exited')
|
||||||
<button wire:click='deploy' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
<button title="With rolling update if possible" wire:click='deploy' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-warning" viewBox="0 0 24 24" stroke-width="2"
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-warning" viewBox="0 0 24 24" stroke-width="2"
|
||||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
</path>
|
</path>
|
||||||
<path d="M7.05 11.038v-3.988"></path>
|
<path d="M7.05 11.038v-3.988"></path>
|
||||||
</svg>
|
</svg>
|
||||||
Restart
|
Redeploy
|
||||||
</button>
|
</button>
|
||||||
<button wire:click='stop' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
<button wire:click='stop' class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24" stroke-width="2"
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-error" viewBox="0 0 24 24" stroke-width="2"
|
||||||
|
@@ -42,28 +42,37 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<h3>Build</h3>
|
@if ($application->build_pack !== 'dockerimage')
|
||||||
@if ($application->could_set_build_commands())
|
<h3>Build</h3>
|
||||||
|
@if ($application->could_set_build_commands())
|
||||||
|
<div class="flex flex-col gap-2 xl:flex-row">
|
||||||
|
<x-forms.input placeholder="pnpm install" id="application.install_command"
|
||||||
|
label="Install Command" />
|
||||||
|
<x-forms.input placeholder="pnpm build" id="application.build_command" label="Build Command" />
|
||||||
|
<x-forms.input placeholder="pnpm start" id="application.start_command" label="Start Command" />
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="flex flex-col gap-2 xl:flex-row">
|
<div class="flex flex-col gap-2 xl:flex-row">
|
||||||
<x-forms.input placeholder="pnpm install" id="application.install_command"
|
<x-forms.input placeholder="/" id="application.base_directory" label="Base Directory"
|
||||||
label="Install Command" />
|
helper="Directory to use as root. Useful for monorepos." />
|
||||||
<x-forms.input placeholder="pnpm build" id="application.build_command" label="Build Command" />
|
@if ($application->could_set_build_commands())
|
||||||
<x-forms.input placeholder="pnpm start" id="application.start_command" label="Start Command" />
|
@if ($application->settings->is_static)
|
||||||
|
<x-forms.input placeholder="/dist" id="application.publish_directory"
|
||||||
|
label="Publish Directory" required />
|
||||||
|
@else
|
||||||
|
<x-forms.input placeholder="/" id="application.publish_directory"
|
||||||
|
label="Publish Directory" />
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="flex flex-col gap-2 xl:flex-row">
|
||||||
|
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image" />
|
||||||
|
<x-forms.input id="application.docker_registry_image_tag" required label="Docker Image Tag" />
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="flex flex-col gap-2 xl:flex-row">
|
|
||||||
<x-forms.input placeholder="/" id="application.base_directory" label="Base Directory"
|
|
||||||
helper="Directory to use as root. Useful for monorepos." />
|
|
||||||
@if ($application->could_set_build_commands())
|
|
||||||
@if ($application->settings->is_static)
|
|
||||||
<x-forms.input placeholder="/dist" id="application.publish_directory" label="Publish Directory"
|
|
||||||
required />
|
|
||||||
@else
|
|
||||||
<x-forms.input placeholder="/" id="application.publish_directory" label="Publish Directory" />
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
@if ($application->dockerfile)
|
@if ($application->dockerfile)
|
||||||
<x-forms.textarea label="Dockerfile" id="application.dockerfile" rows="6"> </x-forms.textarea>
|
<x-forms.textarea label="Dockerfile" id="application.dockerfile" rows="6"> </x-forms.textarea>
|
||||||
@endif
|
@endif
|
||||||
@@ -82,7 +91,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3>Advanced</h3>
|
<h3>Advanced</h3>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
|
|
||||||
<x-forms.checkbox
|
<x-forms.checkbox
|
||||||
helper="Your application will be available only on https if your domain starts with https://..."
|
helper="Your application will be available only on https if your domain starts with https://..."
|
||||||
instantSave id="is_force_https_enabled" label="Force Https" />
|
instantSave id="is_force_https_enabled" label="Force Https" />
|
||||||
|
@@ -6,6 +6,6 @@
|
|||||||
<h2>Docker Image</h2>
|
<h2>Docker Image</h2>
|
||||||
<x-forms.button type="submit">Save</x-forms.button>
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
<x-forms.input rows="20" id="dockerImage" placeholder="nginx"></x-forms.textarea>
|
<x-forms.input rows="20" id="dockerImage" placeholder="nginx:latest"></x-forms.textarea>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user