2023-09-20 13:42:41 +00:00
< ? php
namespace App\Models ;
2025-06-24 10:52:22 +00:00
use App\Enums\ProcessStatus ;
2025-11-20 14:03:18 +00:00
use App\Services\ContainerStatusAggregator ;
2026-09-02 17:39:19 +00:00
use App\Support\DomainPortOverrides ;
2025-09-19 08:17:48 +00:00
use App\Traits\ClearsGlobalSearchCache ;
2025-08-19 10:14:48 +00:00
use App\Traits\HasSafeStringAttribute ;
2024-08-05 13:48:15 +00:00
use Illuminate\Database\Eloquent\Casts\Attribute ;
2023-09-20 13:42:41 +00:00
use Illuminate\Database\Eloquent\Factories\HasFactory ;
use Illuminate\Database\Eloquent\Relations\HasMany ;
2023-12-08 17:32:08 +00:00
use Illuminate\Database\Eloquent\SoftDeletes ;
2023-09-20 13:42:41 +00:00
use Illuminate\Support\Collection ;
2024-09-03 09:47:30 +00:00
use Illuminate\Support\Facades\Storage ;
2024-07-09 11:30:13 +00:00
use OpenApi\Attributes as OA ;
2025-06-24 10:52:22 +00:00
use Spatie\Activitylog\Models\Activity ;
2026-03-28 11:32:57 +00:00
use Symfony\Component\Yaml\Yaml ;
2023-09-20 13:42:41 +00:00
2024-07-09 11:30:13 +00:00
#[OA\Schema(
description : 'Service model' ,
type : 'object' ,
properties : [
2024-07-09 11:59:54 +00:00
'id' => [ 'type' => 'integer' , 'description' => 'The unique identifier of the service. Only used for database identification.' ],
'uuid' => [ 'type' => 'string' , 'description' => 'The unique identifier of the service.' ],
'name' => [ 'type' => 'string' , 'description' => 'The name of the service.' ],
'environment_id' => [ 'type' => 'integer' , 'description' => 'The unique identifier of the environment where the service is attached to.' ],
'server_id' => [ 'type' => 'integer' , 'description' => 'The unique identifier of the server where the service is running.' ],
'description' => [ 'type' => 'string' , 'description' => 'The description of the service.' ],
'docker_compose_raw' => [ 'type' => 'string' , 'description' => 'The raw docker-compose.yml file of the service.' ],
'docker_compose' => [ 'type' => 'string' , 'description' => 'The docker-compose.yml file that is parsed and modified by Coolify.' ],
2024-08-26 10:23:03 +00:00
'destination_type' => [ 'type' => 'string' , 'description' => 'Destination type.' ],
2024-07-09 11:59:54 +00:00
'destination_id' => [ 'type' => 'integer' , 'description' => 'The unique identifier of the destination where the service is running.' ],
'connect_to_docker_network' => [ 'type' => 'boolean' , 'description' => 'The flag to connect the service to the predefined Docker network.' ],
'is_container_label_escape_enabled' => [ 'type' => 'boolean' , 'description' => 'The flag to enable the container label escape.' ],
2024-07-17 12:52:40 +00:00
'is_container_label_readonly_enabled' => [ 'type' => 'boolean' , 'description' => 'The flag to enable the container label readonly.' ],
2024-07-09 11:59:54 +00:00
'config_hash' => [ 'type' => 'string' , 'description' => 'The hash of the service configuration.' ],
'service_type' => [ 'type' => 'string' , 'description' => 'The type of the service.' ],
'created_at' => [ 'type' => 'string' , 'description' => 'The date and time when the service was created.' ],
'updated_at' => [ 'type' => 'string' , 'description' => 'The date and time when the service was last updated.' ],
'deleted_at' => [ 'type' => 'string' , 'description' => 'The date and time when the service was deleted.' ],
2024-07-09 11:30:13 +00:00
],
)]
2023-09-20 13:42:41 +00:00
class Service extends BaseModel
{
2025-09-19 08:17:48 +00:00
use ClearsGlobalSearchCache , HasFactory , HasSafeStringAttribute , SoftDeletes ;
2024-06-10 20:43:34 +00:00
2025-08-04 08:46:59 +00:00
private static $parserVersion = '5' ;
2024-08-28 13:45:11 +00:00
2026-03-28 11:32:57 +00:00
protected $fillable = [
2026-03-31 11:45:31 +00:00
'uuid' ,
2026-03-28 11:32:57 +00:00
'name' ,
'description' ,
'docker_compose_raw' ,
'docker_compose' ,
'connect_to_docker_network' ,
'service_type' ,
'config_hash' ,
'compose_parsing_version' ,
2026-03-30 06:11:23 +00:00
'is_container_label_escape_enabled' ,
2026-03-31 11:45:31 +00:00
'environment_id' ,
'server_id' ,
'destination_id' ,
'destination_type' ,
2026-03-28 11:32:57 +00:00
];
2024-04-12 10:44:49 +00:00
2024-12-13 11:03:05 +00:00
protected $appends = [ 'server_status' , 'status' ];
2024-08-05 13:48:15 +00:00
2026-04-30 09:28:06 +00:00
/**
* Sensitive fields hidden by default in serialized output ( toArray / toJson ) .
* API controllers should call makeVisible ([ ... ]) for callers with the
* `read:sensitive` or `root` token ability . Internal compose generators
* must makeVisible explicitly before toArray () .
*/
protected $hidden = [
'docker_compose' ,
'docker_compose_raw' ,
];
2024-08-27 14:02:52 +00:00
protected static function booted ()
{
2025-03-21 10:31:17 +00:00
static :: creating ( function ( $service ) {
if ( blank ( $service -> name )) {
2026-06-04 09:03:06 +00:00
$service -> name = 'service-' . new_public_id ();
2025-03-21 10:31:17 +00:00
}
});
2024-08-27 14:02:52 +00:00
static :: created ( function ( $service ) {
2024-08-28 13:45:11 +00:00
$service -> compose_parsing_version = self :: $parserVersion ;
2024-08-27 14:02:52 +00:00
$service -> save ();
});
}
2024-04-12 10:44:49 +00:00
public function isConfigurationChanged ( bool $save = false )
{
2026-09-02 17:39:19 +00:00
$applications = $this -> applications () -> get ();
$domains = $applications -> pluck ( 'fqdn' ) -> sort () -> toArray ();
2024-04-12 10:44:49 +00:00
$domains = implode ( ',' , $domains );
2026-09-02 17:39:19 +00:00
$noindexDomains = $applications -> pluck ( 'noindex_domains' ) -> flatten () -> filter () -> sort () -> implode ( ',' );
$domainPortOverrides = $applications
-> mapWithKeys ( fn ( ServiceApplication $application ) : array => [
$application -> id => DomainPortOverrides :: sorted ( $application -> domain_port_overrides ),
])
-> sortKeys ()
-> all ();
$applicationImages = $applications -> pluck ( 'image' ) -> sort ();
2024-04-15 13:45:50 +00:00
$databaseImages = $this -> databases () -> get () -> pluck ( 'image' ) -> sort ();
2024-04-12 10:44:49 +00:00
$images = $applicationImages -> merge ( $databaseImages );
$images = implode ( ',' , $images -> toArray ());
2024-04-15 13:45:50 +00:00
$applicationStorages = $this -> applications () -> get () -> pluck ( 'persistentStorages' ) -> flatten () -> sortBy ( 'id' );
$databaseStorages = $this -> databases () -> get () -> pluck ( 'persistentStorages' ) -> flatten () -> sortBy ( 'id' );
2024-04-12 10:44:49 +00:00
$storages = $applicationStorages -> merge ( $databaseStorages ) -> implode ( 'updated_at' );
2026-09-02 17:39:19 +00:00
$newConfigHash = $images . $domains . $images . $storages . $noindexDomains . json_encode ( $domainPortOverrides );
2026-07-07 10:53:34 +00:00
$newConfigHash .= json_encode ( $this -> environment_variables () -> get ( 'value' ) -> makeVisible ( 'value' ) -> sort ());
2024-04-12 10:44:49 +00:00
$newConfigHash = md5 ( $newConfigHash );
$oldConfigHash = data_get ( $this , 'config_hash' );
if ( $oldConfigHash === null ) {
if ( $save ) {
$this -> config_hash = $newConfigHash ;
$this -> save ();
}
2024-06-10 20:43:34 +00:00
2024-04-12 10:44:49 +00:00
return true ;
}
if ( $oldConfigHash === $newConfigHash ) {
return false ;
2025-01-07 14:31:43 +00:00
} else {
if ( $save ) {
$this -> config_hash = $newConfigHash ;
$this -> save ();
}
2025-01-07 13:52:08 +00:00
2025-01-07 14:31:43 +00:00
return true ;
}
2024-04-12 10:44:49 +00:00
}
2024-06-10 20:43:34 +00:00
2024-08-05 13:48:15 +00:00
protected function serverStatus () : Attribute
{
return Attribute :: make (
get : function () {
return $this -> server -> isFunctional ();
}
);
}
2024-08-01 11:47:58 +00:00
public function isRunning ()
{
2024-12-13 11:03:05 +00:00
return ( bool ) str ( $this -> status ) -> contains ( 'running' );
2024-08-01 11:47:58 +00:00
}
2024-04-12 10:44:49 +00:00
public function isExited ()
{
2024-12-13 11:03:05 +00:00
return ( bool ) str ( $this -> status ) -> contains ( 'exited' );
2024-04-12 10:44:49 +00:00
}
2024-06-10 20:43:34 +00:00
2025-06-24 10:52:22 +00:00
public function isStarting () : bool
{
try {
$activity = Activity :: where ( 'properties->type_uuid' , $this -> uuid ) -> latest () -> first ();
$status = data_get ( $activity , 'properties.status' );
return $status === ProcessStatus :: QUEUED -> value || $status === ProcessStatus :: IN_PROGRESS -> value ;
} catch ( \Throwable ) {
return false ;
}
}
2023-09-22 09:23:49 +00:00
public function type ()
2023-09-20 13:42:41 +00:00
{
2023-09-22 09:23:49 +00:00
return 'service' ;
2023-09-20 13:42:41 +00:00
}
2024-06-10 20:43:34 +00:00
2024-02-03 11:39:07 +00:00
public function project ()
{
return data_get ( $this , 'environment.project' );
}
2024-06-10 20:43:34 +00:00
2024-01-23 16:13:23 +00:00
public function team ()
{
return data_get ( $this , 'environment.project.team' );
}
2024-06-10 20:43:34 +00:00
2024-02-02 10:50:28 +00:00
public function tags ()
{
return $this -> morphToMany ( Tag :: class , 'taggable' );
}
2024-06-10 20:43:34 +00:00
2025-12-08 12:39:33 +00:00
/**
* Get query builder for services owned by current team .
* If you need all services without further query chaining , use ownedByCurrentTeamCached () instead .
*/
2024-11-07 10:09:38 +00:00
public static function ownedByCurrentTeam ()
{
2025-01-07 14:31:43 +00:00
return Service :: whereRelation ( 'environment.project.team' , 'id' , currentTeam () -> id ) -> orderBy ( 'name' );
2024-11-07 10:09:38 +00:00
}
2025-12-08 12:39:33 +00:00
/**
* Get all services owned by current team ( cached for request duration ) .
*/
public static function ownedByCurrentTeamCached ()
{
return once ( function () {
return Service :: ownedByCurrentTeam () -> get ();
});
}
2025-04-30 16:30:43 +00:00
public function deleteConfigurations ()
2024-04-12 08:54:25 +00:00
{
2024-08-09 01:00:30 +00:00
$server = data_get ( $this , 'destination.server' );
2024-04-12 08:54:25 +00:00
$workdir = $this -> workdir ();
if ( str ( $workdir ) -> endsWith ( $this -> uuid )) {
2024-09-23 17:51:31 +00:00
instant_remote_process ([ 'rm -rf ' . $this -> workdir ()], $server , false );
2024-04-12 08:54:25 +00:00
}
}
2024-06-10 20:43:34 +00:00
2025-04-30 16:30:43 +00:00
public function deleteConnectedNetworks ()
2024-08-09 01:00:30 +00:00
{
$server = data_get ( $this , 'destination.server' );
2025-04-30 16:30:43 +00:00
instant_remote_process ([ " docker network disconnect { $this -> uuid } coolify-proxy " ], $server , false );
instant_remote_process ([ " docker network rm { $this -> uuid } " ], $server , false );
2024-08-09 01:00:30 +00:00
}
2025-11-20 14:03:18 +00:00
/**
* Calculate the service ' s aggregate status from its applications and databases .
*
* This method aggregates status from Eloquent model relationships ( not Docker containers ) .
* It differs from the CalculatesExcludedStatus trait which works with Docker container objects
* during container inspection . This accessor runs on - demand for UI display and works with
* already - stored status strings from the database .
*
* Status format : " { status}: { health} " or " { status}: { health}:excluded "
* - Status values : running , exited , degraded , starting , paused , restarting
* - Health values : healthy , unhealthy , unknown
* - : excluded suffix : Indicates all containers are excluded from health monitoring
*
* @ return string The aggregate status in format " status:health " or " status:health:excluded "
*/
2024-12-13 11:03:05 +00:00
public function getStatusAttribute ()
2024-02-23 09:09:42 +00:00
{
2025-06-24 10:52:22 +00:00
if ( $this -> isStarting ()) {
return 'starting:unhealthy' ;
}
2024-02-16 20:56:38 +00:00
$applications = $this -> applications ;
$databases = $this -> databases ;
2024-02-23 09:09:42 +00:00
2025-11-20 14:03:18 +00:00
[ $complexStatus , $complexHealth , $hasNonExcluded ] = $this -> aggregateResourceStatuses (
$applications ,
$databases ,
excludedOnly : false
);
2024-02-23 09:09:42 +00:00
2025-11-20 14:03:18 +00:00
// If all services are excluded from status checks, calculate status from excluded containers
// but mark it with :excluded to indicate monitoring is disabled
if ( ! $hasNonExcluded && ( $complexStatus === null && $complexHealth === null )) {
[ $excludedStatus , $excludedHealth ] = $this -> aggregateResourceStatuses (
$applications ,
$databases ,
excludedOnly : true
);
2025-11-19 12:19:25 +00:00
2025-11-20 14:03:18 +00:00
// Return status with :excluded suffix to indicate monitoring is disabled
if ( $excludedStatus && $excludedHealth ) {
return " { $excludedStatus } : { $excludedHealth } :excluded " ;
2025-11-19 12:19:25 +00:00
}
2025-11-20 14:03:18 +00:00
// If no status was calculated at all (no containers exist), return unknown
if ( $excludedStatus === null && $excludedHealth === null ) {
return 'unknown:unknown:excluded' ;
2024-02-16 20:56:38 +00:00
}
2025-11-20 14:03:18 +00:00
2025-11-24 08:09:08 +00:00
return 'exited' ;
}
// If health is null/empty, return just the status without trailing colon
if ( $complexHealth === null || $complexHealth === '' ) {
return $complexStatus ;
2024-02-16 20:56:38 +00:00
}
2025-11-19 12:19:25 +00:00
2025-11-20 14:03:18 +00:00
return " { $complexStatus } : { $complexHealth } " ;
}
2025-11-19 12:19:25 +00:00
2025-11-20 14:03:18 +00:00
/**
* Aggregate status and health from collections of applications and databases .
*
* This helper method consolidates status aggregation logic using ContainerStatusAggregator .
* It processes container status strings stored in the database ( not live Docker data ) .
*
* @ param \Illuminate\Database\Eloquent\Collection $applications Collection of Application models
* @ param \Illuminate\Database\Eloquent\Collection $databases Collection of Database models
* @ param bool $excludedOnly If true , only process excluded containers ; if false , only process non - excluded
* @ return array { 0 : string | null , 1 : string | null , 2 ? : bool } [ status , health , hasNonExcluded ( only when excludedOnly = false )]
*/
private function aggregateResourceStatuses ( $applications , $databases , bool $excludedOnly = false ) : array
{
$hasNonExcluded = false ;
$statusStrings = collect ();
// Process both applications and databases using the same logic
$resources = $applications -> concat ( $databases );
foreach ( $resources as $resource ) {
$isExcluded = $resource -> exclude_from_status || str ( $resource -> status ) -> contains ( ':excluded' );
// Filter based on excludedOnly flag
if ( $excludedOnly && ! $isExcluded ) {
2024-02-23 09:09:42 +00:00
continue ;
}
2025-11-20 14:03:18 +00:00
if ( ! $excludedOnly && $isExcluded ) {
continue ;
2024-02-16 20:56:38 +00:00
}
2024-06-10 20:43:34 +00:00
2025-11-20 14:03:18 +00:00
if ( ! $excludedOnly ) {
$hasNonExcluded = true ;
2025-11-19 09:54:51 +00:00
}
2025-11-20 14:03:18 +00:00
// Strip :excluded suffix before aggregation (it's in the 3rd part of "status:health:excluded")
$status = str ( $resource -> status ) -> before ( ':excluded' ) -> toString ();
$statusStrings -> push ( $status );
}
2025-11-19 09:54:51 +00:00
2025-11-20 14:03:18 +00:00
// If no status strings collected, return nulls
if ( $statusStrings -> isEmpty ()) {
return $excludedOnly ? [ null , null ] : [ null , null , $hasNonExcluded ];
}
2025-11-19 09:54:51 +00:00
2025-11-20 14:03:18 +00:00
// Use ContainerStatusAggregator service for state machine logic
$aggregator = new ContainerStatusAggregator ;
$aggregatedStatus = $aggregator -> aggregateFromStrings ( $statusStrings );
2025-11-19 09:54:51 +00:00
2025-11-20 14:03:18 +00:00
// Parse the aggregated "status:health" string
$parts = explode ( ':' , $aggregatedStatus );
$status = $parts [ 0 ] ? ? null ;
$health = $parts [ 1 ] ? ? null ;
if ( $excludedOnly ) {
return [ $status , $health ];
2025-11-18 22:24:11 +00:00
}
2025-11-20 14:03:18 +00:00
return [ $status , $health , $hasNonExcluded ];
2024-02-16 20:56:38 +00:00
}
2024-06-10 20:43:34 +00:00
2023-11-13 10:09:21 +00:00
public function extraFields ()
{
$fields = collect ([]);
$applications = $this -> applications () -> get ();
foreach ( $applications as $application ) {
2024-10-07 09:19:14 +00:00
$image = str ( $application -> image ) -> before ( ':' );
if ( $image -> isEmpty ()) {
continue ;
}
2023-11-13 10:09:21 +00:00
switch ( $image ) {
2025-08-11 09:43:59 +00:00
case $image -> contains ( 'drizzle-team/gateway' ) :
$data = collect ([]);
$masterpass = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_DRIZZLE' ) -> first ();
$data = $data -> merge ([
'Master Password' => [
'key' => data_get ( $masterpass , 'key' ),
'value' => data_get ( $masterpass , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
$fields -> put ( 'Drizzle' , $data -> toArray ());
break ;
2024-10-10 11:28:42 +00:00
case $image -> contains ( 'castopod' ) :
$data = collect ([]);
$disable_https = $this -> environment_variables () -> where ( 'key' , 'CP_DISABLE_HTTPS' ) -> first ();
if ( $disable_https ) {
$data = $data -> merge ([
'Disable HTTPS' => [
'key' => 'CP_DISABLE_HTTPS' ,
'value' => data_get ( $disable_https , 'value' ),
'rules' => 'required' ,
2024-10-17 20:08:23 +00:00
'customHelper' => 'If you want to use https, set this to 0. Variable name: CP_DISABLE_HTTPS' ,
2024-10-10 11:28:42 +00:00
],
]);
}
$fields -> put ( 'Castopod' , $data -> toArray ());
break ;
2024-10-07 09:54:54 +00:00
case $image -> contains ( 'label-studio' ) :
$data = collect ([]);
$username = $this -> environment_variables () -> where ( 'key' , 'LABEL_STUDIO_USERNAME' ) -> first ();
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_LABELSTUDIO' ) -> first ();
if ( $username ) {
$data = $data -> merge ([
'Username' => [
'key' => 'LABEL_STUDIO_USERNAME' ,
'value' => data_get ( $username , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $password ) {
$data = $data -> merge ([
'Password' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $password , 'key' ),
2024-10-07 09:54:54 +00:00
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Label Studio' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'litellm' ) :
$data = collect ([]);
$username = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_UI' ) -> first ();
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_UI' ) -> first ();
if ( $username ) {
$data = $data -> merge ([
'Username' => [
'key' => data_get ( $username , 'key' ),
'value' => data_get ( $username , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Litellm' , $data -> toArray ());
break ;
case $image -> contains ( 'langfuse' ) :
$data = collect ([]);
$email = $this -> environment_variables () -> where ( 'key' , 'LANGFUSE_INIT_USER_EMAIL' ) -> first ();
if ( $email ) {
$data = $data -> merge ([
'Admin Email' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $email , 'key' ),
2024-10-07 09:19:14 +00:00
'value' => data_get ( $email , 'value' ),
'rules' => 'required|email' ,
],
]);
}
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_LANGFUSE' ) -> first ();
if ( $password ) {
$data = $data -> merge ([
'Admin Password' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $password , 'key' ),
2024-10-07 09:19:14 +00:00
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Langfuse' , $data -> toArray ());
break ;
case $image -> contains ( 'invoiceninja' ) :
2024-10-05 12:16:53 +00:00
$data = collect ([]);
$email = $this -> environment_variables () -> where ( 'key' , 'IN_USER_EMAIL' ) -> first ();
$data = $data -> merge ([
'Email' => [
2024-10-10 11:13:44 +00:00
'key' => data_get ( $email , 'key' ),
2024-10-05 12:16:53 +00:00
'value' => data_get ( $email , 'value' ),
'rules' => 'required|email' ,
],
]);
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_INVOICENINJAUSER' ) -> first ();
$data = $data -> merge ([
'Password' => [
2024-10-10 11:13:44 +00:00
'key' => data_get ( $password , 'key' ),
2024-10-05 12:16:53 +00:00
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
$fields -> put ( 'Invoice Ninja' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'argilla' ) :
2024-10-04 18:16:58 +00:00
$data = collect ([]);
$api_key = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_APIKEY' ) -> first ();
$data = $data -> merge ([
'API Key' => [
'key' => data_get ( $api_key , 'key' ),
'value' => data_get ( $api_key , 'value' ),
'isPassword' => true ,
'rules' => 'required' ,
],
]);
$data = $data -> merge ([
'API Key' => [
'key' => data_get ( $api_key , 'key' ),
'value' => data_get ( $api_key , 'value' ),
'isPassword' => true ,
'rules' => 'required' ,
],
]);
$username = $this -> environment_variables () -> where ( 'key' , 'ARGILLA_USERNAME' ) -> first ();
$data = $data -> merge ([
'Username' => [
'key' => data_get ( $username , 'key' ),
'value' => data_get ( $username , 'value' ),
'rules' => 'required' ,
],
]);
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_ARGILLA' ) -> first ();
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
$fields -> put ( 'Argilla' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'rabbitmq' ) :
2024-08-12 10:37:39 +00:00
$data = collect ([]);
$host_port = $this -> environment_variables () -> where ( 'key' , 'PORT' ) -> first ();
$username = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_RABBITMQ' ) -> first ();
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_RABBITMQ' ) -> first ();
if ( $host_port ) {
$data = $data -> merge ([
'Host Port Binding' => [
'key' => data_get ( $host_port , 'key' ),
'value' => data_get ( $host_port , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $username ) {
$data = $data -> merge ([
'Username' => [
'key' => data_get ( $username , 'key' ),
'value' => data_get ( $username , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'RabbitMQ' , $data -> toArray ());
break ;
2026-01-05 13:13:42 +00:00
case $image -> is ( 'registry' ) :
$data = collect ([]);
$registry_user = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_REGISTRY' ) -> first ();
$registry_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_REGISTRY' ) -> first ();
if ( $registry_user ) {
$data = $data -> merge ([
'Registry User' => [
'key' => data_get ( $registry_user , 'key' ),
'value' => data_get ( $registry_user , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $registry_password ) {
$data = $data -> merge ([
'Registry Password' => [
'key' => data_get ( $registry_password , 'key' ),
'value' => data_get ( $registry_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Docker Registry' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'tolgee' ) :
2024-04-17 10:48:04 +00:00
$data = collect ([]);
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_TOLGEE' ) -> first ();
$data = $data -> merge ([
'Admin User' => [
'key' => 'TOLGEE_AUTHENTICATION_INITIAL_USERNAME' ,
'value' => 'admin' ,
'readonly' => true ,
'rules' => 'required' ,
],
]);
if ( $admin_password ) {
$data = $data -> merge ([
'Admin Password' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $admin_password , 'key' ),
2024-04-17 10:48:04 +00:00
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Tolgee' , $data -> toArray ());
2024-04-17 10:48:04 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'logto' ) :
2024-04-16 12:08:11 +00:00
$data = collect ([]);
$logto_endpoint = $this -> environment_variables () -> where ( 'key' , 'LOGTO_ENDPOINT' ) -> first ();
$logto_admin_endpoint = $this -> environment_variables () -> where ( 'key' , 'LOGTO_ADMIN_ENDPOINT' ) -> first ();
if ( $logto_endpoint ) {
$data = $data -> merge ([
'Endpoint' => [
'key' => data_get ( $logto_endpoint , 'key' ),
'value' => data_get ( $logto_endpoint , 'value' ),
'rules' => 'required|url' ,
],
]);
}
if ( $logto_admin_endpoint ) {
$data = $data -> merge ([
'Admin Endpoint' => [
'key' => data_get ( $logto_admin_endpoint , 'key' ),
'value' => data_get ( $logto_admin_endpoint , 'value' ),
'rules' => 'required|url' ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Logto' , $data -> toArray ());
2024-04-16 12:08:11 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'unleash-server' ) :
2024-04-16 10:41:28 +00:00
$data = collect ([]);
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_UNLEASH' ) -> first ();
$data = $data -> merge ([
'Admin User' => [
'key' => 'SERVICE_USER_UNLEASH' ,
'value' => 'admin' ,
'readonly' => true ,
'rules' => 'required' ,
],
]);
if ( $admin_password ) {
$data = $data -> merge ([
'Admin Password' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $admin_password , 'key' ),
2024-04-16 10:41:28 +00:00
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Unleash' , $data -> toArray ());
2024-04-16 10:41:28 +00:00
break ;
2026-06-05 20:29:29 +00:00
case $this -> isGrafanaImage ( $image -> toString ()) :
2024-03-12 16:43:00 +00:00
$data = collect ([]);
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_GRAFANA' ) -> first ();
$data = $data -> merge ([
'Admin User' => [
'key' => 'GF_SECURITY_ADMIN_USER' ,
'value' => 'admin' ,
'readonly' => true ,
'rules' => 'required' ,
],
]);
if ( $admin_password ) {
$data = $data -> merge ([
'Admin Password' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $admin_password , 'key' ),
2024-03-12 16:43:00 +00:00
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Grafana' , $data -> toArray ());
2025-10-03 18:05:32 +00:00
break ;
case $image -> contains ( 'elasticsearch' ) :
$data = collect ([]);
$elastic_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_ELASTICSEARCH' ) -> first ();
if ( $elastic_password ) {
$data = $data -> merge ([
'Password (default user: elastic)' => [
'key' => data_get ( $elastic_password , 'key' ),
'value' => data_get ( $elastic_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Elasticsearch' , $data -> toArray ());
2024-03-12 16:43:00 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'directus' ) :
2024-03-04 11:46:33 +00:00
$data = collect ([]);
$admin_email = $this -> environment_variables () -> where ( 'key' , 'ADMIN_EMAIL' ) -> first ();
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_ADMIN' ) -> first ();
if ( $admin_email ) {
$data = $data -> merge ([
'Admin Email' => [
'key' => data_get ( $admin_email , 'key' ),
'value' => data_get ( $admin_email , 'value' ),
'rules' => 'required|email' ,
],
]);
}
if ( $admin_password ) {
$data = $data -> merge ([
'Admin Password' => [
'key' => data_get ( $admin_password , 'key' ),
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Directus' , $data -> toArray ());
2024-03-04 11:46:33 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'kong' ) :
2024-02-28 12:48:39 +00:00
$data = collect ([]);
$dashboard_user = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_ADMIN' ) -> first ();
$dashboard_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_ADMIN' ) -> first ();
if ( $dashboard_user ) {
$data = $data -> merge ([
'Dashboard User' => [
'key' => data_get ( $dashboard_user , 'key' ),
'value' => data_get ( $dashboard_user , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $dashboard_password ) {
$data = $data -> merge ([
'Dashboard Password' => [
'key' => data_get ( $dashboard_password , 'key' ),
'value' => data_get ( $dashboard_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Supabase' , $data -> toArray ());
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'minio' ) :
2023-11-20 14:01:35 +00:00
$data = collect ([]);
2023-11-13 10:09:21 +00:00
$console_url = $this -> environment_variables () -> where ( 'key' , 'MINIO_BROWSER_REDIRECT_URL' ) -> first ();
$s3_api_url = $this -> environment_variables () -> where ( 'key' , 'MINIO_SERVER_URL' ) -> first ();
$admin_user = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_MINIO' ) -> first ();
2023-11-20 14:01:35 +00:00
if ( is_null ( $admin_user )) {
$admin_user = $this -> environment_variables () -> where ( 'key' , 'MINIO_ROOT_USER' ) -> first ();
}
2023-11-13 10:09:21 +00:00
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_MINIO' ) -> first ();
2023-11-20 14:01:35 +00:00
if ( is_null ( $admin_password )) {
$admin_password = $this -> environment_variables () -> where ( 'key' , 'MINIO_ROOT_PASSWORD' ) -> first ();
}
if ( $console_url ) {
$data = $data -> merge ([
'Console URL' => [
'key' => data_get ( $console_url , 'key' ),
'value' => data_get ( $console_url , 'value' ),
'rules' => 'required|url' ,
],
]);
}
if ( $s3_api_url ) {
$data = $data -> merge ([
'S3 API URL' => [
'key' => data_get ( $s3_api_url , 'key' ),
'value' => data_get ( $s3_api_url , 'value' ),
'rules' => 'required|url' ,
],
]);
}
if ( $admin_user ) {
$data = $data -> merge ([
'Admin User' => [
'key' => data_get ( $admin_user , 'key' ),
'value' => data_get ( $admin_user , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $admin_password ) {
$data = $data -> merge ([
'Admin Password' => [
'key' => data_get ( $admin_password , 'key' ),
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'MinIO' , $data -> toArray ());
2023-11-13 10:09:21 +00:00
break ;
2025-12-05 12:46:57 +00:00
case $image -> contains ( 'garage' ) :
$data = collect ([]);
$s3_api_url = $this -> environment_variables () -> where ( 'key' , 'GARAGE_S3_API_URL' ) -> first ();
$web_url = $this -> environment_variables () -> where ( 'key' , 'GARAGE_WEB_URL' ) -> first ();
$admin_url = $this -> environment_variables () -> where ( 'key' , 'GARAGE_ADMIN_URL' ) -> first ();
$admin_token = $this -> environment_variables () -> where ( 'key' , 'GARAGE_ADMIN_TOKEN' ) -> first ();
if ( is_null ( $admin_token )) {
$admin_token = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_GARAGE' ) -> first ();
}
$rpc_secret = $this -> environment_variables () -> where ( 'key' , 'GARAGE_RPC_SECRET' ) -> first ();
if ( is_null ( $rpc_secret )) {
2026-05-27 10:45:56 +00:00
$rpc_secret = $this -> environment_variables () -> where ( 'key' , 'SERVICE_HEX_64_RPCSECRET' ) -> first ()
? ? $this -> environment_variables () -> where ( 'key' , 'SERVICE_HEX_32_RPCSECRET' ) -> first ();
2025-12-05 12:46:57 +00:00
}
$metrics_token = $this -> environment_variables () -> where ( 'key' , 'GARAGE_METRICS_TOKEN' ) -> first ();
if ( is_null ( $metrics_token )) {
$metrics_token = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_GARAGEMETRICS' ) -> first ();
}
if ( $s3_api_url ) {
$data = $data -> merge ([
'S3 API URL' => [
'key' => data_get ( $s3_api_url , 'key' ),
'value' => data_get ( $s3_api_url , 'value' ),
'rules' => 'required|url' ,
],
]);
}
if ( $web_url ) {
$data = $data -> merge ([
'Web URL' => [
'key' => data_get ( $web_url , 'key' ),
'value' => data_get ( $web_url , 'value' ),
'rules' => 'required|url' ,
],
]);
}
if ( $admin_url ) {
$data = $data -> merge ([
'Admin URL' => [
'key' => data_get ( $admin_url , 'key' ),
'value' => data_get ( $admin_url , 'value' ),
'rules' => 'required|url' ,
],
]);
}
if ( $admin_token ) {
$data = $data -> merge ([
'Admin Token' => [
'key' => data_get ( $admin_token , 'key' ),
'value' => data_get ( $admin_token , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $rpc_secret ) {
$data = $data -> merge ([
'RPC Secret' => [
'key' => data_get ( $rpc_secret , 'key' ),
'value' => data_get ( $rpc_secret , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $metrics_token ) {
$data = $data -> merge ([
'Metrics Token' => [
'key' => data_get ( $metrics_token , 'key' ),
'value' => data_get ( $metrics_token , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Garage' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'weblate' ) :
2023-11-20 14:01:35 +00:00
$data = collect ([]);
2023-11-13 14:19:49 +00:00
$admin_email = $this -> environment_variables () -> where ( 'key' , 'WEBLATE_ADMIN_EMAIL' ) -> first ();
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_WEBLATE' ) -> first ();
2023-11-20 14:01:35 +00:00
if ( $admin_email ) {
$data = $data -> merge ([
'Admin Email' => [
'key' => data_get ( $admin_email , 'key' ),
'value' => data_get ( $admin_email , 'value' ),
'rules' => 'required|email' ,
],
]);
}
if ( $admin_password ) {
$data = $data -> merge ([
'Admin Password' => [
'key' => data_get ( $admin_password , 'key' ),
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Weblate' , $data -> toArray ());
2023-11-24 20:04:15 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'meilisearch' ) :
2023-12-03 11:16:33 +00:00
$data = collect ([]);
$SERVICE_PASSWORD_MEILISEARCH = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_MEILISEARCH' ) -> first ();
if ( $SERVICE_PASSWORD_MEILISEARCH ) {
$data = $data -> merge ([
'API Key' => [
'key' => data_get ( $SERVICE_PASSWORD_MEILISEARCH , 'key' ),
'value' => data_get ( $SERVICE_PASSWORD_MEILISEARCH , 'value' ),
'isPassword' => true ,
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Meilisearch' , $data -> toArray ());
2023-12-03 11:16:33 +00:00
break ;
2026-01-12 23:05:43 +00:00
case $image -> contains ( 'linkding' ) :
$data = collect ([]);
$SERVICE_USER_LINKDING = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_LINKDING' ) -> first ();
$SERVICE_PASSWORD_LINKDING = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_LINKDING' ) -> first ();
if ( $SERVICE_USER_LINKDING ) {
$data = $data -> merge ([
'Superuser Name' => [
'key' => data_get ( $SERVICE_USER_LINKDING , 'key' ),
'value' => data_get ( $SERVICE_USER_LINKDING , 'value' ),
],
]);
}
2026-02-09 11:33:17 +00:00
if ( $SERVICE_PASSWORD_LINKDING ) {
2026-01-12 23:05:43 +00:00
$data = $data -> merge ([
'Superuser Password' => [
'key' => data_get ( $SERVICE_PASSWORD_LINKDING , 'key' ),
'value' => data_get ( $SERVICE_PASSWORD_LINKDING , 'value' ),
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Linkding' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'ghost' ) :
2023-11-24 20:04:15 +00:00
$data = collect ([]);
$MAIL_OPTIONS_AUTH_PASS = $this -> environment_variables () -> where ( 'key' , 'MAIL_OPTIONS_AUTH_PASS' ) -> first ();
$MAIL_OPTIONS_AUTH_USER = $this -> environment_variables () -> where ( 'key' , 'MAIL_OPTIONS_AUTH_USER' ) -> first ();
$MAIL_OPTIONS_SECURE = $this -> environment_variables () -> where ( 'key' , 'MAIL_OPTIONS_SECURE' ) -> first ();
$MAIL_OPTIONS_PORT = $this -> environment_variables () -> where ( 'key' , 'MAIL_OPTIONS_PORT' ) -> first ();
$MAIL_OPTIONS_SERVICE = $this -> environment_variables () -> where ( 'key' , 'MAIL_OPTIONS_SERVICE' ) -> first ();
$MAIL_OPTIONS_HOST = $this -> environment_variables () -> where ( 'key' , 'MAIL_OPTIONS_HOST' ) -> first ();
if ( $MAIL_OPTIONS_AUTH_PASS ) {
$data = $data -> merge ([
'Mail Password' => [
'key' => data_get ( $MAIL_OPTIONS_AUTH_PASS , 'key' ),
'value' => data_get ( $MAIL_OPTIONS_AUTH_PASS , 'value' ),
'isPassword' => true ,
],
]);
}
if ( $MAIL_OPTIONS_AUTH_USER ) {
$data = $data -> merge ([
'Mail User' => [
'key' => data_get ( $MAIL_OPTIONS_AUTH_USER , 'key' ),
'value' => data_get ( $MAIL_OPTIONS_AUTH_USER , 'value' ),
],
]);
}
if ( $MAIL_OPTIONS_SECURE ) {
$data = $data -> merge ([
'Mail Secure' => [
'key' => data_get ( $MAIL_OPTIONS_SECURE , 'key' ),
'value' => data_get ( $MAIL_OPTIONS_SECURE , 'value' ),
],
]);
}
if ( $MAIL_OPTIONS_PORT ) {
$data = $data -> merge ([
'Mail Port' => [
'key' => data_get ( $MAIL_OPTIONS_PORT , 'key' ),
'value' => data_get ( $MAIL_OPTIONS_PORT , 'value' ),
],
]);
}
if ( $MAIL_OPTIONS_SERVICE ) {
$data = $data -> merge ([
'Mail Service' => [
'key' => data_get ( $MAIL_OPTIONS_SERVICE , 'key' ),
'value' => data_get ( $MAIL_OPTIONS_SERVICE , 'value' ),
],
]);
}
if ( $MAIL_OPTIONS_HOST ) {
$data = $data -> merge ([
'Mail Host' => [
'key' => data_get ( $MAIL_OPTIONS_HOST , 'key' ),
'value' => data_get ( $MAIL_OPTIONS_HOST , 'value' ),
],
]);
}
2024-05-07 08:22:02 +00:00
$fields -> put ( 'Ghost' , $data -> toArray ());
break ;
2024-08-12 10:37:39 +00:00
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'vaultwarden' ) :
2024-05-27 07:51:32 +00:00
$data = collect ([]);
$DATABASE_URL = $this -> environment_variables () -> where ( 'key' , 'DATABASE_URL' ) -> first ();
$ADMIN_TOKEN = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_64_ADMIN' ) -> first ();
2024-05-31 10:55:14 +00:00
$SIGNUP_ALLOWED = $this -> environment_variables () -> where ( 'key' , 'SIGNUP_ALLOWED' ) -> first ();
2024-05-27 22:40:35 +00:00
$PUSH_ENABLED = $this -> environment_variables () -> where ( 'key' , 'PUSH_ENABLED' ) -> first ();
$PUSH_INSTALLATION_ID = $this -> environment_variables () -> where ( 'key' , 'PUSH_SERVICE_ID' ) -> first ();
$PUSH_INSTALLATION_KEY = $this -> environment_variables () -> where ( 'key' , 'PUSH_SERVICE_KEY' ) -> first ();
2024-05-27 07:51:32 +00:00
if ( $DATABASE_URL ) {
$data = $data -> merge ([
'Database URL' => [
'key' => data_get ( $DATABASE_URL , 'key' ),
'value' => data_get ( $DATABASE_URL , 'value' ),
],
]);
}
if ( $ADMIN_TOKEN ) {
$data = $data -> merge ([
'Admin Password' => [
'key' => data_get ( $ADMIN_TOKEN , 'key' ),
'value' => data_get ( $ADMIN_TOKEN , 'value' ),
'isPassword' => true ,
],
]);
}
2024-05-31 10:55:14 +00:00
if ( $SIGNUP_ALLOWED ) {
$data = $data -> merge ([
'Signup Allowed' => [
'key' => data_get ( $SIGNUP_ALLOWED , 'key' ),
'value' => data_get ( $SIGNUP_ALLOWED , 'value' ),
'rules' => 'required|string|in:true,false' ,
],
]);
}
2024-05-27 07:51:32 +00:00
2024-05-27 22:40:35 +00:00
if ( $PUSH_ENABLED ) {
$data = $data -> merge ([
'Push Enabled' => [
'key' => data_get ( $PUSH_ENABLED , 'key' ),
'value' => data_get ( $PUSH_ENABLED , 'value' ),
'rules' => 'required|string|in:true,false' ,
],
]);
}
if ( $PUSH_INSTALLATION_ID ) {
$data = $data -> merge ([
'Push Installation ID' => [
'key' => data_get ( $PUSH_INSTALLATION_ID , 'key' ),
'value' => data_get ( $PUSH_INSTALLATION_ID , 'value' ),
],
]);
}
if ( $PUSH_INSTALLATION_KEY ) {
$data = $data -> merge ([
'Push Installation Key' => [
'key' => data_get ( $PUSH_INSTALLATION_KEY , 'key' ),
'value' => data_get ( $PUSH_INSTALLATION_KEY , 'value' ),
'isPassword' => true ,
],
]);
}
2024-05-27 07:51:32 +00:00
$fields -> put ( 'Vaultwarden' , $data );
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'gitlab/gitlab' ) :
2024-07-25 12:14:00 +00:00
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_GITLAB' ) -> first ();
$data = collect ([]);
if ( $password ) {
$data = $data -> merge ([
'Root Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$data = $data -> merge ([
'Root User' => [
2024-09-12 08:29:45 +00:00
'key' => 'GITLAB_ROOT_USER' ,
2024-07-25 12:14:00 +00:00
'value' => 'root' ,
'rules' => 'required' ,
'isPassword' => true ,
],
]);
$fields -> put ( 'GitLab' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'code-server' ) :
2024-08-29 08:44:16 +00:00
$data = collect ([]);
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_64_PASSWORDCODESERVER' ) -> first ();
if ( $password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$sudoPassword = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_SUDOCODESERVER' ) -> first ();
if ( $sudoPassword ) {
$data = $data -> merge ([
'Sudo Password' => [
'key' => data_get ( $sudoPassword , 'key' ),
'value' => data_get ( $sudoPassword , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Code Server' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'elestio/strapi' ) :
2024-10-03 11:49:43 +00:00
$data = collect ([]);
$license = $this -> environment_variables () -> where ( 'key' , 'STRAPI_LICENSE' ) -> first ();
if ( $license ) {
$data = $data -> merge ([
'License' => [
'key' => data_get ( $license , 'key' ),
'value' => data_get ( $license , 'value' ),
],
]);
}
$nodeEnv = $this -> environment_variables () -> where ( 'key' , 'NODE_ENV' ) -> first ();
if ( $nodeEnv ) {
$data = $data -> merge ([
'Node Environment' => [
'key' => data_get ( $nodeEnv , 'key' ),
'value' => data_get ( $nodeEnv , 'value' ),
],
]);
}
$fields -> put ( 'Strapi' , $data -> toArray ());
break ;
2026-01-02 13:38:19 +00:00
case $image -> contains ( 'marckohlbrugge/sessy' ) :
$data = collect ([]);
$username = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_SESSY' ) -> first ();
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_SESSY' ) -> first ();
if ( $username ) {
$data = $data -> merge ([
'HTTP Auth Username' => [
'key' => data_get ( $username , 'key' ),
'value' => data_get ( $username , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $password ) {
$data = $data -> merge ([
'HTTP Auth Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Sessy' , $data -> toArray ());
break ;
2026-02-09 11:33:17 +00:00
case $image -> contains ( 'coollabsio/openclaw' ) :
$data = collect ([]);
$username = $this -> environment_variables () -> where ( 'key' , 'AUTH_USERNAME' ) -> first ();
$password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_OPENCLAW' ) -> first ();
$gateway_token = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_64_GATEWAYTOKEN' ) -> first ();
if ( $username ) {
$data = $data -> merge ([
'Username' => [
'key' => data_get ( $username , 'key' ),
'value' => data_get ( $username , 'value' ),
'readonly' => true ,
],
]);
}
if ( $password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $password , 'key' ),
'value' => data_get ( $password , 'value' ),
'isPassword' => true ,
],
]);
}
if ( $gateway_token ) {
$data = $data -> merge ([
'Gateway Token' => [
'key' => data_get ( $gateway_token , 'key' ),
'value' => data_get ( $gateway_token , 'value' ),
'isPassword' => true ,
],
]);
}
$fields -> put ( 'Openclaw' , $data -> toArray ());
break ;
2026-08-13 09:00:04 +00:00
case $image -> contains ( 'coollabsio/jean-server' ) :
$data = collect ([]);
$settings = [
'Token' => [ 'key' => 'SERVICE_PASSWORD_64_JEAN' , 'rules' => 'required' , 'isPassword' => true , 'sortOrder' => 1 , 'customHelper' => 'Token required to access Jean Server. Variable name: SERVICE_PASSWORD_64_JEAN' ],
'Allowed Origins' => [ 'key' => 'JEAN_ALLOWED_ORIGINS' , 'rules' => 'nullable|string' , 'sortOrder' => 2 , 'customHelper' => 'Comma-separated additional browser origins. Same-origin access is always allowed. Variable name: JEAN_ALLOWED_ORIGINS' ],
];
foreach ( $settings as $label => $setting ) {
$variable = $this -> environment_variables () -> where ( 'key' , $setting [ 'key' ]) -> first ();
if ( ! $variable ) {
continue ;
}
$data -> put ( $label , [
... $setting ,
'value' => data_get ( $variable , 'value' ),
]);
}
$fields -> put ( '' , $data -> toArray ());
break ;
2024-10-07 09:19:14 +00:00
default :
$data = collect ([]);
$admin_user = $this -> environment_variables () -> where ( 'key' , 'SERVICE_USER_ADMIN' ) -> first ();
// Chaskiq
$admin_email = $this -> environment_variables () -> where ( 'key' , 'ADMIN_EMAIL' ) -> first ();
2024-10-03 11:49:43 +00:00
2024-10-07 09:19:14 +00:00
$admin_password = $this -> environment_variables () -> where ( 'key' , 'SERVICE_PASSWORD_ADMIN' ) -> first ();
if ( $admin_user ) {
$data = $data -> merge ([
'User' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $admin_user , 'key' ),
2024-10-07 09:19:14 +00:00
'value' => data_get ( $admin_user , 'value' , 'admin' ),
'readonly' => true ,
'rules' => 'required' ,
],
]);
}
if ( $admin_password ) {
$data = $data -> merge ([
'Password' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $admin_password , 'key' ),
2024-10-07 09:19:14 +00:00
'value' => data_get ( $admin_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $admin_email ) {
$data = $data -> merge ([
'Email' => [
2024-10-11 09:36:57 +00:00
'key' => data_get ( $admin_email , 'key' ),
2024-10-07 09:19:14 +00:00
'value' => data_get ( $admin_email , 'value' ),
'rules' => 'required|email' ,
],
]);
}
$fields -> put ( 'Admin' , $data -> toArray ());
break ;
2023-11-13 10:09:21 +00:00
}
}
$databases = $this -> databases () -> get ();
foreach ( $databases as $database ) {
2024-10-07 09:19:14 +00:00
$image = str ( $database -> image ) -> before ( ':' );
if ( $image -> isEmpty ()) {
continue ;
}
2023-11-13 10:09:21 +00:00
switch ( $image ) {
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'postgres' ) :
2023-11-13 10:09:21 +00:00
$userVariables = [ 'SERVICE_USER_POSTGRES' , 'SERVICE_USER_POSTGRESQL' ];
$passwordVariables = [ 'SERVICE_PASSWORD_POSTGRES' , 'SERVICE_PASSWORD_POSTGRESQL' ];
$dbNameVariables = [ 'POSTGRESQL_DATABASE' , 'POSTGRES_DB' ];
$postgres_user = $this -> environment_variables () -> whereIn ( 'key' , $userVariables ) -> first ();
$postgres_password = $this -> environment_variables () -> whereIn ( 'key' , $passwordVariables ) -> first ();
$postgres_db_name = $this -> environment_variables () -> whereIn ( 'key' , $dbNameVariables ) -> first ();
2023-11-13 16:06:43 +00:00
$data = collect ([]);
if ( $postgres_user ) {
$data = $data -> merge ([
'User' => [
'key' => data_get ( $postgres_user , 'key' ),
'value' => data_get ( $postgres_user , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $postgres_password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $postgres_password , 'key' ),
'value' => data_get ( $postgres_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $postgres_db_name ) {
$data = $data -> merge ([
'Database Name' => [
'key' => data_get ( $postgres_db_name , 'key' ),
'value' => data_get ( $postgres_db_name , 'value' ),
'rules' => 'required' ,
],
]);
}
$fields -> put ( 'PostgreSQL' , $data -> toArray ());
2023-11-13 10:09:21 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'mysql' ) :
2024-08-29 08:44:16 +00:00
$userVariables = [ 'SERVICE_USER_MYSQL' , 'SERVICE_USER_WORDPRESS' , 'MYSQL_USER' ];
2024-10-17 20:08:23 +00:00
$passwordVariables = [ 'SERVICE_PASSWORD_MYSQL' , 'SERVICE_PASSWORD_WORDPRESS' , 'MYSQL_PASSWORD' , 'SERVICE_PASSWORD_64_MYSQL' ];
$rootPasswordVariables = [ 'SERVICE_PASSWORD_MYSQLROOT' , 'SERVICE_PASSWORD_ROOT' , 'SERVICE_PASSWORD_64_MYSQLROOT' ];
2023-11-13 10:09:21 +00:00
$dbNameVariables = [ 'MYSQL_DATABASE' ];
$mysql_user = $this -> environment_variables () -> whereIn ( 'key' , $userVariables ) -> first ();
$mysql_password = $this -> environment_variables () -> whereIn ( 'key' , $passwordVariables ) -> first ();
$mysql_root_password = $this -> environment_variables () -> whereIn ( 'key' , $rootPasswordVariables ) -> first ();
$mysql_db_name = $this -> environment_variables () -> whereIn ( 'key' , $dbNameVariables ) -> first ();
2023-11-13 16:06:43 +00:00
$data = collect ([]);
if ( $mysql_user ) {
$data = $data -> merge ([
'User' => [
'key' => data_get ( $mysql_user , 'key' ),
'value' => data_get ( $mysql_user , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $mysql_password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $mysql_password , 'key' ),
'value' => data_get ( $mysql_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $mysql_root_password ) {
$data = $data -> merge ([
'Root Password' => [
'key' => data_get ( $mysql_root_password , 'key' ),
'value' => data_get ( $mysql_root_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $mysql_db_name ) {
$data = $data -> merge ([
'Database Name' => [
'key' => data_get ( $mysql_db_name , 'key' ),
'value' => data_get ( $mysql_db_name , 'value' ),
'rules' => 'required' ,
],
]);
}
$fields -> put ( 'MySQL' , $data -> toArray ());
2023-11-13 10:09:21 +00:00
break ;
2024-10-07 09:19:14 +00:00
case $image -> contains ( 'mariadb' ) :
2025-01-13 11:23:38 +00:00
$userVariables = [ 'SERVICE_USER_MARIADB' , 'SERVICE_USER_WORDPRESS' , 'SERVICE_USER_MYSQL' , 'MYSQL_USER' ];
2024-08-29 08:44:16 +00:00
$passwordVariables = [ 'SERVICE_PASSWORD_MARIADB' , 'SERVICE_PASSWORD_WORDPRESS' , '_APP_DB_PASS' , 'MYSQL_PASSWORD' ];
$rootPasswordVariables = [ 'SERVICE_PASSWORD_MARIADBROOT' , 'SERVICE_PASSWORD_ROOT' , '_APP_DB_ROOT_PASS' , 'MYSQL_ROOT_PASSWORD' ];
$dbNameVariables = [ 'SERVICE_DATABASE_MARIADB' , 'SERVICE_DATABASE_WORDPRESS' , '_APP_DB_SCHEMA' , 'MYSQL_DATABASE' ];
2025-01-13 11:23:38 +00:00
2023-11-13 10:09:21 +00:00
$mariadb_user = $this -> environment_variables () -> whereIn ( 'key' , $userVariables ) -> first ();
$mariadb_password = $this -> environment_variables () -> whereIn ( 'key' , $passwordVariables ) -> first ();
$mariadb_root_password = $this -> environment_variables () -> whereIn ( 'key' , $rootPasswordVariables ) -> first ();
$mariadb_db_name = $this -> environment_variables () -> whereIn ( 'key' , $dbNameVariables ) -> first ();
2023-11-13 16:06:43 +00:00
$data = collect ([]);
2023-09-22 09:23:49 +00:00
2023-11-13 16:06:43 +00:00
if ( $mariadb_user ) {
$data = $data -> merge ([
'User' => [
'key' => data_get ( $mariadb_user , 'key' ),
'value' => data_get ( $mariadb_user , 'value' ),
'rules' => 'required' ,
],
]);
}
if ( $mariadb_password ) {
$data = $data -> merge ([
'Password' => [
'key' => data_get ( $mariadb_password , 'key' ),
'value' => data_get ( $mariadb_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $mariadb_root_password ) {
$data = $data -> merge ([
'Root Password' => [
'key' => data_get ( $mariadb_root_password , 'key' ),
'value' => data_get ( $mariadb_root_password , 'value' ),
'rules' => 'required' ,
'isPassword' => true ,
],
]);
}
if ( $mariadb_db_name ) {
$data = $data -> merge ([
'Database Name' => [
'key' => data_get ( $mariadb_db_name , 'key' ),
'value' => data_get ( $mariadb_db_name , 'value' ),
'rules' => 'required' ,
],
]);
}
$fields -> put ( 'MariaDB' , $data -> toArray ());
2023-11-13 10:09:21 +00:00
break ;
}
}
2025-01-13 11:23:38 +00:00
$fields = collect ( $fields ) -> map ( function ( $extraFields ) {
if ( is_array ( $extraFields )) {
$extraFields = collect ( $extraFields ) -> map ( function ( $field ) {
if ( filled ( $field [ 'value' ]) && str ( $field [ 'value' ]) -> startsWith ( '$SERVICE_' )) {
$searchValue = str ( $field [ 'value' ]) -> after ( '$' ) -> value ;
$newValue = $this -> environment_variables () -> where ( 'key' , $searchValue ) -> first ();
if ( $newValue ) {
$field [ 'value' ] = $newValue -> value ;
}
}
return $field ;
});
}
return $extraFields ;
});
2024-06-10 20:43:34 +00:00
2023-11-13 10:09:21 +00:00
return $fields ;
}
2024-06-10 20:43:34 +00:00
2026-06-05 20:29:29 +00:00
private function isGrafanaImage ( string $image ) : bool
{
return in_array ( $image , [
'grafana/grafana' ,
'grafana/grafana-oss' ,
'grafana/grafana-enterprise' ,
], true );
}
2023-11-13 10:09:21 +00:00
public function saveExtraFields ( $fields )
{
foreach ( $fields as $field ) {
$key = data_get ( $field , 'key' );
$value = data_get ( $field , 'value' );
$found = $this -> environment_variables () -> where ( 'key' , $key ) -> first ();
if ( $found ) {
$found -> value = $value ;
$found -> save ();
} else {
$this -> environment_variables () -> create ([
'key' => $key ,
'value' => $value ,
2024-12-17 09:38:32 +00:00
'resourceable_id' => $this -> id ,
'resourceable_type' => $this -> getMorphClass (),
2023-11-13 10:09:21 +00:00
'is_preview' => false ,
]);
}
}
}
2024-06-10 20:43:34 +00:00
2023-11-27 08:39:43 +00:00
public function link ()
{
2023-11-30 11:21:53 +00:00
if ( data_get ( $this , 'environment.project.uuid' )) {
return route ( 'project.service.configuration' , [
'project_uuid' => data_get ( $this , 'environment.project.uuid' ),
2024-11-22 15:03:20 +00:00
'environment_uuid' => data_get ( $this , 'environment.uuid' ),
2024-06-10 20:43:34 +00:00
'service_uuid' => data_get ( $this , 'uuid' ),
2023-11-30 11:21:53 +00:00
]);
}
2024-06-10 20:43:34 +00:00
2023-11-30 11:21:53 +00:00
return null ;
2023-11-27 08:39:43 +00:00
}
2024-06-10 20:43:34 +00:00
2023-09-26 13:07:33 +00:00
public function documentation ()
{
2024-05-22 07:23:17 +00:00
$services = get_service_templates ();
2024-02-23 09:09:42 +00:00
$service = data_get ( $services , str ( $this -> name ) -> beforeLast ( '-' ) -> value , []);
2024-06-10 20:43:34 +00:00
2024-11-12 14:18:48 +00:00
return data_get ( $service , 'documentation' , config ( 'constants.urls.docs' ));
2023-09-26 13:07:33 +00:00
}
2024-06-10 20:43:34 +00:00
2025-11-06 13:30:39 +00:00
/**
* Get the required port for this service from the template definition .
*/
public function getRequiredPort () : ? int
{
try {
$services = get_service_templates ();
2026-09-07 13:17:23 +00:00
if ( blank ( $this -> service_type )) {
return null ;
}
$serviceName = $this -> service_type ;
2025-11-06 13:30:39 +00:00
$service = data_get ( $services , $serviceName , []);
$port = data_get ( $service , 'port' );
return $port ? ( int ) $port : null ;
} catch ( \Throwable ) {
return null ;
}
}
/**
* Check if this service requires a port to function correctly .
*/
public function requiresPort () : bool
{
return $this -> getRequiredPort () !== null ;
}
2023-09-20 13:42:41 +00:00
public function applications ()
{
return $this -> hasMany ( ServiceApplication :: class );
}
2024-06-10 20:43:34 +00:00
2023-09-20 13:42:41 +00:00
public function databases ()
{
return $this -> hasMany ( ServiceDatabase :: class );
}
2024-06-10 20:43:34 +00:00
2023-10-02 13:51:06 +00:00
public function destination ()
{
return $this -> morphTo ();
}
2024-06-10 20:43:34 +00:00
2023-09-21 15:48:31 +00:00
public function environment ()
{
return $this -> belongsTo ( Environment :: class );
}
2024-06-10 20:43:34 +00:00
2023-09-22 09:23:49 +00:00
public function server ()
{
2023-09-21 15:48:31 +00:00
return $this -> belongsTo ( Server :: class );
}
2024-06-10 20:43:34 +00:00
public function byUuid ( string $uuid )
{
2024-05-14 13:19:28 +00:00
$app = $this -> applications () -> whereUuid ( $uuid ) -> first ();
if ( $app ) {
return $app ;
}
$db = $this -> databases () -> whereUuid ( $uuid ) -> first ();
if ( $db ) {
return $db ;
}
2024-06-10 20:43:34 +00:00
2024-05-14 13:19:28 +00:00
return null ;
}
2024-06-10 20:43:34 +00:00
2023-09-21 15:48:31 +00:00
public function byName ( string $name )
{
$app = $this -> applications () -> whereName ( $name ) -> first ();
if ( $app ) {
return $app ;
}
$db = $this -> databases () -> whereName ( $name ) -> first ();
if ( $db ) {
return $db ;
}
2024-06-10 20:43:34 +00:00
2023-09-21 15:48:31 +00:00
return null ;
}
2024-06-10 20:43:34 +00:00
2024-01-05 05:06:36 +00:00
public function scheduled_tasks () : HasMany
{
return $this -> hasMany ( ScheduledTask :: class ) -> orderBy ( 'name' , 'asc' );
}
2024-06-10 20:43:34 +00:00
2024-12-17 09:38:32 +00:00
public function environment_variables ()
2023-09-20 13:42:41 +00:00
{
2026-01-06 15:18:37 +00:00
return $this -> morphMany ( EnvironmentVariable :: class , 'resourceable' );
2023-11-02 13:03:02 +00:00
}
2024-06-10 20:43:34 +00:00
2023-09-25 13:48:43 +00:00
public function workdir ()
{
2024-09-23 17:51:31 +00:00
return service_configuration_dir () . " / { $this -> uuid } " ;
2023-09-25 10:49:55 +00:00
}
2024-06-10 20:43:34 +00:00
2023-09-25 10:49:55 +00:00
public function saveComposeConfigs ()
{
2025-11-07 13:14:43 +00:00
// Guard against null or empty docker_compose
if ( ! $this -> docker_compose ) {
return ;
}
2023-09-25 10:49:55 +00:00
$workdir = $this -> workdir ();
2024-09-03 09:47:30 +00:00
instant_remote_process ([
" mkdir -p $workdir " ,
" cd $workdir " ,
], $this -> server );
2024-06-22 10:55:26 +00:00
2026-06-04 09:03:06 +00:00
$filename = new_public_id () . '-docker-compose.yml' ;
2024-09-03 09:47:30 +00:00
Storage :: disk ( 'local' ) -> put ( " tmp/ { $filename } " , $this -> docker_compose );
$path = Storage :: path ( " tmp/ { $filename } " );
instant_scp ( $path , " { $workdir } /docker-compose.yml " , $this -> server );
Storage :: disk ( 'local' ) -> delete ( " tmp/ { $filename } " );
2024-06-22 10:55:26 +00:00
2024-09-03 15:27:22 +00:00
$commands [] = " cd $workdir " ;
2026-09-10 07:24:37 +00:00
$environmentFilename = new_public_id () . '.env.tmp' ;
2024-06-22 10:55:26 +00:00
2025-10-03 07:41:59 +00:00
$envs = collect ([]);
// Generate SERVICE_NAME_* environment variables from docker-compose services
if ( $this -> docker_compose ) {
try {
2026-03-28 11:32:57 +00:00
$dockerCompose = Yaml :: parse ( $this -> docker_compose );
2025-10-03 07:41:59 +00:00
$services = data_get ( $dockerCompose , 'services' , []);
foreach ( $services as $serviceName => $_ ) {
$envs -> push ( 'SERVICE_NAME_' . str ( $serviceName ) -> replace ( '-' , '_' ) -> replace ( '.' , '_' ) -> upper () . '=' . $serviceName );
}
} catch ( \Exception $e ) {
}
}
2024-06-25 08:34:56 +00:00
$envs_from_coolify = $this -> environment_variables () -> get ();
2024-09-09 13:04:51 +00:00
$sorted = $envs_from_coolify -> sortBy ( function ( $env ) {
if ( str ( $env -> key ) -> startsWith ( 'SERVICE_' )) {
return 1 ;
}
if ( str ( $env -> value ) -> startsWith ( '$SERVICE_' ) || str ( $env -> value ) -> startsWith ( '${SERVICE_' )) {
return 2 ;
}
return 3 ;
});
foreach ( $sorted as $env ) {
2025-07-07 10:30:44 +00:00
$envs -> push ( " { $env -> key } = { $env -> real_value } " );
2023-09-25 10:49:55 +00:00
}
2025-07-07 10:30:44 +00:00
if ( $envs -> count () === 0 ) {
2026-09-10 07:24:37 +00:00
$commands [] = " touch { $environmentFilename } && mv { $environmentFilename } .env " ;
2025-07-07 10:30:44 +00:00
} else {
2025-09-15 15:55:08 +00:00
$envs_base64 = base64_encode ( $envs -> implode ( " \n " ));
2026-09-10 07:24:37 +00:00
$commands [] = " echo ' $envs_base64 ' | base64 -d | tee { $environmentFilename } > /dev/null && mv { $environmentFilename } .env " ;
2023-09-26 12:45:52 +00:00
}
2025-07-07 10:30:44 +00:00
2023-09-25 10:49:55 +00:00
instant_remote_process ( $commands , $this -> server );
}
2023-09-28 08:53:00 +00:00
2025-08-04 08:46:59 +00:00
public function parse ( bool $isNew = false ) : Collection
2023-09-20 13:42:41 +00:00
{
2024-09-30 12:15:22 +00:00
if (( int ) $this -> compose_parsing_version >= 3 ) {
2025-08-04 08:46:59 +00:00
return serviceParser ( $this );
2025-01-07 14:31:43 +00:00
} elseif ( $this -> docker_compose_raw ) {
2024-08-27 14:02:52 +00:00
return parseDockerComposeFile ( $this , $isNew );
2025-01-07 14:31:43 +00:00
} else {
return collect ([]);
2024-08-27 14:02:52 +00:00
}
2023-09-20 13:42:41 +00:00
}
2024-06-10 20:43:34 +00:00
2023-11-27 08:58:31 +00:00
public function networks ()
{
2024-10-31 17:20:11 +00:00
return getTopLevelNetworks ( $this );
2023-11-27 08:58:31 +00:00
}
2024-10-11 12:38:22 +00:00
protected function isDeployable () : Attribute
{
return Attribute :: make (
2026-08-07 10:24:09 +00:00
get : fn () : bool => $this -> missingRequiredEnvironmentVariables () -> isEmpty ()
2024-10-11 12:38:22 +00:00
);
}
2026-08-07 10:24:09 +00:00
public function missingRequiredEnvironmentVariables () : Collection
{
return $this -> environment_variables ()
-> where ( 'is_required' , true )
-> get ()
-> filter ( fn ( EnvironmentVariable $environmentVariable ) : bool => $environmentVariable -> is_really_required )
-> values ();
}
2023-09-20 13:42:41 +00:00
}