Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add Docker Registry and Images functionality #4187

Draft
wants to merge 54 commits into
base: next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
b57a439
chore: add registry auth to docker image apps
Nov 8, 2024
15653e6
chore: added registry url with default plus fixed functionality
Nov 8, 2024
5a1431c
chore: remove encrypting token since it should be editable and visibl…
Nov 8, 2024
5187324
fix: revert change
Nov 8, 2024
3130b44
fix: revert some more for less confusion
Nov 8, 2024
60d6189
Merge remote-tracking branch 'upstream/next' into docker-image-login
Nov 8, 2024
02d29d9
chore: info tooltip
Nov 8, 2024
ebf2072
chore: encrypt with casts + masking and interpolation + fixes
Nov 9, 2024
9d08eed
chore: small improvement
Nov 10, 2024
3cd185a
chore: changed migrations, created registries, initial progress
Nov 11, 2024
42de7ec
chore: database, navigation images
Nov 11, 2024
1fd8737
fix: navbar link color
Nov 11, 2024
653d0f3
Merge remote-tracking branch 'upstream/next' into docker-image-login
Nov 11, 2024
65eb856
chore: looks and validation
Nov 11, 2024
8787a9b
Merge branch 'next' into docker-image-login
peaklabs-dev Nov 14, 2024
063d420
chore: svg + new validations
Nov 18, 2024
80b5f92
Merge branch 'docker-image-login' of github.com:OSINTRoach/coolify in…
Nov 18, 2024
b7e00ce
Merge remote-tracking branch 'upstream/next' into docker-image-login
Nov 18, 2024
0e2820f
chore: dockerRegistry
Nov 28, 2024
9e1a78e
Merge branch 'next' into docker-image-login
OSINTRoach Nov 28, 2024
4f7631c
chore: Images
Nov 29, 2024
5167bbd
Merge branch 'docker-image-login' of github.com:OSINTRoach/coolify in…
Nov 29, 2024
557cd55
chore: add list docker images
Dec 3, 2024
03bfcfb
Merge branch 'docker-image-login-davidh' into docker-image-login
Dec 3, 2024
e75f704
Merge branch 'next' into docker-image-login
OSINTRoach Dec 3, 2024
0ff0cad
chore: progress select multiple registries
Dec 3, 2024
f1873ef
Merge branch 'docker-image-login' into budaydev
Dec 3, 2024
08d46bc
chore: multi select on dockerimage build
Dec 3, 2024
0308d36
chore: unique
Dec 3, 2024
37f9266
chore: small fix
Dec 3, 2024
8c32dda
Merge pull request #1 from OSINTRoach/budaydev
OSINTRoach Dec 3, 2024
885d852
chore: fillable bug solved
Dec 4, 2024
9e8cbca
Merge branch 'budaydev' into docker-image-login
Dec 4, 2024
40bf9e2
refactor: list docker images
Dec 5, 2024
8cab528
chore: add get_server_dcoker_image_details
Dec 5, 2024
6a16e71
chore: add container count to image details
Dec 5, 2024
20fcd43
chore: add delete_all_dangling_server_docker_images
Dec 5, 2024
80cedee
Merge remote-tracking branch 'origin/docker-image-login-davidh' into …
Dec 5, 2024
d529f8f
Merge branch 'next' into docker-image-login
peaklabs-dev Dec 6, 2024
dab2290
chore: add delete_server_docker_image
Dec 6, 2024
07c545a
chore: images page in progress
Dec 9, 2024
e7ac684
chore: revert
Dec 9, 2024
fad2b04
refactor: delete_server_docker_image
Dec 10, 2024
f8cff8c
refactor: ListServerDockerImages
Dec 11, 2024
0483f98
refactor: GetServerDockerImageDetails
Dec 11, 2024
58357b1
refactor: ListServerDockerImages
Dec 11, 2024
98e1b54
refactor: ListServerDockerImages
Dec 17, 2024
5e2f4de
refactor: ListServerDockerImages
Dec 19, 2024
c3ae14d
chore: red
Dec 19, 2024
710db04
Merge remote-tracking branch 'upstream/next' into docker-image-login
Dec 19, 2024
e67280d
Merge branch 'docker-image-login-davidh' into docker-image-login
Dec 19, 2024
3879c5a
Merge branch 'docker-image-login' into budaydev
Dec 19, 2024
5c2cf9f
chore: list and details progress
Dec 23, 2024
5f45d68
Merge branch 'next' into docker-image-login
peaklabs-dev Dec 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 105 additions & 47 deletions app/Jobs/ApplicationDeploymentJob.php

Large diffs are not rendered by default.

Empty file.
13 changes: 13 additions & 0 deletions app/Livewire/Images/Images/Index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Livewire\Images\Images;

use Livewire\Component;

class Index extends Component
{
public function render()
{
return view('livewire.images.images.index');
}
}
50 changes: 50 additions & 0 deletions app/Livewire/Images/Registry/Create.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Livewire\Images\Registry;

use App\Models\DockerRegistry;
use Livewire\Component;

class Create extends Component
{
public string $name = '';
public string $type = 'docker_hub';
public ?string $url = null;
public ?string $username = null;
public ?string $token = null;

protected $rules = [
OSINTRoach marked this conversation as resolved.
Show resolved Hide resolved
'name' => 'required|string|max:255',
'type' => 'required|string',
'url' => 'nullable|string|max:255',
'username' => 'nullable|string|max:255',
'token' => 'nullable|string',
];

public function getRegistryTypesProperty()
{
return DockerRegistry::getTypes();
}

public function submit()
{
$this->validate();

DockerRegistry::create([
'name' => $this->name,
'type' => $this->type,
'url' => $this->type === 'custom' ? $this->url : 'docker.io',
'username' => $this->username,
'token' => $this->token,
]);

$this->dispatch('registry-added');
$this->dispatch('success', 'Registry added successfully.');
$this->dispatch('close-modal');
}

public function render()
{
return view('livewire.images.registry.create');
}
}
18 changes: 18 additions & 0 deletions app/Livewire/Images/Registry/Index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App\Livewire\Images\Registry;

use App\Models\DockerRegistry;
use Livewire\Component;

class Index extends Component
{
protected $listeners = ['registry-added' => '$refresh'];

public function render()
{
return view('livewire.images.registry.index', [
'registries' => DockerRegistry::all()
]);
}
}
82 changes: 82 additions & 0 deletions app/Livewire/Images/Registry/Show.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace App\Livewire\Images\Registry;

use App\Models\DockerRegistry;
use Livewire\Component;

class Show extends Component
{
public DockerRegistry $registry;
public string $name = '';
public string $type = '';
public ?string $url = null;
public ?string $username = null;
public ?string $token = null;

protected $rules = [
OSINTRoach marked this conversation as resolved.
Show resolved Hide resolved
'name' => 'required|string|max:255',
'type' => 'required|string',
'url' => 'nullable|string|max:255',
'username' => 'nullable|string|max:255',
'token' => 'nullable|string',
];

public function mount(DockerRegistry $registry)
{
$this->registry = $registry;
$this->name = $registry->name;
$this->type = $registry->type;
$this->url = $registry->url;
$this->username = $registry->username;
$this->token = $registry->token;
}

public function getRegistryTypesProperty()
{
return DockerRegistry::getTypes();
}

public function updateRegistry()
{
$this->validate();

$this->registry->update([
'name' => $this->name,
'type' => $this->type,
'url' => $this->type === 'custom' ? $this->url : 'docker.io',
'username' => $this->username,
'token' => $this->token,
]);

$this->dispatch('success', 'Registry updated successfully.');
}

public function delete()
{
// Update all applications using this registry
$this->registry->applications()
->update([
'docker_registry_id' => null,
'docker_use_custom_registry' => false
]);

$this->registry->delete();
$this->dispatch('registry-added');
$this->dispatch('success', 'Registry deleted successfully.');
}

public function render()
{
return view('livewire.images.registry.show');
}

public function getIsFormDirtyProperty(): bool
{
return $this->name !== $this->registry->name
|| $this->type !== $this->registry->type
|| $this->url !== $this->registry->url
|| $this->username !== $this->registry->username
|| $this->token !== $this->registry->token;
}
}
18 changes: 16 additions & 2 deletions app/Livewire/Project/Application/General.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Actions\Application\GenerateConfig;
use App\Models\Application;
use App\Models\DockerRegistry;
use Illuminate\Support\Collection;
use Livewire\Component;
use Spatie\Url\Url;
Expand Down Expand Up @@ -71,6 +72,8 @@ class General extends Component
'application.dockerfile' => 'nullable',
'application.docker_registry_image_name' => 'nullable',
'application.docker_registry_image_tag' => 'nullable',
'application.docker_use_custom_registry' => 'boolean',
'application.docker_registry_id' => 'nullable|required_if:application.docker_use_custom_registry,true',
'application.dockerfile_location' => 'nullable',
'application.docker_compose_location' => 'nullable',
'application.docker_compose' => 'nullable',
Expand Down Expand Up @@ -113,6 +116,8 @@ class General extends Component
'application.dockerfile' => 'Dockerfile',
'application.docker_registry_image_name' => 'Docker registry image name',
'application.docker_registry_image_tag' => 'Docker registry image tag',
'application.docker_use_custom_registry' => 'Use private registry',
'application.docker_registry_id' => 'Registry',
'application.dockerfile_location' => 'Dockerfile location',
'application.docker_compose_location' => 'Docker compose location',
'application.docker_compose' => 'Docker compose',
Expand Down Expand Up @@ -148,6 +153,7 @@ public function mount()
$this->application->fqdn = null;
$this->application->settings->save();
}

$this->parsedServiceDomains = $this->application->docker_compose_domains ? json_decode($this->application->docker_compose_domains, true) : [];
$this->ports_exposes = $this->application->ports_exposes;
$this->is_preserve_repository_enabled = $this->application->settings->is_preserve_repository_enabled;
Expand Down Expand Up @@ -330,7 +336,7 @@ public function checkFqdns($showToaster = true)
public function set_redirect()
{
try {
$has_www = collect($this->application->fqdns)->filter(fn ($fqdn) => str($fqdn)->contains('www.'))->count();
$has_www = collect($this->application->fqdns)->filter(fn($fqdn) => str($fqdn)->contains('www.'))->count();
if ($has_www === 0 && $this->application->redirect === 'www') {
$this->dispatch('error', 'You want to redirect to www, but you do not have a www domain set.<br><br>Please add www to your domain list and as an A DNS record (if applicable).');

Expand Down Expand Up @@ -389,6 +395,7 @@ public function submit($showToaster = true)
if (data_get($this->application, 'build_pack') === 'dockerimage') {
$this->validate([
'application.docker_registry_image_name' => 'required',
'application.docker_registry_id' => 'required_if:application.docker_use_custom_registry,true',
]);
}

Expand Down Expand Up @@ -447,7 +454,14 @@ public function downloadConfig()
echo $config;
}, $fileName, [
'Content-Type' => 'application/json',
'Content-Disposition' => 'attachment; filename='.$fileName,
'Content-Disposition' => 'attachment; filename=' . $fileName,
]);
}

public function render()
{
return view('livewire.project.application.general', [
'registries' => DockerRegistry::all(),
]);
}
}
35 changes: 22 additions & 13 deletions app/Livewire/Project/New/DockerImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Livewire\Project\New;

use App\Models\Application;
use App\Models\DockerRegistry;
use App\Models\Project;
use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
Expand All @@ -12,11 +13,16 @@
class DockerImage extends Component
{
public string $dockerImage = '';

public bool $useCustomRegistry = false;
public ?int $selectedRegistry = null;
public array $parameters;

public array $query;

protected $rules = [
'dockerImage' => 'required|string',
'selectedRegistry' => 'required_if:useCustomRegistry,true|nullable|exists:docker_registries,id'
];

public function mount()
{
$this->parameters = get_route_parameters();
Expand All @@ -25,15 +31,13 @@ public function mount()

public function submit()
{
$this->validate([
'dockerImage' => 'required',
]);
$this->validate(['dockerImage' => 'required',]);

$image = str($this->dockerImage)->before(':');
if (str($this->dockerImage)->contains(':')) {
$tag = str($this->dockerImage)->after(':');
} else {
$tag = 'latest';
}
$tag = str($this->dockerImage)->contains(':') ?
str($this->dockerImage)->after(':') :
'latest';

$destination_uuid = $this->query['destination'];
$destination = StandaloneDocker::where('uuid', $destination_uuid)->first();
if (! $destination) {
Expand All @@ -46,15 +50,18 @@ public function submit()

$project = Project::where('uuid', $this->parameters['project_uuid'])->first();
$environment = $project->load(['environments'])->environments->where('name', $this->parameters['environment_name'])->first();

$application = Application::create([
'name' => 'docker-image-'.new Cuid2,
'name' => 'docker-image-' . new Cuid2,
'repository_project_id' => 0,
'git_repository' => 'coollabsio/coolify',
'git_branch' => 'main',
'build_pack' => 'dockerimage',
'ports_exposes' => 80,
'docker_registry_image_name' => $image,
'docker_registry_image_tag' => $tag,
'docker_use_custom_registry' => $this->useCustomRegistry,
'docker_registry_id' => $this->selectedRegistry ?? null,
'environment_id' => $environment->id,
'destination_id' => $destination->id,
'destination_type' => $destination_class,
Expand All @@ -63,7 +70,7 @@ public function submit()

$fqdn = generateFqdn($destination->server, $application->uuid);
$application->update([
'name' => 'docker-image-'.$application->uuid,
'name' => 'docker-image-' . $application->uuid,
'fqdn' => $fqdn,
]);

Expand All @@ -76,6 +83,8 @@ public function submit()

public function render()
{
return view('livewire.project.new.docker-image');
return view('livewire.project.new.docker-image', [
'registries' => DockerRegistry::all()
]);
}
}
Loading