Merge branch 'next' into improve-persist-ssh-sessions
This commit is contained in:
		
							
								
								
									
										5
									
								
								.github/workflows/coolify-helper-next.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/workflows/coolify-helper-next.yml
									
									
									
									
										vendored
									
									
								
							@@ -38,6 +38,8 @@ jobs:
 | 
				
			|||||||
          platforms: linux/amd64
 | 
					          platforms: linux/amd64
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
 | 
					          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next
 | 
				
			||||||
 | 
					          labels: |
 | 
				
			||||||
 | 
					            coolify.managed=true
 | 
				
			||||||
  aarch64:
 | 
					  aarch64:
 | 
				
			||||||
    runs-on: [ self-hosted, arm64 ]
 | 
					    runs-on: [ self-hosted, arm64 ]
 | 
				
			||||||
    permissions:
 | 
					    permissions:
 | 
				
			||||||
@@ -64,6 +66,8 @@ jobs:
 | 
				
			|||||||
          platforms: linux/aarch64
 | 
					          platforms: linux/aarch64
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
 | 
					          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64
 | 
				
			||||||
 | 
					          labels: |
 | 
				
			||||||
 | 
					            coolify.managed=true
 | 
				
			||||||
  merge-manifest:
 | 
					  merge-manifest:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    permissions:
 | 
					    permissions:
 | 
				
			||||||
@@ -94,3 +98,4 @@ jobs:
 | 
				
			|||||||
        if: always()
 | 
					        if: always()
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL  }}
 | 
					          webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL  }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								.github/workflows/coolify-helper.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/coolify-helper.yml
									
									
									
									
										vendored
									
									
								
							@@ -2,7 +2,7 @@ name: Coolify Helper Image (v4)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
on:
 | 
					on:
 | 
				
			||||||
  push:
 | 
					  push:
 | 
				
			||||||
    branches: [ "main" ]
 | 
					    branches: [ "main", "next" ]
 | 
				
			||||||
    paths:
 | 
					    paths:
 | 
				
			||||||
      - .github/workflows/coolify-helper.yml
 | 
					      - .github/workflows/coolify-helper.yml
 | 
				
			||||||
      - docker/coolify-helper/Dockerfile
 | 
					      - docker/coolify-helper/Dockerfile
 | 
				
			||||||
@@ -38,6 +38,8 @@ jobs:
 | 
				
			|||||||
          platforms: linux/amd64
 | 
					          platforms: linux/amd64
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
 | 
					          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}
 | 
				
			||||||
 | 
					          labels: |
 | 
				
			||||||
 | 
					            coolify.managed=true
 | 
				
			||||||
  aarch64:
 | 
					  aarch64:
 | 
				
			||||||
    runs-on: [ self-hosted, arm64 ]
 | 
					    runs-on: [ self-hosted, arm64 ]
 | 
				
			||||||
    permissions:
 | 
					    permissions:
 | 
				
			||||||
@@ -64,6 +66,8 @@ jobs:
 | 
				
			|||||||
          platforms: linux/aarch64
 | 
					          platforms: linux/aarch64
 | 
				
			||||||
          push: true
 | 
					          push: true
 | 
				
			||||||
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
 | 
					          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64
 | 
				
			||||||
 | 
					          labels: |
 | 
				
			||||||
 | 
					            coolify.managed=true
 | 
				
			||||||
  merge-manifest:
 | 
					  merge-manifest:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
    permissions:
 | 
					    permissions:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@ class CleanupDocker
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $commonCommands = [
 | 
					        $commonCommands = [
 | 
				
			||||||
            'docker container prune -f --filter "label=coolify.managed=true"',
 | 
					            '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',
 | 
					            'docker builder prune -af',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2864,6 +2864,7 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
 | 
				
			|||||||
        return collect($finalServices);
 | 
					        return collect($finalServices);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $preview_id = null): Collection
 | 
					function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $preview_id = null): Collection
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    $isApplication = $resource instanceof Application;
 | 
					    $isApplication = $resource instanceof Application;
 | 
				
			||||||
@@ -2920,6 +2921,178 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $parsedServices = collect([]);
 | 
					    $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) {
 | 
					    foreach ($services as $serviceName => $service) {
 | 
				
			||||||
        $image = data_get_str($service, 'image');
 | 
					        $image = data_get_str($service, 'image');
 | 
				
			||||||
        $restart = data_get_str($service, 'restart', RESTART_MODE);
 | 
					        $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', []));
 | 
					        $ports = collect(data_get($service, 'ports', []));
 | 
				
			||||||
        $buildArgs = collect(data_get($service, 'build.args', []));
 | 
					        $buildArgs = collect(data_get($service, 'build.args', []));
 | 
				
			||||||
        $environment = $environment->merge($buildArgs);
 | 
					        $environment = $environment->merge($buildArgs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $environment = convertComposeEnvironmentToArray($environment);
 | 
				
			||||||
 | 
					        $coolifyEnvironments = collect([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $isDatabase = isDatabaseImage(data_get_str($service, 'image'));
 | 
					        $isDatabase = isDatabaseImage(data_get_str($service, 'image'));
 | 
				
			||||||
        $volumesParsed = collect([]);
 | 
					        $volumesParsed = collect([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3069,10 +3246,10 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
                    if ($topLevel->get('volumes')->has($source->value())) {
 | 
					                    if ($topLevel->get('volumes')->has($source->value())) {
 | 
				
			||||||
                        $temp = $topLevel->get('volumes')->get($source->value());
 | 
					                        $temp = $topLevel->get('volumes')->get($source->value());
 | 
				
			||||||
                        if (data_get($temp, 'driver_opts.type') === 'cifs') {
 | 
					                        if (data_get($temp, 'driver_opts.type') === 'cifs') {
 | 
				
			||||||
                            return $volume;
 | 
					                            continue;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        if (data_get($temp, 'driver_opts.type') === 'nfs') {
 | 
					                        if (data_get($temp, 'driver_opts.type') === 'nfs') {
 | 
				
			||||||
                            return $volume;
 | 
					                            continue;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $slugWithoutUuid = Str::slug($source, '-');
 | 
					                    $slugWithoutUuid = Str::slug($source, '-');
 | 
				
			||||||
@@ -3204,176 +3381,48 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
                ]);
 | 
					                ]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // convert environment variables to one format
 | 
					 | 
				
			||||||
        $environment = convertComposeEnvironmentToArray($environment);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Add Coolify defined environments
 | 
					        $normalEnvironments = $environment->diffKeys($allMagicEnvironments);
 | 
				
			||||||
        $allEnvironments = $resource->environment_variables()->get(['key', 'value']);
 | 
					        $normalEnvironments = $normalEnvironments->filter(function ($value, $key) {
 | 
				
			||||||
 | 
					            return ! str($value)->startsWith('SERVICE_');
 | 
				
			||||||
        $allEnvironments = $allEnvironments->mapWithKeys(function ($item) {
 | 
					 | 
				
			||||||
            return [$item['key'] => $item['value']];
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // remove $environment from $allEnvironments
 | 
					        foreach ($normalEnvironments as $key => $value) {
 | 
				
			||||||
        $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);
 | 
					            $key = str($key);
 | 
				
			||||||
                $value = str(replaceVariables(str($value)));
 | 
					            $value = str($value);
 | 
				
			||||||
                $originalValue = $value;
 | 
					            $parsedValue = str(replaceVariables(str($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 ($key->value() === $parsedValue->value()) {
 | 
				
			||||||
                    if ($isApplication) {
 | 
					                $value = null;
 | 
				
			||||||
                        $fqdn = generateFqdn($server, "{$resource->name}-{$uuid}");
 | 
					                $resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
 | 
				
			||||||
                    } elseif ($isService) {
 | 
					                    'key' => $key,
 | 
				
			||||||
                        $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,
 | 
					                    $nameOfId => $resource->id,
 | 
				
			||||||
                ], [
 | 
					                ], [
 | 
				
			||||||
                    'value' => $value,
 | 
					                    'value' => $value,
 | 
				
			||||||
                    'is_build_time' => false,
 | 
					                    'is_build_time' => false,
 | 
				
			||||||
                    'is_preview' => false,
 | 
					                    'is_preview' => false,
 | 
				
			||||||
                ]);
 | 
					                ]);
 | 
				
			||||||
                }
 | 
					            } else {
 | 
				
			||||||
                // Save the original value to the environment variables
 | 
					                if ($value->startsWith('$')) {
 | 
				
			||||||
                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(':-')) {
 | 
					                    if ($value->contains(':-')) {
 | 
				
			||||||
 | 
					                        $value = str(replaceVariables(str($value)));
 | 
				
			||||||
                        $key = $value->before(':');
 | 
					                        $key = $value->before(':');
 | 
				
			||||||
                        $value = $value->after(':-');
 | 
					                        $value = $value->after(':-');
 | 
				
			||||||
                    } elseif ($value->contains('-')) {
 | 
					                    } elseif ($value->contains('-')) {
 | 
				
			||||||
 | 
					                        $value = str(replaceVariables(str($value)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        $key = $value->before('-');
 | 
					                        $key = $value->before('-');
 | 
				
			||||||
                        $value = $value->after('-');
 | 
					                        $value = $value->after('-');
 | 
				
			||||||
                    } elseif ($value->contains(':?')) {
 | 
					                    } elseif ($value->contains(':?')) {
 | 
				
			||||||
 | 
					                        $value = str(replaceVariables(str($value)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        $key = $value->before(':');
 | 
					                        $key = $value->before(':');
 | 
				
			||||||
                        $value = $value->after(':?');
 | 
					                        $value = $value->after(':?');
 | 
				
			||||||
                    } elseif ($value->contains('?')) {
 | 
					                    } elseif ($value->contains('?')) {
 | 
				
			||||||
 | 
					                        $value = str(replaceVariables(str($value)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        $key = $value->before('?');
 | 
					                        $key = $value->before('?');
 | 
				
			||||||
                        $value = $value->after('?');
 | 
					                        $value = $value->after('?');
 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    $key = $value;
 | 
					 | 
				
			||||||
                    $value = null;
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
 | 
					                    $resource->environment_variables()->where('key', $key)->where($nameOfId, $resource->id)->firstOrCreate([
 | 
				
			||||||
                        'key' => $key,
 | 
					                        'key' => $key,
 | 
				
			||||||
@@ -3384,6 +3433,8 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
                        'is_preview' => false,
 | 
					                        'is_preview' => false,
 | 
				
			||||||
                    ]);
 | 
					                    ]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($isApplication) {
 | 
					        if ($isApplication) {
 | 
				
			||||||
            $branch = $originalResource->git_branch;
 | 
					            $branch = $originalResource->git_branch;
 | 
				
			||||||
@@ -3391,13 +3442,13 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
                $branch = "pull/{$pullRequestId}/head";
 | 
					                $branch = "pull/{$pullRequestId}/head";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if ($originalResource->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
 | 
					            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
 | 
					        // Add COOLIFY_CONTAINER_NAME to environment
 | 
				
			||||||
        if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
 | 
					        if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) {
 | 
				
			||||||
            $environment->put('COOLIFY_CONTAINER_NAME', $containerName);
 | 
					            $coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', $containerName);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($isApplication) {
 | 
					        if ($isApplication) {
 | 
				
			||||||
@@ -3451,15 +3502,20 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        // Add COOLIFY_FQDN & COOLIFY_URL to environment
 | 
					        // Add COOLIFY_FQDN & COOLIFY_URL to environment
 | 
				
			||||||
        if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
 | 
					        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) {
 | 
					            $urls = $fqdns->map(function ($fqdn) {
 | 
				
			||||||
                return str($fqdn)->replace('http://', '')->replace('https://', '');
 | 
					                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);
 | 
					        $serviceLabels = $labels->merge($defaultLabels);
 | 
				
			||||||
        if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
 | 
					        if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) {
 | 
				
			||||||
            if ($isApplication) {
 | 
					            if ($isApplication) {
 | 
				
			||||||
@@ -3554,8 +3610,8 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int
 | 
				
			|||||||
        if ($volumesParsed->count() > 0) {
 | 
					        if ($volumesParsed->count() > 0) {
 | 
				
			||||||
            $payload['volumes'] = $volumesParsed;
 | 
					            $payload['volumes'] = $volumesParsed;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($environment->count() > 0 || $coolifyDefinedEnvironments->count() > 0) {
 | 
					        if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) {
 | 
				
			||||||
            $payload['environment'] = $environment->merge($coolifyDefinedEnvironments);
 | 
					            $payload['environment'] = $environment->merge($coolifyEnvironments);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($logging) {
 | 
					        if ($logging) {
 | 
				
			||||||
            $payload['logging'] = $logging;
 | 
					            $payload['logging'] = $logging;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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.331',
 | 
					    'release' => '4.0.0-beta.332',
 | 
				
			||||||
    // 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.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:
 | 
					    environment:
 | 
				
			||||||
      - SERVICE_FQDN_PLUNK_3000
 | 
					      - SERVICE_FQDN_PLUNK_3000
 | 
				
			||||||
      - REDIS_URL=redis://redis:6379
 | 
					      - 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}
 | 
					      - JWT_SECRET=${SERVICE_PASSWORD_JWT_SECRET}
 | 
				
			||||||
      - AWS_REGION=${AWS_REGION}
 | 
					      - AWS_REGION=${AWS_REGION}
 | 
				
			||||||
      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
 | 
					      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -88,114 +88,61 @@ networks:
 | 
				
			|||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
    $this->serviceYaml = '
 | 
					    $this->serviceYaml = '
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
  chatwoot:
 | 
					  activepieces:
 | 
				
			||||||
    image: chatwoot/chatwoot:latest
 | 
					    image: "ghcr.io/activepieces/activepieces:latest"
 | 
				
			||||||
    depends_on:
 | 
					 | 
				
			||||||
      - postgres
 | 
					 | 
				
			||||||
      - redis
 | 
					 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
      - SERVICE_FQDN_CHATWOOT_3000
 | 
					      - SERVICE_FQDN_ACTIVEPIECES
 | 
				
			||||||
      - SECRET_KEY_BASE=$SERVICE_PASSWORD_CHATWOOT
 | 
					      - AP_API_KEY=$SERVICE_PASSWORD_64_APIKEY
 | 
				
			||||||
      - FRONTEND_URL=${SERVICE_FQDN_CHATWOOT}
 | 
					      - AP_ENCRYPTION_KEY=$SERVICE_PASSWORD_ENCRYPTIONKEY
 | 
				
			||||||
      - DEFAULT_LOCALE=${CHATWOOT_DEFAULT_LOCALE}
 | 
					      - AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js
 | 
				
			||||||
      - FORCE_SSL=false
 | 
					      - AP_ENVIRONMENT=prod
 | 
				
			||||||
      - ENABLE_ACCOUNT_SIGNUP=false
 | 
					      - AP_EXECUTION_MODE=UNSANDBOXED
 | 
				
			||||||
      - REDIS_URL=redis://default@redis:6379
 | 
					      - AP_FRONTEND_URL=$SERVICE_FQDN_ACTIVEPIECES
 | 
				
			||||||
      - REDIS_PASSWORD=$SERVICE_PASSWORD_REDIS
 | 
					      - AP_JWT_SECRET=$SERVICE_PASSWORD_64_JWT
 | 
				
			||||||
      - REDIS_OPENSSL_VERIFY_MODE=none
 | 
					      - AP_POSTGRES_DATABASE=activepieces
 | 
				
			||||||
      - POSTGRES_DATABASE=chatwoot
 | 
					      - AP_POSTGRES_HOST=postgres
 | 
				
			||||||
      - POSTGRES_HOST=postgres
 | 
					      - AP_POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
 | 
				
			||||||
      - POSTGRES_USERNAME=$SERVICE_USER_POSTGRES_USER
 | 
					      - AP_POSTGRES_PORT=5432
 | 
				
			||||||
      - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
 | 
					      - AP_POSTGRES_USERNAME=$SERVICE_USER_POSTGRES
 | 
				
			||||||
      - RAILS_MAX_THREADS=5
 | 
					      - AP_REDIS_HOST=redis
 | 
				
			||||||
      - NODE_ENV=production
 | 
					      - AP_REDIS_PORT=6379
 | 
				
			||||||
      - RAILS_ENV=production
 | 
					      - AP_SANDBOX_RUN_TIME_SECONDS=600
 | 
				
			||||||
      - INSTALLATION_ENV=docker
 | 
					      - AP_TELEMETRY_ENABLED=true
 | 
				
			||||||
      - MAILER_SENDER_EMAIL=${CHATWOOT_MAILER_SENDER_EMAIL}
 | 
					      - "AP_TEMPLATES_SOURCE_URL=https://cloud.activepieces.com/api/v1/flow-templates"
 | 
				
			||||||
      - SMTP_ADDRESS=${CHATWOOT_SMTP_ADDRESS}
 | 
					      - AP_TRIGGER_DEFAULT_POLL_INTERVAL=5
 | 
				
			||||||
      - SMTP_AUTHENTICATION=${CHATWOOT_SMTP_AUTHENTICATION}
 | 
					      - AP_WEBHOOK_TIMEOUT_SECONDS=30
 | 
				
			||||||
      - SMTP_DOMAIN=${CHATWOOT_SMTP_DOMAIN}
 | 
					    depends_on:
 | 
				
			||||||
      - SMTP_ENABLE_STARTTLS_AUTO=${CHATWOOT_SMTP_ENABLE_STARTTLS_AUTO}
 | 
					      postgres:
 | 
				
			||||||
      - SMTP_PORT=${CHATWOOT_SMTP_PORT}
 | 
					        condition: service_healthy
 | 
				
			||||||
      - SMTP_USERNAME=${CHATWOOT_SMTP_USERNAME}
 | 
					      redis:
 | 
				
			||||||
      - SMTP_PASSWORD=${CHATWOOT_SMTP_PASSWORD}
 | 
					        condition: service_started
 | 
				
			||||||
      - 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
 | 
					 | 
				
			||||||
    healthcheck:
 | 
					    healthcheck:
 | 
				
			||||||
      test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:3000"]
 | 
					      test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
 | 
				
			||||||
      interval: 5s
 | 
					      interval: 5s
 | 
				
			||||||
      timeout: 20s
 | 
					      timeout: 20s
 | 
				
			||||||
      retries: 10
 | 
					      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:
 | 
					  postgres:
 | 
				
			||||||
    image: postgres:12
 | 
					    image: "postgres:latest"
 | 
				
			||||||
    restart: always
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - postgres-data:/var/lib/postgresql/data
 | 
					 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
      - POSTGRES_DB=chatwoot
 | 
					      - POSTGRES_DB=activepieces
 | 
				
			||||||
      - POSTGRES_USER=$SERVICE_USER_POSTGRES_USER
 | 
					 | 
				
			||||||
      - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
 | 
					      - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES
 | 
				
			||||||
    healthcheck:
 | 
					      - POSTGRES_USER=$SERVICE_USER_POSTGRES
 | 
				
			||||||
      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\""]
 | 
					 | 
				
			||||||
    volumes:
 | 
					    volumes:
 | 
				
			||||||
      - redis-data:/data
 | 
					      - "pg-data:/var/lib/postgresql/data"
 | 
				
			||||||
    healthcheck:
 | 
					    healthcheck:
 | 
				
			||||||
      test: ["CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "PING"]
 | 
					      test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
 | 
				
			||||||
      interval: 30s
 | 
					      interval: 5s
 | 
				
			||||||
      timeout: 10s
 | 
					      timeout: 20s
 | 
				
			||||||
      retries: 5
 | 
					      retries: 10
 | 
				
			||||||
 | 
					  redis:
 | 
				
			||||||
 | 
					    image: "redis:latest"
 | 
				
			||||||
 | 
					    volumes:
 | 
				
			||||||
 | 
					      - "redis_data:/data"
 | 
				
			||||||
 | 
					    healthcheck:
 | 
				
			||||||
 | 
					      test: ["CMD", "redis-cli", "ping"]
 | 
				
			||||||
 | 
					      interval: 5s
 | 
				
			||||||
 | 
					      timeout: 20s
 | 
				
			||||||
 | 
					      retries: 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
';
 | 
					';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,13 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    "coolify": {
 | 
					    "coolify": {
 | 
				
			||||||
        "v4": {
 | 
					        "v4": {
 | 
				
			||||||
            "version": "4.0.0-beta.331"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "nightly": {
 | 
					 | 
				
			||||||
            "version": "4.0.0-beta.332"
 | 
					            "version": "4.0.0-beta.332"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "nightly": {
 | 
				
			||||||
 | 
					            "version": "4.0.0-beta.333"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "helper": {
 | 
					        "helper": {
 | 
				
			||||||
            "version": "1.0.0"
 | 
					            "version": "1.0.1"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user