mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-13 20:14:45 +00:00
Merge branch 'next' into improve-persist-ssh-sessions
This commit is contained in:
11 files changed
+332
-283
No files matched your search
@@ -38,6 +38,8 @@ jobs:
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
|
||||
labels: |
|
||||
coolify.managed=true
|
||||
aarch64:
|
||||
runs-on: [ self-hosted, arm64 ]
|
||||
permissions:
|
||||
@@ -64,6 +66,8 @@ jobs:
|
||||
platforms: linux/aarch64
|
||||
push: true
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
|
||||
labels: |
|
||||
coolify.managed=true
|
||||
merge-manifest:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
@@ -94,3 +98,4 @@ jobs:
|
||||
if: always()
|
||||
with:
|
||||
webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }}
|
||||
|
||||
@@ -2,7 +2,7 @@ name: Coolify Helper Image (v4)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
branches: [ "main", "next" ]
|
||||
paths:
|
||||
- .github/workflows/coolify-helper.yml
|
||||
- docker/coolify-helper/Dockerfile
|
||||
@@ -38,6 +38,8 @@ jobs:
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
|
||||
labels: |
|
||||
coolify.managed=true
|
||||
aarch64:
|
||||
runs-on: [ self-hosted, arm64 ]
|
||||
permissions:
|
||||
@@ -64,6 +66,8 @@ jobs:
|
||||
platforms: linux/aarch64
|
||||
push: true
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
|
||||
labels: |
|
||||
coolify.managed=true
|
||||
merge-manifest:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
|
||||
@@ -23,7 +23,7 @@ class CleanupDocker
|
||||
{
|
||||
$commonCommands = [
|
||||
'docker container prune -f --filter "label=coolify.managed=true"',
|
||||
'docker image prune -af',
|
||||
'docker image prune -af --filter "label!=coolify.managed=true"',
|
||||
'docker builder prune -af',
|
||||
];
|
||||
|
||||
|
||||
+230
-174
@@ -2864,6 +2864,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
|
||||
return collect($finalServices);
|
||||
}
|
||||
}
|
||||
|
||||
function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $preview_id = null): Collection
|
||||
{
|
||||
$isApplication = $resource instanceof Application;
|
||||
@@ -2920,6 +2921,178 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
}
|
||||
|
||||
$parsedServices = collect([]);
|
||||
|
||||
// parse environments first
|
||||
$allMagicEnvironments = collect([]);
|
||||
foreach ($services as $serviceName => $service) {
|
||||
$magicEnvironments = collect([]);
|
||||
$image = data_get_str($service, 'image');
|
||||
$environment = collect(data_get($service, 'environment', []));
|
||||
$buildArgs = collect(data_get($service, 'build.args', []));
|
||||
$environment = $environment->merge($buildArgs);
|
||||
$isDatabase = isDatabaseImage(data_get_str($service, 'image'));
|
||||
|
||||
if ($isService) {
|
||||
if ($isDatabase) {
|
||||
$savedService = ServiceDatabase::firstOrCreate([
|
||||
'name' => $serviceName,
|
||||
'image' => $image,
|
||||
'service_id' => $resource->id,
|
||||
]);
|
||||
} else {
|
||||
$savedService = ServiceApplication::firstOrCreate([
|
||||
'name' => $serviceName,
|
||||
'image' => $image,
|
||||
'service_id' => $resource->id,
|
||||
]);
|
||||
}
|
||||
$environment = collect(data_get($service, 'environment', []));
|
||||
$buildArgs = collect(data_get($service, 'build.args', []));
|
||||
$environment = $environment->merge($buildArgs);
|
||||
|
||||
// convert environment variables to one format
|
||||
$environment = convertComposeEnvironmentToArray($environment);
|
||||
|
||||
// Add Coolify defined environments
|
||||
$allEnvironments = $resource->environment_variables()->get(['key', 'value']);
|
||||
|
||||
$allEnvironments = $allEnvironments->mapWithKeys(function ($item) {
|
||||
return [$item['key'] => $item['value']];
|
||||
});
|
||||
// filter magic environments
|
||||
foreach ($environment as $key => $value) {
|
||||
$regex = '/\$(\{?([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\}?)/';
|
||||
preg_match_all($regex, $value, $valueMatches);
|
||||
preg_match_all($regex, $key, $keyMatches);
|
||||
if (count($valueMatches[1]) > 0) {
|
||||
foreach ($valueMatches[1] as $match) {
|
||||
if (str($match)->startsWith('SERVICE_')) {
|
||||
if ($magicEnvironments->has($match)) {
|
||||
continue;
|
||||
}
|
||||
$magicEnvironments->put($match, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($keyMatches[1]) > 0) {
|
||||
foreach ($keyMatches[1] as $match) {
|
||||
if (str($match)->startsWith('SERVICE_')) {
|
||||
if ($magicEnvironments->has($match)) {
|
||||
continue;
|
||||
}
|
||||
$magicEnvironments->put($match, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str($key)->startsWith('SERVICE_')) {
|
||||
$magicEnvironments->put($key, $value);
|
||||
if (substr_count(str($key)->value(), '_') === 3) {
|
||||
$newKey = str($key)->beforeLast('_')->value();
|
||||
if ($newKey) {
|
||||
$magicEnvironments->put($newKey, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$allMagicEnvironments = $allMagicEnvironments->merge($magicEnvironments);
|
||||
if ($magicEnvironments->count() > 0) {
|
||||
foreach ($magicEnvironments as $key => $value) {
|
||||
$key = str($key);
|
||||
$value = str(replaceVariables(str($value)));
|
||||
$originalValue = $value;
|
||||
$keyCommand = $key->after('SERVICE_')->before('_');
|
||||
$valueCommand = $value->after('SERVICE_')->before('_');
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
|
||||
if (str($fqdnFor)->contains('_')) {
|
||||
$fqdnFor = str($fqdnFor)->before('_');
|
||||
}
|
||||
} elseif ($value->startsWith('SERVICE_FQDN_')) {
|
||||
$fqdnFor = $value->after('SERVICE_FQDN_')->lower()->value();
|
||||
if (str($fqdnFor)->contains('_')) {
|
||||
$fqdnFor = str($fqdnFor)->before('_');
|
||||
}
|
||||
} else {
|
||||
$fqdnFor = null;
|
||||
}
|
||||
if ($keyCommand->value() === 'FQDN' || $valueCommand->value() === 'FQDN') {
|
||||
if ($isApplication) {
|
||||
$fqdn = generateFqdn($server, "{$resource->name}-$uuid");
|
||||
} elseif ($isService) {
|
||||
if ($fqdnFor) {
|
||||
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
||||
} else {
|
||||
$fqdn = generateFqdn($server, "{$savedService->name}-$uuid");
|
||||
}
|
||||
}
|
||||
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
|
||||
$path = $value->value();
|
||||
if ($value === '/') {
|
||||
$value = "$fqdn";
|
||||
} else {
|
||||
$value = "$fqdn$path";
|
||||
}
|
||||
} else {
|
||||
$value = $fqdn;
|
||||
}
|
||||
if (! $isDatabase) {
|
||||
if ($key->startsWith('SERVICE_FQDN_') && ($originalValue->value() === '' || $originalValue->startsWith('/'))) {
|
||||
if ($isApplication && is_null($resource->fqdn)) {
|
||||
data_forget($resource, 'environment_variables');
|
||||
data_forget($resource, 'environment_variables_preview');
|
||||
$resource->fqdn = $value;
|
||||
$resource->save();
|
||||
} elseif ($isService && is_null($savedService->fqdn)) {
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$savedService->fqdn = $value;
|
||||
$savedService->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($keyCommand->value() === 'URL' || $valueCommand->value() === 'URL') {
|
||||
if ($isApplication) {
|
||||
$fqdn = generateFqdn($server, "{$resource->name}-{$uuid}");
|
||||
} elseif ($isService) {
|
||||
$fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
|
||||
}
|
||||
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
|
||||
$path = $value->value();
|
||||
$value = "$fqdn$path";
|
||||
} else {
|
||||
$value = $fqdn;
|
||||
}
|
||||
$value = str($fqdn)->replace('http://', '')->replace('https://', '');
|
||||
} else {
|
||||
$generatedValue = generateEnvValue($keyCommand, $resource);
|
||||
if ($generatedValue) {
|
||||
$value = $generatedValue;
|
||||
}
|
||||
}
|
||||
if (str($fqdnFor)->startsWith('/')) {
|
||||
$fqdnFor = null;
|
||||
}
|
||||
// Lets save the magic value to the environment variables
|
||||
if (! $originalValue->startsWith('/')) {
|
||||
if ($key->startsWith('SERVICE_')) {
|
||||
$originalValue = $key;
|
||||
}
|
||||
$resource->environment_variables()->where('key', $originalValue->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
||||
'key' => $originalValue->value(),
|
||||
$nameOfId => $resource->id,
|
||||
], [
|
||||
'value' => $value,
|
||||
'is_build_time' => false,
|
||||
'is_preview' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the rest of the services
|
||||
foreach ($services as $serviceName => $service) {
|
||||
$image = data_get_str($service, 'image');
|
||||
$restart = data_get_str($service, 'restart', RESTART_MODE);
|
||||
@@ -2938,6 +3111,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
$ports = collect(data_get($service, 'ports', []));
|
||||
$buildArgs = collect(data_get($service, 'build.args', []));
|
||||
$environment = $environment->merge($buildArgs);
|
||||
|
||||
$environment = convertComposeEnvironmentToArray($environment);
|
||||
$coolifyEnvironments = collect([]);
|
||||
|
||||
$isDatabase = isDatabaseImage(data_get_str($service, 'image'));
|
||||
$volumesParsed = collect([]);
|
||||
|
||||
@@ -3069,10 +3246,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
if ($topLevel->get('volumes')->has($source->value())) {
|
||||
$temp = $topLevel->get('volumes')->get($source->value());
|
||||
if (data_get($temp, 'driver_opts.type') === 'cifs') {
|
||||
return $volume;
|
||||
continue;
|
||||
}
|
||||
if (data_get($temp, 'driver_opts.type') === 'nfs') {
|
||||
return $volume;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$slugWithoutUuid = Str::slug($source, '-');
|
||||
@@ -3204,177 +3381,19 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
]);
|
||||
}
|
||||
}
|
||||
// convert environment variables to one format
|
||||
$environment = convertComposeEnvironmentToArray($environment);
|
||||
|
||||
// Add Coolify defined environments
|
||||
$allEnvironments = $resource->environment_variables()->get(['key', 'value']);
|
||||
|
||||
$allEnvironments = $allEnvironments->mapWithKeys(function ($item) {
|
||||
return [$item['key'] => $item['value']];
|
||||
$normalEnvironments = $environment->diffKeys($allMagicEnvironments);
|
||||
$normalEnvironments = $normalEnvironments->filter(function ($value, $key) {
|
||||
return ! str($value)->startsWith('SERVICE_');
|
||||
});
|
||||
|
||||
// remove $environment from $allEnvironments
|
||||
$coolifyDefinedEnvironments = $allEnvironments->diffKeys($environment);
|
||||
|
||||
// filter magic environments
|
||||
$magicEnvironments = $environment->filter(function ($value, $key) {
|
||||
$regex = '/\$\{(.*?)\}/';
|
||||
preg_match_all($regex, $value, $matches);
|
||||
if (count($matches[1]) > 0) {
|
||||
foreach ($matches[1] as $match) {
|
||||
if (str($match)->startsWith('SERVICE_') || str($match)->startsWith('SERVICE_')) {
|
||||
return $match;
|
||||
}
|
||||
}
|
||||
}
|
||||
$value = str(replaceVariables(str($value)));
|
||||
|
||||
return str($key)->startsWith('SERVICE_') || str($value)->startsWith('SERVICE_');
|
||||
});
|
||||
foreach ($environment as $key => $value) {
|
||||
$regex = '/\$\{(.*?)\}/';
|
||||
preg_match_all($regex, $value, $matches);
|
||||
if (count($matches[1]) > 0) {
|
||||
foreach ($matches[1] as $match) {
|
||||
if (str($match)->startsWith('SERVICE_') || str($match)->startsWith('SERVICE_')) {
|
||||
$magicEnvironments->put($match, '$'.$match);
|
||||
}
|
||||
}
|
||||
$magicEnvironments->forget($key);
|
||||
}
|
||||
}
|
||||
$normalEnvironments = $environment->diffKeys($magicEnvironments);
|
||||
if ($magicEnvironments->count() > 0) {
|
||||
foreach ($magicEnvironments as $key => $value) {
|
||||
$key = str($key);
|
||||
$value = str(replaceVariables(str($value)));
|
||||
$originalValue = $value;
|
||||
$keyCommand = $key->after('SERVICE_')->before('_');
|
||||
$valueCommand = $value->after('SERVICE_')->before('_');
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value();
|
||||
if (str($fqdnFor)->contains('_')) {
|
||||
$fqdnFor = str($fqdnFor)->before('_');
|
||||
}
|
||||
} elseif ($value->startsWith('SERVICE_FQDN_')) {
|
||||
$fqdnFor = $value->after('SERVICE_FQDN_')->lower()->value();
|
||||
if (str($fqdnFor)->contains('_')) {
|
||||
$fqdnFor = str($fqdnFor)->before('_');
|
||||
}
|
||||
} else {
|
||||
$fqdnFor = null;
|
||||
}
|
||||
if ($keyCommand->value() === 'FQDN' || $valueCommand->value() === 'FQDN') {
|
||||
if ($isApplication) {
|
||||
$fqdn = generateFqdn($server, "{$resource->name}-$uuid");
|
||||
} elseif ($isService) {
|
||||
if ($fqdnFor) {
|
||||
$fqdn = generateFqdn($server, "$fqdnFor-$uuid");
|
||||
} else {
|
||||
$fqdn = generateFqdn($server, "{$savedService->name}-$uuid");
|
||||
}
|
||||
}
|
||||
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
|
||||
$path = $value->value();
|
||||
if ($value === '/') {
|
||||
$value = "$fqdn";
|
||||
} else {
|
||||
$value = "$fqdn$path";
|
||||
}
|
||||
} else {
|
||||
$value = $fqdn;
|
||||
}
|
||||
if (! $isDatabase) {
|
||||
if ($key->startsWith('SERVICE_FQDN_') && ($originalValue->value() === '' || $originalValue->startsWith('/'))) {
|
||||
if ($isApplication && is_null($resource->fqdn)) {
|
||||
data_forget($resource, 'environment_variables');
|
||||
data_forget($resource, 'environment_variables_preview');
|
||||
$resource->fqdn = $value;
|
||||
$resource->save();
|
||||
} elseif ($isService && is_null($savedService->fqdn)) {
|
||||
if ($key->startsWith('SERVICE_FQDN_')) {
|
||||
$savedService->fqdn = $value;
|
||||
$savedService->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($keyCommand->value() === 'URL' || $valueCommand->value() === 'URL') {
|
||||
if ($isApplication) {
|
||||
$fqdn = generateFqdn($server, "{$resource->name}-{$uuid}");
|
||||
} elseif ($isService) {
|
||||
$fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}");
|
||||
}
|
||||
if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) {
|
||||
$path = $value->value();
|
||||
$value = "$fqdn$path";
|
||||
} else {
|
||||
$value = $fqdn;
|
||||
}
|
||||
$value = str($fqdn)->replace('http://', '')->replace('https://', '');
|
||||
} else {
|
||||
$generatedValue = generateEnvValue($valueCommand, $resource);
|
||||
if ($generatedValue) {
|
||||
$value = $generatedValue;
|
||||
}
|
||||
}
|
||||
if (str($fqdnFor)->startsWith('/')) {
|
||||
$fqdnFor = null;
|
||||
}
|
||||
// Lets save the magic value to the environment variables
|
||||
if (! $originalValue->startsWith('/')) {
|
||||
if ($key->startsWith('SERVICE_')) {
|
||||
$originalValue = $key;
|
||||
}
|
||||
$resource->environment_variables()->where('key', $originalValue->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
||||
'key' => $originalValue->value(),
|
||||
$nameOfId => $resource->id,
|
||||
], [
|
||||
'value' => $value,
|
||||
'is_build_time' => false,
|
||||
'is_preview' => false,
|
||||
]);
|
||||
}
|
||||
// Save the original value to the environment variables
|
||||
if ($originalValue->startsWith('SERVICE_')) {
|
||||
$value = "$$originalValue";
|
||||
}
|
||||
$resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->firstOrCreate([
|
||||
'key' => $key->value(),
|
||||
$nameOfId => $resource->id,
|
||||
], [
|
||||
'value' => "$value",
|
||||
'is_build_time' => false,
|
||||
'is_preview' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach ($normalEnvironments as $key => $value) {
|
||||
$key = str($key);
|
||||
$value = str($value);
|
||||
if ($value->startsWith('$') || $value->contains('${')) {
|
||||
if ($value->contains('${')) {
|
||||
$value = $value->after('${')->before('}');
|
||||
}
|
||||
$value = str(replaceVariables(str($value)));
|
||||
if ($value->contains(':-')) {
|
||||
$key = $value->before(':');
|
||||
$value = $value->after(':-');
|
||||
} elseif ($value->contains('-')) {
|
||||
$key = $value->before('-');
|
||||
$value = $value->after('-');
|
||||
} elseif ($value->contains(':?')) {
|
||||
$key = $value->before(':');
|
||||
$value = $value->after(':?');
|
||||
} elseif ($value->contains('?')) {
|
||||
$key = $value->before('?');
|
||||
$value = $value->after('?');
|
||||
} else {
|
||||
$key = $value;
|
||||
$value = null;
|
||||
}
|
||||
$parsedValue = str(replaceVariables(str($value)));
|
||||
|
||||
if ($key->value() === $parsedValue->value()) {
|
||||
$value = null;
|
||||
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
|
||||
'key' => $key,
|
||||
$nameOfId => $resource->id,
|
||||
@@ -3383,6 +3402,38 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
'is_build_time' => false,
|
||||
'is_preview' => false,
|
||||
]);
|
||||
} else {
|
||||
if ($value->startsWith('$')) {
|
||||
if ($value->contains(':-')) {
|
||||
$value = str(replaceVariables(str($value)));
|
||||
$key = $value->before(':');
|
||||
$value = $value->after(':-');
|
||||
} elseif ($value->contains('-')) {
|
||||
$value = str(replaceVariables(str($value)));
|
||||
|
||||
$key = $value->before('-');
|
||||
$value = $value->after('-');
|
||||
} elseif ($value->contains(':?')) {
|
||||
$value = str(replaceVariables(str($value)));
|
||||
|
||||
$key = $value->before(':');
|
||||
$value = $value->after(':?');
|
||||
} elseif ($value->contains('?')) {
|
||||
$value = str(replaceVariables(str($value)));
|
||||
|
||||
$key = $value->before('?');
|
||||
$value = $value->after('?');
|
||||
}
|
||||
$resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
|
||||
'key' => $key,
|
||||
$nameOfId => $resource->id,
|
||||
], [
|
||||
'value' => $value,
|
||||
'is_build_time' => false,
|
||||
'is_preview' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ($isApplication) {
|
||||
@@ -3391,13 +3442,13 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
$branch = "pull/{$pullRequestId}/head";
|
||||
}
|
||||
if ($originalResource->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
|
||||
$environment->put('COOLIFY_BRANCH', $branch);
|
||||
$coolifyEnvironments->put('COOLIFY_BRANCH', $branch);
|
||||
}
|
||||
}
|
||||
|
||||
// Add COOLIFY_CONTAINER_NAME to environment
|
||||
if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
|
||||
$environment->put('COOLIFY_CONTAINER_NAME', $containerName);
|
||||
$coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', $containerName);
|
||||
}
|
||||
|
||||
if ($isApplication) {
|
||||
@@ -3451,15 +3502,20 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
}
|
||||
// Add COOLIFY_FQDN & COOLIFY_URL to environment
|
||||
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
|
||||
$environment->put('COOLIFY_URL', $fqdns->implode(','));
|
||||
$coolifyEnvironments->put('COOLIFY_URL', $fqdns->implode(','));
|
||||
|
||||
$urls = $fqdns->map(function ($fqdn) {
|
||||
return str($fqdn)->replace('http://', '')->replace('https://', '');
|
||||
});
|
||||
$environment->put('COOLIFY_FQDN', $urls->implode(','));
|
||||
$coolifyEnvironments->put('COOLIFY_FQDN', $urls->implode(','));
|
||||
}
|
||||
add_coolify_default_environment_variables($resource, $environment, $resource->environment_variables);
|
||||
add_coolify_default_environment_variables($resource, $coolifyEnvironments, $resource->environment_variables);
|
||||
|
||||
if ($environment->count() > 0) {
|
||||
$environment = $environment->filter(function ($value, $key) {
|
||||
return ! str($key)->startsWith('SERVICE_FQDN_');
|
||||
});
|
||||
}
|
||||
$serviceLabels = $labels->merge($defaultLabels);
|
||||
if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
|
||||
if ($isApplication) {
|
||||
@@ -3554,8 +3610,8 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
|
||||
if ($volumesParsed->count() > 0) {
|
||||
$payload['volumes'] = $volumesParsed;
|
||||
}
|
||||
if ($environment->count() > 0 || $coolifyDefinedEnvironments->count() > 0) {
|
||||
$payload['environment'] = $environment->merge($coolifyDefinedEnvironments);
|
||||
if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) {
|
||||
$payload['environment'] = $environment->merge($coolifyEnvironments);
|
||||
}
|
||||
if ($logging) {
|
||||
$payload['logging'] = $logging;
|
||||
|
||||
+1
-1
@@ -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.331',
|
||||
'release' => '4.0.0-beta.332',
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => config('app.env'),
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
<?php
|
||||
|
||||
return '4.0.0-beta.331';
|
||||
return '4.0.0-beta.332';
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use App\Models\ServerSetting;
|
||||
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('server_settings', function (Blueprint $table) {
|
||||
$table->string('docker_cleanup_frequency')->default('0 0 * * *')->change();
|
||||
});
|
||||
|
||||
$serverSettings = ServerSetting::all();
|
||||
foreach ($serverSettings as $serverSetting) {
|
||||
if ($serverSetting->force_docker_cleanup && $serverSetting->docker_cleanup_frequency === '*/10 * * * *') {
|
||||
$serverSetting->docker_cleanup_frequency = '0 0 * * *';
|
||||
$serverSetting->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('server_settings', function (Blueprint $table) {
|
||||
$table->string('docker_cleanup_frequency')->default('*/10 * * * *')->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -16,7 +16,7 @@ services:
|
||||
environment:
|
||||
- SERVICE_FQDN_PLUNK_3000
|
||||
- REDIS_URL=redis://redis:6379
|
||||
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/docmost?schema=public
|
||||
- DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/plunk?schema=public
|
||||
- JWT_SECRET=${SERVICE_PASSWORD_JWT_SECRET}
|
||||
- AWS_REGION=${AWS_REGION}
|
||||
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"activepieces":{"documentation":"https:\/\/www.activepieces.com\/docs\/getting-started\/introduction?utm_source=coolify.io","slogan":"Open source no-code business automation.","compose":"c2VydmljZXM6CiAgYWN0aXZlcGllY2VzOgogICAgaW1hZ2U6ICdnaGNyLmlvL2FjdGl2ZXBpZWNlcy9hY3RpdmVwaWVjZXM6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0FDVElWRVBJRUNFUwogICAgICAtIEFQX0FQSV9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfQVBJS0VZCiAgICAgIC0gQVBfRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfRU5DUllQVElPTktFWQogICAgICAtIEFQX0VOR0lORV9FWEVDVVRBQkxFX1BBVEg9ZGlzdC9wYWNrYWdlcy9lbmdpbmUvbWFpbi5qcwogICAgICAtIEFQX0VOVklST05NRU5UPXByb2QKICAgICAgLSBBUF9FWEVDVVRJT05fTU9ERT1VTlNBTkRCT1hFRAogICAgICAtIEFQX0ZST05URU5EX1VSTD0kU0VSVklDRV9GUUROX0FDVElWRVBJRUNFUwogICAgICAtIEFQX0pXVF9TRUNSRVQ9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfSldUCiAgICAgIC0gQVBfUE9TVEdSRVNfREFUQUJBU0U9YWN0aXZlcGllY2VzCiAgICAgIC0gQVBfUE9TVEdSRVNfSE9TVD1wb3N0Z3JlcwogICAgICAtIEFQX1BPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gQVBfUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gQVBfUE9TVEdSRVNfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIEFQX1JFRElTX0hPU1Q9cmVkaXMKICAgICAgLSBBUF9SRURJU19QT1JUPTYzNzkKICAgICAgLSBBUF9TQU5EQk9YX1JVTl9USU1FX1NFQ09ORFM9NjAwCiAgICAgIC0gQVBfVEVMRU1FVFJZX0VOQUJMRUQ9dHJ1ZQogICAgICAtICdBUF9URU1QTEFURVNfU09VUkNFX1VSTD1odHRwczovL2Nsb3VkLmFjdGl2ZXBpZWNlcy5jb20vYXBpL3YxL2Zsb3ctdGVtcGxhdGVzJwogICAgICAtIEFQX1RSSUdHRVJfREVGQVVMVF9QT0xMX0lOVEVSVkFMPTUKICAgICAgLSBBUF9XRUJIT09LX1RJTUVPVVRfU0VDT05EUz0zMAogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19EQj1hY3RpdmVwaWVjZXMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgdm9sdW1lczoKICAgICAgLSAncGctZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK","tags":["workflow","automation","no code","open source"],"logo":"svgs\/activepieces.png","minversion":"0.0.0","port":"80"},"appsmith":{"documentation":"https:\/\/appsmith.com?utm_source=coolify.io","slogan":"A low-code application platform for building internal tools.","compose":"c2VydmljZXM6CiAgYXBwc21pdGg6CiAgICBpbWFnZTogJ2luZGV4LmRvY2tlci5pby9hcHBzbWl0aC9hcHBzbWl0aC1jZTpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVBQU01JVEgKICAgICAgLSBBUFBTTUlUSF9NQUlMX0VOQUJMRUQ9ZmFsc2UKICAgICAgLSBBUFBTTUlUSF9ESVNBQkxFX1RFTEVNRVRSWT10cnVlCiAgICAgIC0gQVBQU01JVEhfRElTQUJMRV9JTlRFUkNPTT10cnVlCiAgICAgIC0gQVBQU01JVEhfU0VOVFJZX0RTTj0KICAgICAgLSBBUFBTTUlUSF9TTUFSVF9MT09LX0lEPQogICAgdm9sdW1lczoKICAgICAgLSAnc3RhY2tzLWRhdGE6L2FwcHNtaXRoLXN0YWNrcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=","tags":["lowcode","nocode","no","low","platform"],"logo":"svgs\/appsmith.svg","minversion":"0.0.0"},"appwrite":{"documentation":"https:\/\/appwrite.io?utm_source=coolify.io","slogan":"A backend-as-a-service platform that simplifies the web & mobile app development.","compose":"eC1sb2dnaW5nOgogIGxvZ2dpbmc6CiAgICBkcml2ZXI6IGpzb24tZmlsZQogICAgb3B0aW9uczoKICAgICAgbWF4LWZpbGU6ICc1JwogICAgICBtYXgtc2l6ZTogMTBtCnNlcnZpY2VzOgogIGFwcHdyaXRlOgogICAgaW1hZ2U6ICdhcHB3cml0ZS9hcHB3cml0ZToxLjUnCiAgICBjb250YWluZXJfbmFtZTogYXBwd3JpdGUKICAgIGxvZ2dpbmc6CiAgICAgIGRyaXZlcjoganNvbi1maWxlCiAgICAgIG9wdGlvbnM6CiAgICAgICAgbWF4LWZpbGU6ICc1JwogICAgICAgIG1heC1zaXplOiAxMG0KICAgIHZvbHVtZXM6CiAgICAgIC0gJ2FwcHdyaXRlLXVwbG9hZHM6L3N0b3JhZ2UvdXBsb2FkczpydycKICAgICAgLSAnYXBwd3JpdGUtY2FjaGU6L3N0b3JhZ2UvY2FjaGU6cncnCiAgICAgIC0gJ2FwcHdyaXRlLWNvbmZpZzovc3RvcmFnZS9jb25maWc6cncnCiAgICAgIC0gJ2FwcHdyaXRlLWNlcnRpZmljYXRlczovc3RvcmFnZS9jZXJ0aWZpY2F0ZXM6cncnCiAgICAgIC0gJ2FwcHdyaXRlLWZ1bmN0aW9uczovc3RvcmFnZS9mdW5jdGlvbnM6cncnCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwcHdyaXRlLW1hcmlhZGIKICAgICAgLSBhcHB3cml0ZS1yZWRpcwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0FQUFdSSVRFPS8KICAgICAgLSBfQVBQX0VOVgogICAgICAtIF9BUFBfV09SS0VSX1BFUl9DT1JFCiAgICAgIC0gX0FQUF9MT0NBTEUKICAgICAgLSBfQVBQX0NPTlNPTEVfV0hJVEVMSVNUX1JPT1QKICAgICAgLSBfQVBQX0NPTlNPTEVfV0hJVEVMSVNUX0VNQUlMUwogICAgICAtIF9BLine truncated
|
||||
{"activepieces":{"documentation":"https:\/\/www.activepieces.com\/docs\/getting-started\/introduction?utm_source=coolify.io","slogan":"Open source no-code business automation.","compose":"c2VydmljZXM6CiAgYWN0aXZlcGllY2VzOgogICAgaW1hZ2U6ICdnaGNyLmlvL2FjdGl2ZXBpZWNlcy9hY3RpdmVwaWVjZXM6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0FDVElWRVBJRUNFUwogICAgICAtIEFQX0FQSV9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfQVBJS0VZCiAgICAgIC0gQVBfRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfRU5DUllQVElPTktFWQogICAgICAtIEFQX0VOR0lORV9FWEVDVVRBQkxFX1BBVEg9ZGlzdC9wYWNrYWdlcy9lbmdpbmUvbWFpbi5qcwogICAgICAtIEFQX0VOVklST05NRU5UPXByb2QKICAgICAgLSBBUF9FWEVDVVRJT05fTU9ERT1VTlNBTkRCT1hFRAogICAgICAtIEFQX0ZST05URU5EX1VSTD0kU0VSVklDRV9GUUROX0FDVElWRVBJRUNFUwogICAgICAtIEFQX0pXVF9TRUNSRVQ9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfSldUCiAgICAgIC0gQVBfUE9TVEdSRVNfREFUQUJBU0U9YWN0aXZlcGllY2VzCiAgICAgIC0gQVBfUE9TVEdSRVNfSE9TVD1wb3N0Z3JlcwogICAgICAtIEFQX1BPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gQVBfUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gQVBfUE9TVEdSRVNfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIEFQX1JFRElTX0hPU1Q9cmVkaXMKICAgICAgLSBBUF9SRURJU19QT1JUPTYzNzkKICAgICAgLSBBUF9TQU5EQk9YX1JVTl9USU1FX1NFQ09ORFM9NjAwCiAgICAgIC0gQVBfVEVMRU1FVFJZX0VOQUJMRUQ9dHJ1ZQogICAgICAtICdBUF9URU1QTEFURVNfU09VUkNFX1VSTD1odHRwczovL2Nsb3VkLmFjdGl2ZXBpZWNlcy5jb20vYXBpL3YxL2Zsb3ctdGVtcGxhdGVzJwogICAgICAtIEFQX1RSSUdHRVJfREVGQVVMVF9QT0xMX0lOVEVSVkFMPTUKICAgICAgLSBBUF9XRUJIT09LX1RJTUVPVVRfU0VDT05EUz0zMAogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19EQj1hY3RpdmVwaWVjZXMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgdm9sdW1lczoKICAgICAgLSAncGctZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK","tags":["workflow","automation","no code","open source"],"logo":"svgs\/activepieces.png","minversion":"0.0.0","port":"80"},"appsmith":{"documentation":"https:\/\/appsmith.com?utm_source=coolify.io","slogan":"A low-code application platform for building internal tools.","compose":"c2VydmljZXM6CiAgYXBwc21pdGg6CiAgICBpbWFnZTogJ2luZGV4LmRvY2tlci5pby9hcHBzbWl0aC9hcHBzbWl0aC1jZTpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVBQU01JVEgKICAgICAgLSBBUFBTTUlUSF9NQUlMX0VOQUJMRUQ9ZmFsc2UKICAgICAgLSBBUFBTTUlUSF9ESVNBQkxFX1RFTEVNRVRSWT10cnVlCiAgICAgIC0gQVBQU01JVEhfRElTQUJMRV9JTlRFUkNPTT10cnVlCiAgICAgIC0gQVBQU01JVEhfU0VOVFJZX0RTTj0KICAgICAgLSBBUFBTTUlUSF9TTUFSVF9MT09LX0lEPQogICAgdm9sdW1lczoKICAgICAgLSAnc3RhY2tzLWRhdGE6L2FwcHNtaXRoLXN0YWNrcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=","tags":["lowcode","nocode","no","low","platform"],"logo":"svgs\/appsmith.svg","minversion":"0.0.0"},"appwrite":{"documentation":"https:\/\/appwrite.io?utm_source=coolify.io","slogan":"A backend-as-a-service platform that simplifies the web & mobile app development.","compose":"eC1sb2dnaW5nOgogIGxvZ2dpbmc6CiAgICBkcml2ZXI6IGpzb24tZmlsZQogICAgb3B0aW9uczoKICAgICAgbWF4LWZpbGU6ICc1JwogICAgICBtYXgtc2l6ZTogMTBtCnNlcnZpY2VzOgogIGFwcHdyaXRlOgogICAgaW1hZ2U6ICdhcHB3cml0ZS9hcHB3cml0ZToxLjUnCiAgICBjb250YWluZXJfbmFtZTogYXBwd3JpdGUKICAgIGxvZ2dpbmc6CiAgICAgIGRyaXZlcjoganNvbi1maWxlCiAgICAgIG9wdGlvbnM6CiAgICAgICAgbWF4LWZpbGU6ICc1JwogICAgICAgIG1heC1zaXplOiAxMG0KICAgIHZvbHVtZXM6CiAgICAgIC0gJ2FwcHdyaXRlLXVwbG9hZHM6L3N0b3JhZ2UvdXBsb2FkczpydycKICAgICAgLSAnYXBwd3JpdGUtY2FjaGU6L3N0b3JhZ2UvY2FjaGU6cncnCiAgICAgIC0gJ2FwcHdyaXRlLWNvbmZpZzovc3RvcmFnZS9jb25maWc6cncnCiAgICAgIC0gJ2FwcHdyaXRlLWNlcnRpZmljYXRlczovc3RvcmFnZS9jZXJ0aWZpY2F0ZXM6cncnCiAgICAgIC0gJ2FwcHdyaXRlLWZ1bmN0aW9uczovc3RvcmFnZS9mdW5jdGlvbnM6cncnCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwcHdyaXRlLW1hcmlhZGIKICAgICAgLSBhcHB3cml0ZS1yZWRpcwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0FQUFdSSVRFPS8KICAgICAgLSBfQVBQX0VOVgogICAgICAtIF9BUFBfV09SS0VSX1BFUl9DT1JFCiAgICAgIC0gX0FQUF9MT0NBTEUKICAgICAgLSBfQVBQX0NPTlNPTEVfV0hJVEVMSVNUX1JPT1QKICAgICAgLSBfQVBQX0NPTlNPTEVfV0hJVEVMSVNUX0VNQUlMUwogICAgICAtIF9BLine truncated
|
||||
@@ -88,114 +88,61 @@ networks:
|
||||
]);
|
||||
$this->serviceYaml = '
|
||||
services:
|
||||
chatwoot:
|
||||
image: chatwoot/chatwoot:latest
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
activepieces:
|
||||
image: "ghcr.io/activepieces/activepieces:latest"
|
||||
environment:
|
||||
- SERVICE_FQDN_CHATWOOT_3000
|
||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||
- FORCE_SSL=false
|
||||
- ENABLE_ACCOUNT_SIGNUP=false
|
||||
- REDIS_URL=redis://default@redis:6379
|
||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
||||
- POSTGRES_DATABASE=chatwoot
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- RAILS_MAX_THREADS=5
|
||||
- NODE_ENV=production
|
||||
- RAILS_ENV=production
|
||||
- INSTALLATION_ENV=docker
|
||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||
- SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
|
||||
- SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
|
||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||
- ACTIVE_STORAGE_SERVICE=local
|
||||
entrypoint: docker/entrypoints/rails.sh
|
||||
command: sh -c "bundle exec rails db:chatwoot_prepare && bundle exec rails s -p 3000 -b 0.0.0.0"
|
||||
volumes:
|
||||
- rails-data:/app/storage
|
||||
- SERVICE_FQDN_ACTIVEPIECES
|
||||
- AP_API_KEY=$SERVICE_PASSWORD_64_APIKEY
|
||||
- AP_ENCRYPTION_KEY=$SERVICE_PASSWORD_ENCRYPTIONKEY
|
||||
- AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js
|
||||
- AP_ENVIRONMENT=prod
|
||||
- AP_EXECUTION_MODE=UNSANDBOXED
|
||||
- AP_FRONTEND_URL=$SERVICE_FQDN_ACTIVEPIECES
|
||||
- AP_JWT_SECRET=$SERVICE_PASSWORD_64_JWT
|
||||
- AP_POSTGRES_DATABASE=activepieces
|
||||
- AP_POSTGRES_HOST=postgres
|
||||
- AP_POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- AP_POSTGRES_PORT=5432
|
||||
- AP_POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
|
||||
- AP_REDIS_HOST=redis
|
||||
- AP_REDIS_PORT=6379
|
||||
- AP_SANDBOX_RUN_TIME_SECONDS=600
|
||||
- AP_TELEMETRY_ENABLED=true
|
||||
- "AP_TEMPLATES_SOURCE_URL=https://cloud.activepieces.com/api/v1/flow-templates"
|
||||
- AP_TRIGGER_DEFAULT_POLL_INTERVAL=5
|
||||
- AP_WEBHOOK_TIMEOUT_SECONDS=30
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:3000"]
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
|
||||
sidekiq:
|
||||
image: chatwoot/chatwoot:latest
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
environment:
|
||||
- SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
|
||||
- FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
|
||||
- DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
|
||||
- FORCE_SSL=false
|
||||
- ENABLE_ACCOUNT_SIGNUP=false
|
||||
- REDIS_URL=redis://default@redis:6379
|
||||
- REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
|
||||
- REDIS_OPENSSL_VERIFY_MODE=none
|
||||
- POSTGRES_DATABASE=chatwoot
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
- RAILS_MAX_THREADS=5
|
||||
- NODE_ENV=production
|
||||
- RAILS_ENV=production
|
||||
- INSTALLATION_ENV=docker
|
||||
- MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
|
||||
- SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
|
||||
- SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
|
||||
- SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
|
||||
- SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
|
||||
- SMTP_PORT=${CHATWOOT_SMTP_PORT}
|
||||
- SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
|
||||
- SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
|
||||
- ACTIVE_STORAGE_SERVICE=local
|
||||
command: ["bundle", "exec", "sidekiq", "-C", "config/sidekiq.yml"]
|
||||
volumes:
|
||||
- sidekiq-data:/app/storage
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "bundle exec rails runner \'puts Sidekiq.redis(&:info)\' > /dev/null 2>&1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
postgres:
|
||||
image: postgres:12
|
||||
restart: always
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
image: "postgres:latest"
|
||||
environment:
|
||||
- POSTGRES_DB=chatwoot
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES_USER
|
||||
- POSTGRES_DB=activepieces
|
||||
- POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $SERVICE_USER_POSTGRES_USER -d chatwoot -h 127.0.0.1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
restart: always
|
||||
command: ["sh", "-c", "redis-server --requirepass \"$SERVICE_PASSWORD_REDIS\""]
|
||||
- POSTGRES_USER=$SERVICE_USER_POSTGRES
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
- "pg-data:/var/lib/postgresql/data"
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "PING"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
redis:
|
||||
image: "redis:latest"
|
||||
volumes:
|
||||
- "redis_data:/data"
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
|
||||
';
|
||||
|
||||
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"coolify": {
|
||||
"v4": {
|
||||
"version": "4.0.0-beta.331"
|
||||
},
|
||||
"nightly": {
|
||||
"version": "4.0.0-beta.332"
|
||||
},
|
||||
"nightly": {
|
||||
"version": "4.0.0-beta.333"
|
||||
},
|
||||
"helper": {
|
||||
"version": "1.0.0"
|
||||
"version": "1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user