2
.github/workflows/coolify-helper-next.yml
vendored
2
.github/workflows/coolify-helper-next.yml
vendored
@@ -4,7 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [ "next" ]
|
branches: [ "next" ]
|
||||||
paths:
|
paths:
|
||||||
- .github/workflows/coolify-helper.yml
|
- .github/workflows/coolify-helper-next.yml
|
||||||
- docker/coolify-helper/Dockerfile
|
- docker/coolify-helper/Dockerfile
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class SyncBunny extends Command
|
|||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'sync:bunny {--only-template}';
|
protected $signature = 'sync:bunny {--only-template} {--only-version}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
@@ -30,7 +30,9 @@ class SyncBunny extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
$that = $this;
|
||||||
$only_template = $this->option('only-template');
|
$only_template = $this->option('only-template');
|
||||||
|
$only_version = $this->option('only-version');
|
||||||
$bunny_cdn = "https://cdn.coollabs.io";
|
$bunny_cdn = "https://cdn.coollabs.io";
|
||||||
$bunny_cdn_path = "coolify";
|
$bunny_cdn_path = "coolify";
|
||||||
$bunny_cdn_storage_name = "coolcdn";
|
$bunny_cdn_storage_name = "coolcdn";
|
||||||
@@ -46,7 +48,7 @@ class SyncBunny extends Command
|
|||||||
|
|
||||||
$versions = "versions.json";
|
$versions = "versions.json";
|
||||||
|
|
||||||
PendingRequest::macro('storage', function ($file) {
|
PendingRequest::macro('storage', function ($file) use($that) {
|
||||||
$headers = [
|
$headers = [
|
||||||
'AccessKey' => env('BUNNY_STORAGE_API_KEY'),
|
'AccessKey' => env('BUNNY_STORAGE_API_KEY'),
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
@@ -54,21 +56,22 @@ class SyncBunny extends Command
|
|||||||
];
|
];
|
||||||
$fileStream = fopen($file, "r");
|
$fileStream = fopen($file, "r");
|
||||||
$file = fread($fileStream, filesize($file));
|
$file = fread($fileStream, filesize($file));
|
||||||
|
$that->info('Uploading: ' . $file);
|
||||||
return PendingRequest::baseUrl('https://storage.bunnycdn.com')->withHeaders($headers)->withBody($file)->throw();
|
return PendingRequest::baseUrl('https://storage.bunnycdn.com')->withHeaders($headers)->withBody($file)->throw();
|
||||||
});
|
});
|
||||||
PendingRequest::macro('purge', function ($url) {
|
PendingRequest::macro('purge', function ($url) use ($that) {
|
||||||
$headers = [
|
$headers = [
|
||||||
'AccessKey' => env('BUNNY_API_KEY'),
|
'AccessKey' => env('BUNNY_API_KEY'),
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
];
|
];
|
||||||
ray('Purging: ' . $url);
|
$that->info('Purging: ' . $url);
|
||||||
return PendingRequest::withHeaders($headers)->get('https://api.bunny.net/purge', [
|
return PendingRequest::withHeaders($headers)->get('https://api.bunny.net/purge', [
|
||||||
"url" => $url,
|
"url" => $url,
|
||||||
"async" => false
|
"async" => false
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
$confirmed = confirm('Are you sure?');
|
$confirmed = confirm('Are you sure you want to sync?');
|
||||||
if (!$confirmed) {
|
if (!$confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -80,23 +83,28 @@ class SyncBunny extends Command
|
|||||||
$this->info('Service template uploaded & purged...');
|
$this->info('Service template uploaded & purged...');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ($only_version) {
|
||||||
|
Http::pool(fn (Pool $pool) => [
|
||||||
|
$pool->storage(fileName: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$versions"),
|
||||||
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$versions"),
|
||||||
|
]);
|
||||||
|
$this->info('versions.json uploaded & purged...');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Http::pool(fn (Pool $pool) => [
|
Http::pool(fn (Pool $pool) => [
|
||||||
$pool->storage(file: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"),
|
$pool->storage(fileName: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"),
|
||||||
$pool->storage(file: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"),
|
$pool->storage(fileName: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"),
|
||||||
$pool->storage(file: "$parent_dir/$production_env")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$production_env"),
|
$pool->storage(fileName: "$parent_dir/$production_env")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$production_env"),
|
||||||
$pool->storage(file: "$parent_dir/scripts/$upgrade_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$upgrade_script"),
|
$pool->storage(fileName: "$parent_dir/scripts/$upgrade_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$upgrade_script"),
|
||||||
$pool->storage(file: "$parent_dir/scripts/$install_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$install_script"),
|
$pool->storage(fileName: "$parent_dir/scripts/$install_script")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$install_script"),
|
||||||
$pool->storage(file: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$versions"),
|
|
||||||
]);
|
]);
|
||||||
$this->info("{$bunny_cdn}/{$bunny_cdn_path}");
|
|
||||||
Http::pool(fn (Pool $pool) => [
|
Http::pool(fn (Pool $pool) => [
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file_prod"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$compose_file_prod"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$production_env"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$production_env"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$upgrade_script"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$upgrade_script"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$install_script"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$install_script"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$versions"),
|
|
||||||
]);
|
]);
|
||||||
$this->info("All files uploaded & purged...");
|
$this->info("All files uploaded & purged...");
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ class ProjectController extends Controller
|
|||||||
|
|
||||||
public function new()
|
public function new()
|
||||||
{
|
{
|
||||||
$services = Cache::get('services', []);
|
$services = getServiceTemplates();
|
||||||
$type = Str::of(request()->query('type'));
|
$type = Str::of(request()->query('type'));
|
||||||
$destination_uuid = request()->query('destination');
|
$destination_uuid = request()->query('destination');
|
||||||
$server_id = request()->query('server');
|
$server_id = request()->query('server_id');
|
||||||
|
|
||||||
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
$project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
|
||||||
if (!$project) {
|
if (!$project) {
|
||||||
@@ -66,9 +66,10 @@ class ProjectController extends Controller
|
|||||||
'database_uuid' => $standalone_postgresql->uuid,
|
'database_uuid' => $standalone_postgresql->uuid,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
if ($type->startsWith('one-click-service-')) {
|
if ($type->startsWith('one-click-service-') && !is_null( (int)$server_id)) {
|
||||||
$oneClickServiceName = $type->after('one-click-service-')->value();
|
$oneClickServiceName = $type->after('one-click-service-')->value();
|
||||||
$oneClickService = data_get($services, "$oneClickServiceName.compose");
|
$oneClickService = data_get($services, "$oneClickServiceName.compose");
|
||||||
|
ray($oneClickServiceName);
|
||||||
$oneClickDotEnvs = data_get($services, "$oneClickServiceName.envs", null);
|
$oneClickDotEnvs = data_get($services, "$oneClickServiceName.envs", null);
|
||||||
if ($oneClickDotEnvs) {
|
if ($oneClickDotEnvs) {
|
||||||
$oneClickDotEnvs = Str::of(base64_decode($oneClickDotEnvs))->split('/\r\n|\r|\n/');
|
$oneClickDotEnvs = Str::of(base64_decode($oneClickDotEnvs))->split('/\r\n|\r|\n/');
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
public function selectExistingPrivateKey()
|
public function selectExistingPrivateKey()
|
||||||
{
|
{
|
||||||
$this->createdPrivateKey = PrivateKey::find($this->selectedExistingPrivateKey);
|
$this->createdPrivateKey = PrivateKey::find($this->selectedExistingPrivateKey);
|
||||||
|
$this->privateKey = $this->createdPrivateKey->private_key;
|
||||||
$this->currentState = 'create-server';
|
$this->currentState = 'create-server';
|
||||||
}
|
}
|
||||||
public function createNewServer()
|
public function createNewServer()
|
||||||
|
|||||||
@@ -60,28 +60,9 @@ class Select extends Component
|
|||||||
if ($forceReload) {
|
if ($forceReload) {
|
||||||
Cache::forget('services');
|
Cache::forget('services');
|
||||||
}
|
}
|
||||||
if (isDev()) {
|
$this->services = getServiceTemplates();
|
||||||
$cached = Cache::remember('services', 3600, function () {
|
$this->emit('success', 'Successfully loaded services.');
|
||||||
$services = File::get(base_path('templates/service-templates.json'));
|
|
||||||
$services = collect(json_decode($services))->sortKeys();
|
|
||||||
$this->emit('success', 'Successfully reloaded services from filesystem (development mode).');
|
|
||||||
return $services;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$cached = Cache::remember('services', 3600, function () {
|
|
||||||
$services = Http::get(config('constants.services.official'));
|
|
||||||
if ($services->failed()) {
|
|
||||||
throw new \Exception($services->body());
|
|
||||||
}
|
|
||||||
|
|
||||||
$services = collect($services->json())->sortKeys();
|
|
||||||
$this->emit('success', 'Successfully reloaded services from the internet.');
|
|
||||||
return $services;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$this->services = $cached;
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
ray($e);
|
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
} finally {
|
} finally {
|
||||||
$this->loadingServices = false;
|
$this->loadingServices = false;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ use Livewire\Component;
|
|||||||
class Show extends Component
|
class Show extends Component
|
||||||
{
|
{
|
||||||
public Service $service;
|
public Service $service;
|
||||||
public ServiceApplication $serviceApplication;
|
public ?ServiceApplication $serviceApplication = null;
|
||||||
public ServiceDatabase $serviceDatabase;
|
public ?ServiceDatabase $serviceDatabase = null;
|
||||||
public array $parameters;
|
public array $parameters;
|
||||||
public array $query;
|
public array $query;
|
||||||
public Collection $services;
|
public Collection $services;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ class ShowPrivateKey extends Component
|
|||||||
public function setPrivateKey($newPrivateKeyId)
|
public function setPrivateKey($newPrivateKeyId)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
refresh_server_connection($this->server->privateKey);
|
|
||||||
$oldPrivateKeyId = $this->server->private_key_id;
|
$oldPrivateKeyId = $this->server->private_key_id;
|
||||||
|
refresh_server_connection($this->server->privateKey);
|
||||||
$this->server->update([
|
$this->server->update([
|
||||||
'private_key_id' => $newPrivateKeyId
|
'private_key_id' => $newPrivateKeyId
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class Configuration extends Component
|
|||||||
{
|
{
|
||||||
$file = "$this->dynamic_config_path/coolify.yaml";
|
$file = "$this->dynamic_config_path/coolify.yaml";
|
||||||
if (empty($this->settings->fqdn)) {
|
if (empty($this->settings->fqdn)) {
|
||||||
remote_process([
|
instant_remote_process([
|
||||||
"rm -f $file",
|
"rm -f $file",
|
||||||
], $this->server);
|
], $this->server);
|
||||||
} else {
|
} else {
|
||||||
@@ -129,7 +129,6 @@ class Configuration extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
$this->save_configuration_to_disk($traefik_dynamic_conf, $file);
|
$this->save_configuration_to_disk($traefik_dynamic_conf, $file);
|
||||||
dispatch(new ContainerStatusJob($this->server));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +141,7 @@ class Configuration extends Component
|
|||||||
$yaml;
|
$yaml;
|
||||||
|
|
||||||
$base64 = base64_encode($yaml);
|
$base64 = base64_encode($yaml);
|
||||||
remote_process([
|
instant_remote_process([
|
||||||
"mkdir -p $this->dynamic_config_path",
|
"mkdir -p $this->dynamic_config_path",
|
||||||
"echo '$base64' | base64 -d > $file",
|
"echo '$base64' | base64 -d > $file",
|
||||||
], $this->server);
|
], $this->server);
|
||||||
|
|||||||
@@ -212,13 +212,9 @@ class Application extends BaseModel
|
|||||||
{
|
{
|
||||||
if (data_get($this, 'private_key_id')) {
|
if (data_get($this, 'private_key_id')) {
|
||||||
return 'deploy_key';
|
return 'deploy_key';
|
||||||
}
|
} else if (data_get($this, 'source')) {
|
||||||
if (data_get($this, 'source')) {
|
|
||||||
return 'source';
|
return 'source';
|
||||||
}
|
}
|
||||||
if (data_get($this, 'private_key_id')) {
|
|
||||||
return 'deploy_key';
|
|
||||||
}
|
|
||||||
throw new \Exception('No deployment type found');
|
throw new \Exception('No deployment type found');
|
||||||
}
|
}
|
||||||
public function could_set_build_commands(): bool
|
public function could_set_build_commands(): bool
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class Environment extends Model
|
|||||||
|
|
||||||
public function can_delete_environment()
|
public function can_delete_environment()
|
||||||
{
|
{
|
||||||
return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0;
|
return $this->applications()->count() == 0 && $this->postgresqls()->count() == 0 && $this->services()->count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applications()
|
public function applications()
|
||||||
|
|||||||
@@ -406,3 +406,18 @@ function sslip(Server $server)
|
|||||||
}
|
}
|
||||||
return "{$server->ip}.sslip.io";
|
return "{$server->ip}.sslip.io";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getServiceTemplates()
|
||||||
|
{
|
||||||
|
if (isDev()) {
|
||||||
|
$services = File::get(base_path('templates/service-templates.json'));
|
||||||
|
$services = collect(json_decode($services))->sortKeys();
|
||||||
|
} else {
|
||||||
|
$services = Http::get(config('constants.services.official'));
|
||||||
|
if ($services->failed()) {
|
||||||
|
throw new \Exception($services->body());
|
||||||
|
}
|
||||||
|
$services = collect($services->json())->sortKeys();
|
||||||
|
}
|
||||||
|
return $services;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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.46',
|
'release' => '4.0.0-beta.47',
|
||||||
// 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.46';
|
return '4.0.0-beta.47';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
Save
|
Save
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
<div class="">General configuration for your Coolify instance.</div>
|
<div>General configuration for your Coolify instance.</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-2 pt-4">
|
<div class="flex flex-col gap-2 pt-4">
|
||||||
<div class="flex gap-2 w-96">
|
<div class="flex gap-2 w-96">
|
||||||
|
|||||||
@@ -72,14 +72,21 @@ cat >/etc/docker/daemon.json.coolify <<EOL
|
|||||||
EOL
|
EOL
|
||||||
cat <<<$(jq . /etc/docker/daemon.json.coolify) >/etc/docker/daemon.json.coolify
|
cat <<<$(jq . /etc/docker/daemon.json.coolify) >/etc/docker/daemon.json.coolify
|
||||||
cat <<<$(jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify) >/etc/docker/daemon.json
|
cat <<<$(jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify) >/etc/docker/daemon.json
|
||||||
DIFF=$(diff <(jq --sort-keys . /etc/docker/daemon.json) <(jq --sort-keys . /etc/docker/daemon.json.original-$DATE))
|
|
||||||
if [ "$DIFF" != "" ]; then
|
if [ -s /etc/docker/daemon.json.original-$DATE ]; then
|
||||||
|
DIFF=$(diff <(jq --sort-keys . /etc/docker/daemon.json) <(jq --sort-keys . /etc/docker/daemon.json.original-$DATE))
|
||||||
|
if [ "$DIFF" != "" ]; then
|
||||||
|
echo "Docker configuration updated, restart docker daemon..."
|
||||||
|
systemctl restart docker
|
||||||
|
else
|
||||||
|
echo "Docker configuration is up to date."
|
||||||
|
fi
|
||||||
|
else
|
||||||
echo "Docker configuration updated, restart docker daemon..."
|
echo "Docker configuration updated, restart docker daemon..."
|
||||||
systemctl restart docker
|
systemctl restart docker
|
||||||
else
|
|
||||||
echo "Docker configuration is up to date."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo -e "-------------"
|
echo -e "-------------"
|
||||||
|
|
||||||
mkdir -p /data/coolify/ssh/keys
|
mkdir -p /data/coolify/ssh/keys
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.46"
|
"version": "4.0.0-beta.47"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user