diff --git a/app/Actions/Database/StartMariadb.php b/app/Actions/Database/StartMariadb.php index f9d516634..8dca584f2 100644 --- a/app/Actions/Database/StartMariadb.php +++ b/app/Actions/Database/StartMariadb.php @@ -106,7 +106,6 @@ class StartMariadb $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; - $database_name = addslashes($database->name); $this->commands[] = "echo 'Database started.'"; return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } diff --git a/app/Actions/Database/StartMongodb.php b/app/Actions/Database/StartMongodb.php index b5c4dde88..ef04a9be8 100644 --- a/app/Actions/Database/StartMongodb.php +++ b/app/Actions/Database/StartMongodb.php @@ -122,7 +122,6 @@ class StartMongodb $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; - $database_name = addslashes($database->name); $this->commands[] = "echo 'Database started.'"; return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } diff --git a/app/Actions/Database/StartMysql.php b/app/Actions/Database/StartMysql.php index a103b3531..3b47483a3 100644 --- a/app/Actions/Database/StartMysql.php +++ b/app/Actions/Database/StartMysql.php @@ -106,7 +106,6 @@ class StartMysql $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; - $database_name = addslashes($database->name); $this->commands[] = "echo 'Database started.'"; return remote_process($this->commands, $database->destination->server,callEventOnFinish: 'DatabaseStatusChanged'); } diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index a77d09381..844f81c31 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -128,7 +128,6 @@ class StartPostgresql $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; - $database_name = addslashes($database->name); $this->commands[] = "echo 'Database started.'"; return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index f6e8b3780..e1a8eef41 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -117,7 +117,6 @@ class StartRedis $this->commands[] = "echo 'Pulling {$database->image} image.'"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml pull"; $this->commands[] = "docker compose -f $this->configuration_dir/docker-compose.yml up -d"; - $database_name = addslashes($database->name); $this->commands[] = "echo 'Database started.'"; return remote_process($this->commands, $database->destination->server, callEventOnFinish: 'DatabaseStatusChanged'); } diff --git a/app/Actions/Service/StartService.php b/app/Actions/Service/StartService.php index 84f954e80..6ec71c4f3 100644 --- a/app/Actions/Service/StartService.php +++ b/app/Actions/Service/StartService.php @@ -13,10 +13,6 @@ class StartService { ray('Starting service: ' . $service->name); $service->saveComposeConfigs(); - - $service_name = addslashes($service->name); - $server_name = addslashes($service->server->name); - $commands[] = "cd " . $service->workdir(); $commands[] = "echo 'Saved configuration files to {$service->workdir()}.'"; $commands[] = "echo 'Creating Docker network.'"; diff --git a/app/Livewire/Boarding/Index.php b/app/Livewire/Boarding/Index.php index 8cb1dd7d2..2b73957df 100644 --- a/app/Livewire/Boarding/Index.php +++ b/app/Livewire/Boarding/Index.php @@ -206,7 +206,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== try { config()->set('coolify.mux_enabled', false); - instant_remote_process(['uptime'], $this->createdServer, true); + // EC2 does not have `uptime` command, lol + instant_remote_process(['ls /'], $this->createdServer, true); $this->createdServer->settings()->update([ 'is_reachable' => true, diff --git a/app/Livewire/Project/Service/ServiceApplicationView.php b/app/Livewire/Project/Service/ServiceApplicationView.php index a17494d1d..53532a855 100644 --- a/app/Livewire/Project/Service/ServiceApplicationView.php +++ b/app/Livewire/Project/Service/ServiceApplicationView.php @@ -17,6 +17,7 @@ class ServiceApplicationView extends Component 'application.exclude_from_status' => 'required|boolean', 'application.required_fqdn' => 'required|boolean', 'application.is_log_drain_enabled' => 'nullable|boolean', + 'application.is_gzip_enabled' => 'nullable|boolean', ]; public function render() { diff --git a/app/Livewire/Project/Service/StackForm.php b/app/Livewire/Project/Service/StackForm.php index 894428182..44672fe64 100644 --- a/app/Livewire/Project/Service/StackForm.php +++ b/app/Livewire/Project/Service/StackForm.php @@ -45,8 +45,10 @@ class StackForm extends Component $this->service->docker_compose_raw = $raw; $this->submit(); } - public function instantSave() { + public function instantSave() + { $this->service->save(); + $this->dispatch('success', 'Service settings saved successfully.'); } public function submit() diff --git a/app/Livewire/Project/Shared/Destination.php b/app/Livewire/Project/Shared/Destination.php index 3d816149b..6981886bf 100644 --- a/app/Livewire/Project/Shared/Destination.php +++ b/app/Livewire/Project/Shared/Destination.php @@ -37,6 +37,9 @@ class Destination extends Component $this->networks = $this->networks->reject(function ($network) use ($all_networks) { return $all_networks->pluck('id')->contains($network->id); }); + $this->networks = $this->networks->reject(function ($network) { + return $this->resource->destination->server->id == $network->server->id; + }); } public function redeploy(int $network_id, int $server_id) { @@ -70,7 +73,7 @@ class Destination extends Component } public function removeServer(int $network_id, int $server_id) { - if ($this->resource->destination->server->id == $server_id) { + if ($this->resource->destination->server->id == $server_id && $this->resource->destination->id == $network_id) { $this->dispatch('error', 'You cannot remove this destination server.', 'You are trying to remove the main server.'); return; } diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index bb9c7c3a1..239fa86bd 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -13,8 +13,9 @@ class Form extends Component public ?string $wildcard_domain = null; public int $cleanup_after_percentage; public bool $dockerInstallationStarted = false; + public bool $revalidate = false; - protected $listeners = ['serverInstalled']; + protected $listeners = ['serverInstalled', 'revalidate' => '$refresh']; protected $rules = [ 'server.name' => 'required', @@ -68,6 +69,10 @@ class Form extends Component return handleError($e, $this); } } + public function revalidate() + { + $this->revalidate = true; + } public function checkLocalhostConnection() { $uptime = $this->server->validateConnection(); diff --git a/app/Livewire/Server/ValidateAndInstall.php b/app/Livewire/Server/ValidateAndInstall.php index 4d37feca2..b5c46fa32 100644 --- a/app/Livewire/Server/ValidateAndInstall.php +++ b/app/Livewire/Server/ValidateAndInstall.php @@ -19,12 +19,12 @@ class ValidateAndInstall extends Component public $docker_version = null; public $proxy_started = false; public $error = null; + public bool $ask = false; protected $listeners = ['validateServer' => 'init', 'validateDockerEngine', 'validateServerNow' => 'validateServer']; public function init(bool $install = true) { - $this->install = $install; $this->uptime = null; $this->supported_os_type = null; @@ -34,9 +34,14 @@ class ValidateAndInstall extends Component $this->proxy_started = null; $this->error = null; $this->number_of_tries = 0; - $this->dispatch('validateServerNow'); + if (!$this->ask) { + $this->dispatch('validateServerNow'); + } + } + public function startValidatingAfterAsking() { + $this->ask = false; + $this->init(); } - public function validateServer() { try { diff --git a/app/Models/Server.php b/app/Models/Server.php index e4a7b895a..f19943d05 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -400,7 +400,9 @@ class Server extends BaseModel if ($server->skipServer()) { return false; } - $uptime = instant_remote_process(['uptime'], $server, false); + // EC2 does not have `uptime` command, lol + + $uptime = instant_remote_process(['ls /'], $server, false); if (!$uptime) { $server->settings()->update([ 'is_reachable' => false, diff --git a/app/Models/ServiceApplication.php b/app/Models/ServiceApplication.php index be1eb0f6d..314a01ba3 100644 --- a/app/Models/ServiceApplication.php +++ b/app/Models/ServiceApplication.php @@ -23,6 +23,10 @@ class ServiceApplication extends BaseModel { return data_get($this, 'is_log_drain_enabled', false); } + public function isGzipEnabled() + { + return data_get($this, 'is_gzip_enabled', true); + } public function type() { return 'service'; diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index 0bde42c20..31bd2786d 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -21,6 +21,10 @@ class ServiceDatabase extends BaseModel { return data_get($this, 'is_log_drain_enabled', false); } + public function isGzipEnabled() + { + return true; + } public function type() { return 'service'; diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index f01eb972f..7b367c63c 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -7,7 +7,6 @@ use App\Models\ServiceApplication; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Spatie\Url\Url; -use Visus\Cuid2\Cuid2; function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection { @@ -213,7 +212,7 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource, } return $payload; } -function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null) +function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled = false, $onlyPort = null, ?Collection $serviceLabels = null, ?bool $is_gzip_enabled = true) { $labels = collect([]); $labels->push('traefik.enable=true'); @@ -276,23 +275,35 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ } if ($path !== '/') { $labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}"); - $middlewares = "gzip,{$https_label}-stripprefix"; - if ($basic_auth && $basic_auth_middleware) { - $middlewares = $middlewares . ',' . $basic_auth_middleware; + $middlewares = collect(["{$https_label}-stripprefix"]); + if ($is_gzip_enabled) { + $middlewares->push('gzip'); } - if ($redirect && $redirect_middleware) { - $middlewares = $middlewares . ',' . $redirect_middleware; - } - $labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}"); - } else { - $middlewares = "gzip"; if ($basic_auth && $basic_auth_middleware) { - $middlewares = $middlewares . ',' . $basic_auth_middleware; + $middlewares->push($basic_auth_middleware); } if ($redirect && $redirect_middleware) { - $middlewares = $middlewares . ',' . $redirect_middleware; + $middlewares->push($redirect_middleware); + } + if ($middlewares->isNotEmpty()) { + $middlewares = $middlewares->join(','); + $labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}"); + } + } else { + $middlewares = collect([]); + if ($is_gzip_enabled) { + $middlewares->push('gzip'); + } + if ($basic_auth && $basic_auth_middleware) { + $middlewares->push($basic_auth_middleware); + } + if ($redirect && $redirect_middleware) { + $middlewares->push($redirect_middleware); + } + if ($middlewares->isNotEmpty()) { + $middlewares = $middlewares->join(','); + $labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}"); } - $labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}"); } $labels->push("traefik.http.routers.{$https_label}.tls=true"); $labels->push("traefik.http.routers.{$https_label}.tls.certresolver=letsencrypt"); @@ -317,23 +328,35 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ } if ($path !== '/') { $labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}"); - $middlewares = "gzip,{$http_label}-stripprefix"; - if ($basic_auth && $basic_auth_middleware) { - $middlewares = $middlewares . ',' . $basic_auth_middleware; + $middlewares = collect(["{$http_label}-stripprefix"]); + if ($is_gzip_enabled) { + $middlewares->push('gzip'); } - if ($redirect && $redirect_middleware) { - $middlewares = $middlewares . ',' . $redirect_middleware; - } - $labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}"); - } else { - $middlewares = "gzip"; if ($basic_auth && $basic_auth_middleware) { - $middlewares = $middlewares . ',' . $basic_auth_middleware; + $middlewares->push($basic_auth_middleware); } if ($redirect && $redirect_middleware) { - $middlewares = $middlewares . ',' . $redirect_middleware; + $middlewares->push($redirect_middleware); + } + if ($middlewares->isNotEmpty()) { + $middlewares = $middlewares->join(','); + $labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}"); + } + } else { + $middlewares = collect([]); + if ($is_gzip_enabled) { + $middlewares->push('gzip'); + } + if ($basic_auth && $basic_auth_middleware) { + $middlewares->push($basic_auth_middleware); + } + if ($redirect && $redirect_middleware) { + $middlewares->push($redirect_middleware); + } + if ($middlewares->isNotEmpty()) { + $middlewares = $middlewares->join(','); + $labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}"); } - $labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}"); } } } catch (\Throwable $e) { diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index d981ca436..cec7e82aa 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -228,56 +228,6 @@ function refresh_server_connection(?PrivateKey $private_key = null) } } -// function validateServer(Server $server, bool $throwError = false) -// { -// try { -// $uptime = instant_remote_process(['uptime'], $server, $throwError); -// if (!$uptime) { -// $server->settings->is_reachable = false; -// $server->team->notify(new Unreachable($server)); -// $server->unreachable_notification_sent = true; -// $server->save(); -// return [ -// "uptime" => null, -// "dockerVersion" => null, -// ]; -// } -// $server->settings->is_reachable = true; -// instant_remote_process(["docker ps"], $server, $throwError); -// $dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $server, $throwError); -// if (!$dockerVersion) { -// $dockerVersion = null; -// return [ -// "uptime" => $uptime, -// "dockerVersion" => null, -// ]; -// } -// $dockerVersion = checkMinimumDockerEngineVersion($dockerVersion); -// if (is_null($dockerVersion)) { -// $server->settings->is_usable = false; -// } else { -// $server->settings->is_usable = true; -// if (data_get($server, 'unreachable_notification_sent') === true) { -// $server->team->notify(new Revived($server)); -// $server->unreachable_notification_sent = false; -// $server->save(); -// } -// } -// return [ -// "uptime" => $uptime, -// "dockerVersion" => $dockerVersion, -// ]; -// } catch (\Throwable $e) { -// $server->settings->is_reachable = false; -// $server->settings->is_usable = false; -// throw $e; -// } finally { -// if (data_get($server, 'settings')) { -// $server->settings->save(); -// } -// } -// } - function checkRequiredCommands(Server $server) { $commands = collect(["jq", "jc"]); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index bc33388eb..f7939c9c3 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -1039,7 +1039,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal $serviceLabels = $serviceLabels->merge($defaultLabels); if (!$isDatabase && $fqdns->count() > 0) { if ($fqdns) { - $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($resource->uuid, $fqdns, true, serviceLabels: $serviceLabels)); + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($resource->uuid, $fqdns, true, serviceLabels: $serviceLabels, is_gzip_enabled: $savedService->isGzipEnabled())); } } if ($resource->server->isLogDrainEnabled() && $savedService->isLogDrainEnabled()) { diff --git a/config/sentry.php b/config/sentry.php index 355c5d8f1..80b7ffe7f 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.218', + 'release' => '4.0.0-beta.219', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 720085e96..81f48a3c5 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ boolean('is_gzip_enabled')->default(true); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('service_applications', function (Blueprint $table) { + $table->dropColumn('is_gzip_enabled'); + }); + } +}; diff --git a/resources/views/livewire/boarding/index.blade.php b/resources/views/livewire/boarding/index.blade.php index 88ca49bb9..2777eb3ac 100644 --- a/resources/views/livewire/boarding/index.blade.php +++ b/resources/views/livewire/boarding/index.blade.php @@ -241,7 +241,7 @@ - Validating & Configuring + Validate & configure diff --git a/resources/views/livewire/project/service/service-application-view.blade.php b/resources/views/livewire/project/service/service-application-view.blade.php index 57ad0403a..a69653385 100644 --- a/resources/views/livewire/project/service/service-application-view.blade.php +++ b/resources/views/livewire/project/service/service-application-view.blade.php @@ -32,7 +32,9 @@

Advanced

-
+
+ diff --git a/resources/views/livewire/project/service/stack-form.blade.php b/resources/views/livewire/project/service/stack-form.blade.php index 440d80f1b..b9593087b 100644 --- a/resources/views/livewire/project/service/stack-form.blade.php +++ b/resources/views/livewire/project/service/stack-form.blade.php @@ -15,7 +15,8 @@
- +
@if ($fields)
diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 209f951ef..708a2dcd8 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -2,7 +2,7 @@

General

- @if ($server->id === 0) + @if ($server->id !== 0) You could lost a lot of functionalities if you change the server details of the server where Coolify is @@ -10,16 +10,25 @@ @else Save + + Validate & configure + + + + + Revalidate server + + @endif
- @if (!$server->isFunctional()) - You can't use this server until it is validated. - @else + @if ($server->isFunctional()) Server is reachable and validated. + @else + You can't use this server until it is validated. @endif @if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0) - Validating & Configuring + Validate & configure diff --git a/resources/views/livewire/server/validate-and-install.blade.php b/resources/views/livewire/server/validate-and-install.blade.php index b243487df..35d5ab06a 100644 --- a/resources/views/livewire/server/validate-and-install.blade.php +++ b/resources/views/livewire/server/validate-and-install.blade.php @@ -1,29 +1,12 @@
- @if ($uptime) -
Server is reachable: - - - - -
+ @if ($ask) + This will revalidate the server, install / update Docker Engine, Docker Compose and all related + configuration. It will also restart Docker Engine, so your running containers will be unreachable + for the time being. + Continue @else - @if ($error) -
Server is reachable: - -
- @else -
- @endif - @endif - @if ($uptime) - @if ($supported_os_type) -
Supported OS type: Server is reachable:
@else -
+
@endif @endif - @endif - @if ($uptime && $supported_os_type) - @if ($docker_installed) -
Docker is installed: - - - - -
- @else - @if ($error) -
Docker is installed: - -
- @else -
- @endif - @endif - @if ($docker_compose_installed) -
Docker Compose is installed: - - - - -
- @if ($proxy_started) -
Proxy Started: Supported OS type:
@else @if ($error) -
Proxy Started: +
Server is reachable:
@else -
+
@endif @endif - @else - @if ($error) -
Docker Compose is installed: Docker is installed: - + + + +
@else -
+ @if ($error) +
Docker is installed: + +
+ @else +
+ @endif @endif + @if ($docker_compose_installed) +
Docker Compose is installed: + + + + +
+ @if ($proxy_started) +
Proxy Started: + + + + +
+ @else + @if ($error) +
Proxy Started: + +
+ @else +
+ @endif + @endif + @else + @if ($error) +
Docker Compose is installed: + +
+ @else +
+ @endif + @endif + @endif + @isset($docker_version) +
Minimum Docker version installed: + + + + +
+ @endisset + + @isset($error) +
{!! $error !!}
+ @endisset @endif - @isset($docker_version) -
Minimum Docker version installed: - - - - -
- @endisset - - - @isset($error) -
{!! $error !!}
- @endisset
diff --git a/templates/compose/docker-registry.yaml b/templates/compose/docker-registry.yaml new file mode 100644 index 000000000..6874b2358 --- /dev/null +++ b/templates/compose/docker-registry.yaml @@ -0,0 +1,48 @@ +# documentation: https://docs.docker.com/registry/ +# slogan: The Docker Registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images. +# tags: registry,images,docker + +services: + registry: + image: registry:2 + environment: + - SERVICE_FQDN_REGISTRY + - REGISTRY_AUTH=htpasswd + - REGISTRY_AUTH_HTPASSWD_REALM=Registry + - REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password + - REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data + volumes: + - type: bind + source: ./auth/registry.password + target: /auth/registry.password + isDirectory: false + content: >- + testuser:$2y$05$/o2JvmI2bhExXIt6Oqxa7ekYB7v3scj1wFEf6tBslJvJOMoPQL.Gy + - type: bind + source: ./config/config.yml + target: /etc/docker/registry/config.yml + isDirectory: false + content: >- + version: 0.1 + + log: + fields: + service: registry + storage: + cache: + blobdescriptor: inmemory + filesystem: + rootdirectory: /var/lib/registry + http: + addr: :5000 + headers: + X-Content-Type-Options: [nosniff] + health: + storagedriver: + enabled: true + interval: 10s + threshold: 3 + - type: bind + source: ./data + target: /data + isDirectory: true diff --git a/templates/service-templates.json b/templates/service-templates.json index 3aae101b5..7c28b9956 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -87,6 +87,16 @@ "sql" ] }, + "docker-registry": { + "documentation": "https:\/\/docs.docker.com\/registry\/", + "slogan": "The Docker Registry is a stateless, highly scalable server side application that stores and lets you distribute Docker images.", + "compose": "c2VydmljZXM6CiAgcmVnaXN0cnk6CiAgICBpbWFnZTogJ3JlZ2lzdHJ5OjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUkVHSVNUUlkKICAgICAgLSBSRUdJU1RSWV9BVVRIPWh0cGFzc3dkCiAgICAgIC0gUkVHSVNUUllfQVVUSF9IVFBBU1NXRF9SRUFMTT1SZWdpc3RyeQogICAgICAtIFJFR0lTVFJZX0FVVEhfSFRQQVNTV0RfUEFUSD0vYXV0aC9yZWdpc3RyeS5wYXNzd29yZAogICAgICAtIFJFR0lTVFJZX1NUT1JBR0VfRklMRVNZU1RFTV9ST09URElSRUNUT1JZPS9kYXRhCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9hdXRoL3JlZ2lzdHJ5LnBhc3N3b3JkCiAgICAgICAgdGFyZ2V0OiAvYXV0aC9yZWdpc3RyeS5wYXNzd29yZAogICAgICAgIGlzRGlyZWN0b3J5OiBmYWxzZQogICAgICAgIGNvbnRlbnQ6ICd0ZXN0dXNlcjokMnkkMDUkL28ySnZtSTJiaEV4WEl0Nk9xeGE3ZWtZQjd2M3NjajF3RkVmNnRCc2xKdkpPTW9QUUwuR3knCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2NvbmZpZy9jb25maWcueW1sCiAgICAgICAgdGFyZ2V0OiAvZXRjL2RvY2tlci9yZWdpc3RyeS9jb25maWcueW1sCiAgICAgICAgaXNEaXJlY3Rvcnk6IGZhbHNlCiAgICAgICAgY29udGVudDogInZlcnNpb246IDAuMVxubG9nOlxuICBmaWVsZHM6XG4gICAgc2VydmljZTogcmVnaXN0cnlcbnN0b3JhZ2U6XG4gIGNhY2hlOlxuICAgIGJsb2JkZXNjcmlwdG9yOiBpbm1lbW9yeVxuICBmaWxlc3lzdGVtOlxuICAgIHJvb3RkaXJlY3Rvcnk6IC92YXIvbGliL3JlZ2lzdHJ5XG5odHRwOlxuICBhZGRyOiA6NTAwMFxuICBoZWFkZXJzOlxuICAgIFgtQ29udGVudC1UeXBlLU9wdGlvbnM6IFtub3NuaWZmXVxuaGVhbHRoOlxuICBzdG9yYWdlZHJpdmVyOlxuICAgIGVuYWJsZWQ6IHRydWVcbiAgICBpbnRlcnZhbDogMTBzXG4gICAgdGhyZXNob2xkOiAzIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9kYXRhCiAgICAgICAgdGFyZ2V0OiAvZGF0YQogICAgICAgIGlzRGlyZWN0b3J5OiB0cnVlCg==", + "tags": [ + "registry", + "images", + "docker" + ] + }, "dokuwiki": { "documentation": "https:\/\/www.dokuwiki.org\/faq", "slogan": "A lightweight and easy-to-use wiki platform for creating and managing documentation and knowledge bases with simplicity and flexibility.", diff --git a/versions.json b/versions.json index 562416b31..da42b0e85 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.218" + "version": "4.0.0-beta.219" } } }