Compare commits

...

31 Commits

Author SHA1 Message Date
Andras Bacsai
144b34ca2e Merge pull request #2025 from coollabsio/next
v4.0.0-beta.265
2024-04-18 13:54:23 +02:00
Andras Bacsai
676c022e41 fix: .env saved to deployment server, not to build server 2024-04-18 13:53:10 +02:00
Andras Bacsai
7c0b98bb70 Fix sorting issue in save_environment_variables() function 2024-04-18 12:37:06 +02:00
Andras Bacsai
7779713392 Fix issue with user validation in Server.php 2024-04-18 11:48:10 +02:00
Andras Bacsai
5e1396025c Fix issue with saving environment variables in ApplicationDeploymentJob.php 2024-04-18 11:41:58 +02:00
Andras Bacsai
d09c88f71c Fix formatting issue in deployment show.blade.php 2024-04-18 11:14:26 +02:00
Andras Bacsai
7980f21b1b Update version numbers to 4.0.0-beta.265 2024-04-18 11:14:23 +02:00
Andras Bacsai
3843994a05 Merge pull request #2022 from coollabsio/next
v4.0.0-beta.264
2024-04-18 06:58:01 +02:00
Andras Bacsai
a1b08ca037 revert .env changes 2024-04-18 06:55:47 +02:00
Andras Bacsai
144cdd11ec Update version numbers to 4.0.0-beta.264 2024-04-18 06:55:40 +02:00
Andras Bacsai
b6531cdb10 Merge pull request #2016 from coollabsio/next
v4.0.0-beta.262
2024-04-17 18:50:54 +02:00
Andras Bacsai
0eef4a5fa1 Fix DNS validation issue and check domain usage 2024-04-17 18:49:31 +02:00
Andras Bacsai
42baaf8f2d Update version numbers to 4.0.0-beta.263 2024-04-17 18:49:25 +02:00
Andras Bacsai
08d9dff8eb Merge pull request #2014 from coollabsio/next
v4.0.0-beta.262
2024-04-17 16:47:14 +02:00
Andras Bacsai
01b3aab9bc fix: $ in labels escaped 2024-04-17 16:46:12 +02:00
Andras Bacsai
fde34ef178 version++ 2024-04-17 16:46:00 +02:00
Andras Bacsai
5195abec94 Update slogans in appsmith.yaml, appwrite.yaml, babybuddy.yaml, and budge.yaml 2024-04-17 15:48:14 +02:00
Andras Bacsai
aa79acd09e Merge pull request #2012 from coollabsio/next
v4.0.0-beta.261
2024-04-17 15:34:44 +02:00
Andras Bacsai
67011ccd72 fix: base64 encode .env 2024-04-17 15:34:31 +02:00
Andras Bacsai
e2cd7fe17e fix: rollback feature 2024-04-17 15:30:08 +02:00
Andras Bacsai
4c0624f489 fix: remove lazy loading until bug figured out 2024-04-17 15:16:08 +02:00
Andras Bacsai
8c033250b1 Update version numbers to 4.0.0-beta.261 2024-04-17 14:27:53 +02:00
Andras Bacsai
05b5a6fddf Update healthcheck URLs to use 127.0.0.1 instead of localhost 2024-04-17 14:27:51 +02:00
Andras Bacsai
df5bde7b8e Merge pull request #2008 from coollabsio/next
v4.0.0-beta.260
2024-04-17 12:52:09 +02:00
Andras Bacsai
ca5f52c48c Add Tolgee service to compose file and service templates 2024-04-17 12:48:11 +02:00
Andras Bacsai
3656adf059 Add Tolgee authentication fields to Service.php 2024-04-17 12:48:04 +02:00
Andras Bacsai
4381792b05 Refactor variable name display in stack-form.blade.php 2024-04-17 12:48:01 +02:00
Andras Bacsai
0a3c20b08a Fix issue with sorting environment variables in StackForm.php 2024-04-17 12:47:57 +02:00
Andras Bacsai
4ab3f41665 Remove debug statement in remoteProcess.php 2024-04-17 12:47:45 +02:00
Andras Bacsai
10356a4376 Fix issue with sorting environment variables in ApplicationDeploymentJob.php 2024-04-17 12:13:44 +02:00
Andras Bacsai
98c2056f53 Fix issue with saving environment variables and update version numbers 2024-04-17 12:08:35 +02:00
26 changed files with 253 additions and 98 deletions

View File

@@ -56,7 +56,7 @@ class Handler extends ExceptionHandler
{
$this->reportable(function (Throwable $e) {
if (isDev()) {
// return;
return;
}
if ($e instanceof RuntimeException) {
return;

View File

@@ -24,6 +24,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Sleep;
use Illuminate\Support\Str;
use RuntimeException;
@@ -49,6 +50,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private string $deployment_uuid;
private int $pull_request_id;
private string $commit;
private bool $rollback;
private bool $force_rebuild;
private bool $restart_only;
@@ -117,6 +119,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->deployment_uuid = $this->application_deployment_queue->deployment_uuid;
$this->pull_request_id = $this->application_deployment_queue->pull_request_id;
$this->commit = $this->application_deployment_queue->commit;
$this->rollback = $this->application_deployment_queue->rollback;
$this->force_rebuild = $this->application_deployment_queue->force_rebuild;
$this->restart_only = $this->application_deployment_queue->restart_only;
$this->only_this_server = $this->application_deployment_queue->only_this_server;
@@ -738,8 +741,12 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$envs->push("SOURCE_COMMIT=unknown");
}
}
$envs = $envs->sort(function ($a, $b) {
return strpos($a, '$') === false ? -1 : 1;
});
Log::info("message", $envs->implode("\n"));
} else {
$this->env_filename = ".env-coolify";
$this->env_filename = ".env";
foreach ($this->application->environment_variables as $env) {
$real_value = $env->real_value;
if ($env->version === '4.0.0-beta.239') {
@@ -767,9 +774,16 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$envs->push("SOURCE_COMMIT=unknown");
}
}
$envs = $envs->sort(function ($a, $b) {
return strpos($a, '$') === false ? -1 : 1;
});
}
if ($envs->isEmpty()) {
$this->env_filename = null;
if ($this->use_build_server) {
$this->server = $this->original_server;
}
$this->execute_remote_command(
[
"command" => "rm -f $this->configuration_dir/{$this->env_filename}",
@@ -777,30 +791,51 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
"ignore_errors" => true
]
);
$this->env_filename = null;
return;
}
$this->execute_remote_command([
executeInDocker($this->deployment_uuid, "cat $this->workdir/.env 2>/dev/null || true"),
"hidden" => true,
"save" => "dotenv"
]);
if (str($this->saved_outputs->get('dotenv'))->isNotEmpty()) {
if ($this->use_build_server) {
$this->server = $this->build_server;
}
} else {
$envs_base64 = base64_encode($envs->implode("\n"));
$this->execute_remote_command(
[
"echo '{$this->saved_outputs->get('dotenv')->value()}' | tee $this->configuration_dir/.env > /dev/null"
executeInDocker($this->deployment_uuid, "echo '$envs_base64' | base64 -d | tee $this->workdir/{$this->env_filename} > /dev/null")
],
);
if ($this->use_build_server) {
$this->server = $this->original_server;
}
$this->execute_remote_command(
[
"echo '$envs_base64' | base64 -d | tee $this->configuration_dir/{$this->env_filename} > /dev/null"
]
);
if ($this->use_build_server) {
$this->server = $this->build_server;
}
}
$envs_base64 = base64_encode($envs->implode("\n"));
$this->execute_remote_command(
[
executeInDocker($this->deployment_uuid, "echo '$envs_base64' | base64 -d | tee $this->workdir/{$this->env_filename} > /dev/null")
],
[
"echo '$envs_base64' | base64 -d | tee $this->configuration_dir/{$this->env_filename} > /dev/null"
]
);
// $this->execute_remote_command([
// executeInDocker($this->deployment_uuid, "cat $this->workdir/.env 2>/dev/null || true"),
// "hidden" => true,
// "save" => "dotenv"
// ]);
// if (str($this->saved_outputs->get('dotenv'))->isNotEmpty()) {
// $base64_dotenv = base64_encode($this->saved_outputs->get('dotenv')->value());
// $this->execute_remote_command(
// [
// "echo '{$base64_dotenv}' | base64 -d | tee $this->configuration_dir/.env > /dev/null"
// ]
// );
// } else {
// $this->execute_remote_command(
// [
// "command" => "rm -f $this->configuration_dir/.env",
// "hidden" => true,
// "ignore_errors" => true
// ]
// );
// }
}
@@ -1059,7 +1094,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
],
);
}
if ($this->saved_outputs->get('git_commit_sha')) {
if ($this->saved_outputs->get('git_commit_sha') && !$this->rollback) {
$this->commit = $this->saved_outputs->get('git_commit_sha')->before("\t");
}
}
@@ -1225,8 +1260,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->pull_request_id !== 0) {
$labels = collect(generateLabelsApplication($this->application, $this->preview));
}
$labels = $labels->map(function ($value, $key) {
return escapeDollarSign($value);
});
$labels = $labels->merge(defaultLabels($this->application->id, $this->application->uuid, $this->pull_request_id))->toArray();
// Check for custom HEALTHCHECK
$this->custom_healthcheck_found = false;
if ($this->application->build_pack === 'dockerfile' || $this->application->dockerfile) {
@@ -1265,21 +1302,23 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
]
]
];
if (str($this->saved_outputs->get('dotenv'))->isNotEmpty()) {
if (data_get($docker_compose, "services.{$this->container_name}.env_file")) {
$docker_compose['services'][$this->container_name]['env_file'][] = '.env';
} else {
$docker_compose['services'][$this->container_name]['env_file'] = ['.env'];
}
// if (str($this->saved_outputs->get('dotenv'))->isNotEmpty()) {
// if (data_get($docker_compose, "services.{$this->container_name}.env_file")) {
// $docker_compose['services'][$this->container_name]['env_file'][] = '.env';
// } else {
// $docker_compose['services'][$this->container_name]['env_file'] = ['.env'];
// }
// }
// if ($this->env_filename) {
// if (data_get($docker_compose, "services.{$this->container_name}.env_file")) {
// $docker_compose['services'][$this->container_name]['env_file'][] = $this->env_filename;
// } else {
// $docker_compose['services'][$this->container_name]['env_file'] = [$this->env_filename];
// }
// }
if (!is_null($this->env_filename)) {
$docker_compose['services'][$this->container_name]['env_file'] = [$this->env_filename];
}
if ($this->env_filename) {
if (data_get($docker_compose, "services.{$this->container_name}.env_file")) {
$docker_compose['services'][$this->container_name]['env_file'][] = $this->env_filename;
} else {
$docker_compose['services'][$this->container_name]['env_file'] = [$this->env_filename];
}
}
if (!$this->custom_healthcheck_found) {
$docker_compose['services'][$this->container_name]['healthcheck'] = [
'test' => [

View File

@@ -18,7 +18,6 @@ class Rollback extends Component
{
$this->parameters = get_route_parameters();
}
public function rollbackImage($commit)
{
$deployment_uuid = new Cuid2(7);
@@ -27,6 +26,7 @@ class Rollback extends Component
application: $this->application,
deployment_uuid: $deployment_uuid,
commit: $commit,
rollback: true,
force_rebuild: false,
);
return redirect()->route('project.application.deployment.show', [

View File

@@ -42,7 +42,7 @@ class StackForm extends Component
$this->validationAttributes["fields.$key.value"] = $fieldKey;
}
}
$this->fields = $this->fields->sort();
$this->fields = $this->fields->sortDesc();
}
public function saveCompose($raw)
{

View File

@@ -69,13 +69,14 @@ class Configuration extends Component
}
$this->validate();
if ($this->settings->is_dns_validation_enabled) {
if ($this->settings->is_dns_validation_enabled && $this->settings->fqdn) {
ray('asdf');
if (!validate_dns_entry($this->settings->fqdn, $this->server)) {
$this->dispatch('error', "Validating DNS ({$this->settings->fqdn}) failed.<br><br>Make sure you have added the DNS records correctly.<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> for further help.");
$error_show = true;
}
}
check_domain_usage(domain: $this->settings->fqdn);
if ($this->settings->fqdn) check_domain_usage(domain: $this->settings->fqdn);
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->replaceEnd(',', '')->trim();
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->trim()->explode(',')->map(function ($dns) {
return str($dns)->trim()->lower();

View File

@@ -860,6 +860,9 @@ $schema://$host {
}
public function isNonRoot()
{
if ($this->user instanceof Stringable) {
return $this->user->value() !== 'root';
}
return $this->user !== 'root';
}
}

View File

@@ -150,6 +150,29 @@ class Service extends BaseModel
foreach ($applications as $application) {
$image = str($application->image)->before(':')->value();
switch ($image) {
case str($image)?->contains('tolgee'):
$data = collect([]);
$admin_password = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_TOLGEE')->first();
$data = $data->merge([
'Admin User' => [
'key' => 'TOLGEE_AUTHENTICATION_INITIAL_USERNAME',
'value' => 'admin',
'readonly' => true,
'rules' => 'required',
],
]);
if ($admin_password) {
$data = $data->merge([
'Admin Password' => [
'key' => 'SERVICE_PASSWORD_TOLGEE',
'value' => data_get($admin_password, 'value'),
'rules' => 'required',
'isPassword' => true,
],
]);
}
$fields->put('Tolgee', $data);
break;
case str($image)?->contains('logto'):
$data = collect([]);
$logto_endpoint = $this->environment_variables()->where('key', 'LOGTO_ENDPOINT')->first();

View File

@@ -9,7 +9,7 @@ use App\Models\StandaloneDocker;
use Illuminate\Support\Collection;
use Spatie\Url\Url;
function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, Server $server = null, StandaloneDocker $destination = null, bool $only_this_server = false)
function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, Server $server = null, StandaloneDocker $destination = null, bool $only_this_server = false, bool $rollback = false)
{
$application_id = $application->id;
$deployment_link = Url::fromString($application->link() . "/deployment/{$deployment_uuid}");
@@ -38,6 +38,7 @@ function queue_application_deployment(Application $application, string $deployme
'is_webhook' => $is_webhook,
'restart_only' => $restart_only,
'commit' => $commit,
'rollback' => $rollback,
'git_type' => $git_type,
'only_this_server' => $only_this_server
]);

View File

@@ -35,7 +35,6 @@ function remote_process(
if ($server->isNonRoot()) {
$command = parseCommandsByLineForSudo(collect($command), $server);
}
ray($command);
$command_string = implode("\n", $command);
if (auth()->user()) {
$teams = auth()->user()->teams->pluck('id');

View File

@@ -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.259',
'release' => '4.0.0-beta.265',
// When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'),

View File

@@ -1,3 +1,3 @@
<?php
return '4.0.0-beta.259';
return '4.0.0-beta.265';

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('application_deployment_queues', function (Blueprint $table) {
$table->boolean('rollback')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('application_deployment_queues', function (Blueprint $table) {
$table->dropColumn('rollback');
});
}
};

View File

@@ -95,7 +95,7 @@ services:
expose:
- "${APP_PORT:-8000}"
healthcheck:
test: curl --fail http://localhost:80/api/health || exit 1
test: curl --fail http://127.0.0.1:80/api/health || exit 1
interval: 5s
retries: 10
timeout: 2s
@@ -142,7 +142,7 @@ services:
SOKETI_DEFAULT_APP_KEY: "${PUSHER_APP_KEY}"
SOKETI_DEFAULT_APP_SECRET: "${PUSHER_APP_SECRET}"
healthcheck:
test: wget -qO- http://localhost:6001/ready || exit 1
test: wget -qO- http://127.0.0.1:6001/ready || exit 1
interval: 5s
retries: 10
timeout: 2s

View File

@@ -83,48 +83,48 @@
<livewire:project.application.general :application="$application" />
</div>
<div x-cloak x-show="activeTab === 'swarm'" class="h-full">
<livewire:project.application.swarm :application="$application" lazy />
<livewire:project.application.swarm :application="$application" />
</div>
<div x-cloak x-show="activeTab === 'advanced'" class="h-full">
<livewire:project.application.advanced :application="$application" lazy />
<livewire:project.application.advanced :application="$application" />
</div>
<div x-cloak x-show="activeTab === 'environment-variables'">
<livewire:project.shared.environment-variable.all :resource="$application" lazy />
<livewire:project.shared.environment-variable.all :resource="$application" />
</div>
@if ($application->git_based())
<div x-cloak x-show="activeTab === 'source'">
<livewire:project.application.source :application="$application" lazy />
<livewire:project.application.source :application="$application" />
</div>
@endif
<div x-cloak x-show="activeTab === 'servers'">
<livewire:project.shared.destination :resource="$application" :servers="$servers" lazy />
<livewire:project.shared.destination :resource="$application" :servers="$servers" />
</div>
<div x-cloak x-show="activeTab === 'storages'">
<livewire:project.service.storage :resource="$application" lazy />
<livewire:project.service.storage :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'webhooks'">
<livewire:project.shared.webhooks :resource="$application" lazy />
<livewire:project.shared.webhooks :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'previews'">
<livewire:project.application.previews :application="$application" lazy />
<livewire:project.application.previews :application="$application" />
</div>
<div x-cloak x-show="activeTab === 'health'">
<livewire:project.shared.health-checks :resource="$application" lazy />
<livewire:project.shared.health-checks :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'rollback'">
<livewire:project.application.rollback :application="$application" lazy />
<livewire:project.application.rollback :application="$application" />
</div>
<div x-cloak x-show="activeTab === 'resource-limits'">
<livewire:project.shared.resource-limits :resource="$application" lazy />
<livewire:project.shared.resource-limits :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'scheduled-tasks'">
<livewire:project.shared.scheduled-task.all :resource="$application" lazy />
<livewire:project.shared.scheduled-task.all :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'resource-operations'">
<livewire:project.shared.resource-operations :resource="$application" lazy />
<livewire:project.shared.resource-operations :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'tags'">
<livewire:project.shared.tags :resource="$application" lazy />
<livewire:project.shared.tags :resource="$application" />
</div>
<div x-cloak x-show="activeTab === 'danger'">
<livewire:project.shared.danger :resource="$application" />

View File

@@ -87,7 +87,7 @@
@foreach (decode_remote_command_output($application_deployment_queue) as $line)
<span @class([
'dark:text-warning whitespace-pre-line' => $line['hidden'],
'text-red-500 font-bold' => $line['type'] == 'stderr',
'text-red-500 font-bold whitespace-pre-line' => $line['type'] == 'stderr',
])>[{{ $line['timestamp'] }}] @if ($line['hidden'])
<br><br>[COMMAND] {{ $line['command'] }}<br>[OUTPUT]
@endif @if (str($line['output'])->contains('http://') || str($line['output'])->contains('https://'))
@@ -100,7 +100,7 @@
@endphp {!! $line['output'] !!}
@else
{{ $line['output'] }}
@endif
</span>
@endforeach

View File

@@ -57,7 +57,7 @@
<div class="pb-4">Previews</div>
<div class="flex flex-wrap gap-6">
@foreach ($application->previews as $preview)
<div class="flex flex-col p-4 dark:bg-coolgray-200">
<div class="flex flex-col p-4 dark:bg-coolgray-100">
<div class="flex gap-2">PR #{{ data_get($preview, 'pull_request_id') }} |
@if (Str::of(data_get($preview, 'status'))->startsWith('running'))
<x-status.running :status="data_get($preview, 'status')" />
@@ -86,18 +86,20 @@
Redeploy
@endif
</x-forms.button>
<a
href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
<x-forms.button class="dark:bg-coolgray-500">
Deployment Logs
</x-forms.button>
</a>
<a
href="{{ route('project.application.logs', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
<x-forms.button class="dark:bg-coolgray-500">
Application Logs
</x-forms.button>
</a>
@if (count($parameters) > 0)
<a
href="{{ route('project.application.deployment.index', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
<x-forms.button class="dark:bg-coolgray-500">
Deployment Logs
</x-forms.button>
</a>
<a
href="{{ route('project.application.logs', [...$parameters, 'pull_request_id' => data_get($preview, 'pull_request_id')]) }}">
<x-forms.button class="dark:bg-coolgray-500">
Application Logs
</x-forms.button>
</a>
@endif
<x-forms.button isError class="dark:bg-coolgray-500"
wire:click="stop({{ data_get($preview, 'pull_request_id') }})">Delete
</x-forms.button>

View File

@@ -9,7 +9,7 @@
<div class="flex flex-wrap">
@forelse ($images as $image)
<div class="w-2/4 p-2">
<div class="bg-white border rounded dark:border-bg-black dark:bg-coolgray-100">
<div class="bg-white border rounded dark:border-black dark:bg-coolgray-100">
<div class="p-2">
<div class="">
@if (data_get($image, 'is_current'))

View File

@@ -75,7 +75,8 @@
<x-modal-input title="Edit Domains">
<x-slot:content>
<span class="cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 dark:text-warning text-coollabs"
<svg xmlns="http://www.w3.org/2000/svg"
class="w-4 h-4 dark:text-warning text-coollabs"
viewBox="0 0 24 24">
<g fill="none" stroke="currentColor"
stroke-linecap="round" stroke-linejoin="round"
@@ -89,7 +90,8 @@
</span>
</x-slot:content>
<livewire:project.service.edit-domain
applicationId="{{ $application->id }}" wire:key="edit-domain-{{ $application->id }}" />
applicationId="{{ $application->id }}"
wire:key="edit-domain-{{ $application->id }}" />
</x-modal-input>
</span>
@endif
@@ -160,29 +162,29 @@
<span class="dark:text-warning">Please modify storage layout in your Docker Compose file.</span>
@foreach ($applications as $application)
<livewire:project.service.storage wire:key="application-{{ $application->id }}"
:resource="$application" lazy />
:resource="$application" />
@endforeach
@foreach ($databases as $database)
<livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database" lazy />
<livewire:project.service.storage wire:key="database-{{ $database->id }}" :resource="$database" />
@endforeach
</div>
<div x-cloak x-show="activeTab === 'webhooks'">
<livewire:project.shared.webhooks :resource="$service" lazy />
<livewire:project.shared.webhooks :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'logs'">
<livewire:project.shared.logs :resource="$service" />
<livewire:project.shared.logs :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'execute-command'">
<livewire:project.shared.execute-container-command :resource="$service" />
<livewire:project.shared.execute-container-command :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'environment-variables'">
<livewire:project.shared.environment-variable.all :resource="$service" lazy />
<livewire:project.shared.environment-variable.all :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'resource-operations'">
<livewire:project.shared.resource-operations :resource="$service" lazy />
<livewire:project.shared.resource-operations :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'tags'">
<livewire:project.shared.tags :resource="$service" lazy />
<livewire:project.shared.tags :resource="$service" />
</div>
<div x-cloak x-show="activeTab === 'danger'">
<livewire:project.shared.danger :resource="$service" />

View File

@@ -23,10 +23,11 @@
</div>
<div class="grid grid-cols-2 gap-2">
@foreach ($fields as $serviceName => $field)
<div class="flex items-center gap-2"><span
class="font-bold">{{ data_get($field, 'serviceName') }}</span>{{ data_get($field, 'name') }}<x-helper
helper="Variable name: {{ $serviceName }}" /></div>
<x-forms.input type="{{ data_get($field, 'isPassword') ? 'password' : 'text' }}"
required="{{ str(data_get($field, 'rules'))?->contains('required') }}"
helper="Variable name: {{ $serviceName }}"
label="{{ data_get($field, 'serviceName') }} {{ data_get($field, 'name') }}"
id="fields.{{ $serviceName }}.value"></x-forms.input>
@endforeach
</div>

View File

@@ -1,5 +1,5 @@
# documentation: https://appsmith.com
# slogan: Appsmith is low-code application platform for building internal tools.
# slogan: A low-code application platform for building internal tools.
# tags: lowcode,nocode,no,low,platform
# logo: svgs/appsmith.svg

View File

@@ -1,5 +1,5 @@
# documentation: https://appwrite.io
# slogan: Appwrite is backend-as-a-service platform that simplifies the web & mobile app development.
# slogan: A backend-as-a-service platform that simplifies the web & mobile app development.
# env_file: appwrite.env
# tags: backend-as-a-service, platform
# logo: svgs/appwrite.svg

View File

@@ -1,5 +1,5 @@
# documentation: https://docs.baby-buddy.net
# slogan: Baby Buddy helps parents track their baby's daily activities, growth, and health with ease.
# slogan: It helps parents track their baby's daily activities, growth, and health with ease.
# tags: baby, parents, health, growth, activities
# logo: svgs/babybuddy.png

View File

@@ -1,5 +1,5 @@
# documentation: https://github.com/linuxserver/budge
# slogan: Budge is a budgeting personal finance app.
# slogan: A budgeting personal finance app.
# tags: personal finance, budgeting, expense tracking
services:

View File

@@ -0,0 +1,42 @@
# documentation: https://tolgee.io/
# slogan: Tolgee is a localization management platform for developers and translators.
# tags: localization,translation,management,platform
# logo: svgs/tolgee.svg
# port: 8080
services:
tolgee:
image: tolgee/tolgee
environment:
- SERVICE_FQDN_TOLGEE_8080
- TOLGEE_AUTHENTICATION_ENABLED=true
- TOLGEE_AUTHENTICATION_INITIAL_PASSWORD=$SERVICE_PASSWORD_TOLGEE
- TOLGEE_AUTHENTICATION_INITIAL_USERNAME=admin
- TOLGEE_AUTHENTICATION_JWT_SECRET=$SERVICE_PASSWORD_JWT
- TOLGEE_POSTGRES_AUTOSTART_ENABLED=false
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgresql:5432/${POSTGRES_DB:-tolgee}
- SPRING_DATASOURCE_USERNAME=${SERVICE_USER_POSTGRESQL}
- SPRING_DATASOURCE_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
volumes:
- tolgee-data:/data
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080"]
interval: 5s
timeout: 20s
retries: 10
depends_on:
postgresql:
condition: service_healthy
postgresql:
image: postgres:16-alpine
volumes:
- tolgee-postgresql-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=${SERVICE_USER_POSTGRESQL}
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL}
- POSTGRES_DB=${POSTGRESQL_DATABASE:-tolgee}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 20s
retries: 10

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"coolify": {
"v4": {
"version": "4.0.0-beta.259"
"version": "4.0.0-beta.265"
}
}
}