feat(docker): add container name prefix for generated container names

This commit is contained in:
peaklabs-dev
2026-09-09 15:01:57 +02:00
committed by 🏔️ Peak
parent 62df33ba3d
commit 266d414a04
5 changed files with 53 additions and 1 deletions
+14
View File
@@ -32,6 +32,7 @@ use OpenApi\Attributes as OA;
'is_stripprefix_enabled' => ['type' => 'boolean'],
'connect_to_docker_network' => ['type' => 'boolean'],
'custom_internal_name' => ['type' => 'string', 'nullable' => true],
'custom_container_name_prefix' => ['type' => 'string', 'nullable' => true],
'is_container_label_escape_enabled' => ['type' => 'boolean'],
'is_env_sorting_enabled' => ['type' => 'boolean'],
'is_container_label_readonly_enabled' => ['type' => 'boolean'],
@@ -106,6 +107,7 @@ class ApplicationSetting extends Model
'is_stripprefix_enabled',
'connect_to_docker_network',
'custom_internal_name',
'custom_container_name_prefix',
'is_container_label_escape_enabled',
'is_env_sorting_enabled',
'is_container_label_readonly_enabled',
@@ -121,6 +123,18 @@ class ApplicationSetting extends Model
'stop_grace_period',
];
/**
* Like custom container names, a prefix must be unique per server so that uuid, custom container
* name and prefix each identify one container when resolving connections.
*/
public static function isContainerNamePrefixInUse(string $prefix, Server $server, ?int $ignoreApplicationId = null): bool
{
return $server->applications()->contains(function (Application $application) use ($prefix, $ignoreApplicationId) {
return $application->id !== $ignoreApplicationId
&& in_array($prefix, [$application->uuid, $application->settings->custom_container_name_prefix, $application->settings->custom_internal_name], true);
});
}
public function stopGracePeriodSeconds(): int
{
if (
@@ -170,6 +170,7 @@ class ApplicationConfigurationSnapshot
$this->item('custom_network_aliases', 'Network aliases', $this->application->custom_network_aliases, 'redeploy'),
$this->item('connect_to_docker_network', 'Connect to Docker network', data_get($this->application, 'settings.connect_to_docker_network'), 'redeploy'),
$this->item('custom_internal_name', 'Custom container name', data_get($this->application, 'settings.custom_internal_name'), 'redeploy'),
$this->item('custom_container_name_prefix', 'Container name prefix', data_get($this->application, 'settings.custom_container_name_prefix'), 'redeploy'),
$this->item('is_consistent_container_name_enabled', 'Consistent container name', data_get($this->application, 'settings.is_consistent_container_name_enabled'), 'redeploy'),
$this->item('is_container_label_escape_enabled', 'Escape container labels', data_get($this->application, 'settings.is_container_label_escape_enabled'), 'redeploy'),
$this->item('is_container_label_readonly_enabled', 'Read-only container labels', data_get($this->application, 'settings.is_container_label_readonly_enabled'), 'redeploy'),
+1 -1
View File
@@ -358,7 +358,7 @@ function generateApplicationContainerName(Application $application, $pull_reques
return $name;
}
return $application->uuid.'-'.$now;
return ($application->settings->custom_container_name_prefix ?: $application->uuid).'-'.$now;
}
}
@@ -0,0 +1,18 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->string('custom_container_name_prefix')->nullable();
});
}
};
@@ -64,3 +64,22 @@ it('recognises generated container names in both timestamp formats', function ()
->and(isGeneratedContainerName('application-uuid-pr-42'))->toBeFalse()
->and(isGeneratedContainerName('my-api'))->toBeFalse();
});
function applicationWithContainerNamePrefix(string $prefix = 'my-api', bool $consistent = false): Application
{
$application = new Application;
$application->forceFill(['uuid' => 'application-uuid']);
$application->setRelation('settings', new ApplicationSetting([
'custom_container_name_prefix' => $prefix,
'is_consistent_container_name_enabled' => $consistent,
]));
return $application;
}
it('uses the container name prefix for generated container names only', function () {
expect(generateApplicationContainerName(applicationWithContainerNamePrefix()))->toMatch('/^my-api-\d{8}T\d{6}$/')
->and(generateApplicationContainerName(applicationWithContainerNamePrefix('')))->toMatch('/^application-uuid-\d{8}T\d{6}$/')
->and(generateApplicationContainerName(applicationWithContainerNamePrefix(consistent: true)))->toBe('application-uuid')
->and(generateApplicationContainerName(applicationWithContainerNamePrefix(), 42))->toBe('application-uuid-pr-42');
});