Merge pull request #4741 from piotr-woojcik/docker-network-aliases
Custom network aliases for interconnectivity of services deployed with rolling release with Dockerfile, Docker Image and Nixpacks
This commit is contained in:
@@ -329,7 +329,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
} else {
|
} else {
|
||||||
$this->write_deployment_configurations();
|
$this->write_deployment_configurations();
|
||||||
}
|
}
|
||||||
$this->application_deployment_queue->addLogEntry("Starting graceful shutdown container: {$this->deployment_uuid}");
|
$this->application_deployment_queue->addLogEntry("Gracefully shutting down build container: {$this->deployment_uuid}");
|
||||||
$this->graceful_shutdown_container($this->deployment_uuid);
|
$this->graceful_shutdown_container($this->deployment_uuid);
|
||||||
|
|
||||||
ApplicationStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id'));
|
ApplicationStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id'));
|
||||||
@@ -1361,7 +1361,6 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->application_deployment_queue->addLogEntry("Preparing container with helper image: $helperImage.");
|
$this->application_deployment_queue->addLogEntry("Preparing container with helper image: $helperImage.");
|
||||||
$this->application_deployment_queue->addLogEntry("Starting graceful shutdown container: {$this->deployment_uuid}");
|
|
||||||
$this->graceful_shutdown_container($this->deployment_uuid);
|
$this->graceful_shutdown_container($this->deployment_uuid);
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[
|
[
|
||||||
@@ -1710,6 +1709,10 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
]);
|
]);
|
||||||
$this->application->parseHealthcheckFromDockerfile($this->saved_outputs->get('dockerfile_from_repo'));
|
$this->application->parseHealthcheckFromDockerfile($this->saved_outputs->get('dockerfile_from_repo'));
|
||||||
}
|
}
|
||||||
|
$custom_network_aliases = [];
|
||||||
|
if (is_array($this->application->custom_network_aliases) && count($this->application->custom_network_aliases) > 0) {
|
||||||
|
$custom_network_aliases = $this->application->custom_network_aliases;
|
||||||
|
}
|
||||||
$docker_compose = [
|
$docker_compose = [
|
||||||
'services' => [
|
'services' => [
|
||||||
$this->container_name => [
|
$this->container_name => [
|
||||||
@@ -1719,9 +1722,10 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
|||||||
'expose' => $ports,
|
'expose' => $ports,
|
||||||
'networks' => [
|
'networks' => [
|
||||||
$this->destination->network => [
|
$this->destination->network => [
|
||||||
'aliases' => [
|
'aliases' => array_merge(
|
||||||
$this->container_name,
|
[$this->container_name],
|
||||||
],
|
$custom_network_aliases
|
||||||
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'mem_limit' => $this->application->limits_memory,
|
'mem_limit' => $this->application->limits_memory,
|
||||||
|
@@ -68,6 +68,7 @@ class General extends Component
|
|||||||
'application.publish_directory' => 'nullable',
|
'application.publish_directory' => 'nullable',
|
||||||
'application.ports_exposes' => 'required',
|
'application.ports_exposes' => 'required',
|
||||||
'application.ports_mappings' => 'nullable',
|
'application.ports_mappings' => 'nullable',
|
||||||
|
'application.custom_network_aliases' => 'nullable',
|
||||||
'application.dockerfile' => 'nullable',
|
'application.dockerfile' => 'nullable',
|
||||||
'application.docker_registry_image_name' => 'nullable',
|
'application.docker_registry_image_name' => 'nullable',
|
||||||
'application.docker_registry_image_tag' => 'nullable',
|
'application.docker_registry_image_tag' => 'nullable',
|
||||||
@@ -121,6 +122,7 @@ class General extends Component
|
|||||||
'application.custom_labels' => 'Custom labels',
|
'application.custom_labels' => 'Custom labels',
|
||||||
'application.dockerfile_target_build' => 'Dockerfile target build',
|
'application.dockerfile_target_build' => 'Dockerfile target build',
|
||||||
'application.custom_docker_run_options' => 'Custom docker run commands',
|
'application.custom_docker_run_options' => 'Custom docker run commands',
|
||||||
|
'application.custom_network_aliases' => 'Custom docker network aliases',
|
||||||
'application.docker_compose_custom_start_command' => 'Docker compose custom start command',
|
'application.docker_compose_custom_start_command' => 'Docker compose custom start command',
|
||||||
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
|
'application.docker_compose_custom_build_command' => 'Docker compose custom build command',
|
||||||
'application.custom_nginx_configuration' => 'Custom Nginx configuration',
|
'application.custom_nginx_configuration' => 'Custom Nginx configuration',
|
||||||
|
@@ -45,6 +45,7 @@ use Visus\Cuid2\Cuid2;
|
|||||||
'start_command' => ['type' => 'string', 'description' => 'Start command.'],
|
'start_command' => ['type' => 'string', 'description' => 'Start command.'],
|
||||||
'ports_exposes' => ['type' => 'string', 'description' => 'Ports exposes.'],
|
'ports_exposes' => ['type' => 'string', 'description' => 'Ports exposes.'],
|
||||||
'ports_mappings' => ['type' => 'string', 'nullable' => true, 'description' => 'Ports mappings.'],
|
'ports_mappings' => ['type' => 'string', 'nullable' => true, 'description' => 'Ports mappings.'],
|
||||||
|
'custom_network_aliases' => ['type' => 'string', 'nullable' => true, 'description' => 'Network aliases for Docker container.'],
|
||||||
'base_directory' => ['type' => 'string', 'description' => 'Base directory for all commands.'],
|
'base_directory' => ['type' => 'string', 'description' => 'Base directory for all commands.'],
|
||||||
'publish_directory' => ['type' => 'string', 'description' => 'Publish directory.'],
|
'publish_directory' => ['type' => 'string', 'description' => 'Publish directory.'],
|
||||||
'health_check_enabled' => ['type' => 'boolean', 'description' => 'Health check enabled.'],
|
'health_check_enabled' => ['type' => 'boolean', 'description' => 'Health check enabled.'],
|
||||||
@@ -115,6 +116,68 @@ class Application extends BaseModel
|
|||||||
|
|
||||||
protected $appends = ['server_status'];
|
protected $appends = ['server_status'];
|
||||||
|
|
||||||
|
protected $casts = ['custom_network_aliases' => 'array'];
|
||||||
|
|
||||||
|
public function customNetworkAliases(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
set: function ($value) {
|
||||||
|
if (is_null($value) || $value === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's already a JSON string, decode it
|
||||||
|
if (is_string($value) && $this->isJson($value)) {
|
||||||
|
$value = json_decode($value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's a string but not JSON, treat it as a comma-separated list
|
||||||
|
if (is_string($value) && ! is_array($value)) {
|
||||||
|
$value = explode(',', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = collect($value)
|
||||||
|
->map(function ($alias) {
|
||||||
|
if (is_string($alias)) {
|
||||||
|
return str_replace(' ', '-', trim($alias));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
->filter()
|
||||||
|
->unique() // Remove duplicate values
|
||||||
|
->values()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
return empty($value) ? null : json_encode($value);
|
||||||
|
},
|
||||||
|
get: function ($value) {
|
||||||
|
if (is_null($value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) && $this->isJson($value)) {
|
||||||
|
return json_decode($value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_array($value) ? $value : [];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string is a valid JSON
|
||||||
|
*/
|
||||||
|
private function isJson($string)
|
||||||
|
{
|
||||||
|
if (! is_string($string)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
json_decode($string);
|
||||||
|
|
||||||
|
return json_last_error() === JSON_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
protected static function booted()
|
protected static function booted()
|
||||||
{
|
{
|
||||||
static::addGlobalScope('withRelations', function ($builder) {
|
static::addGlobalScope('withRelations', function ($builder) {
|
||||||
|
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->text('custom_network_aliases')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('applications', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('custom_network_aliases');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -342,6 +342,11 @@
|
|||||||
<x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings"
|
<x-forms.input placeholder="3000:3000" id="application.ports_mappings" label="Ports Mappings"
|
||||||
helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><br><span class='inline-block font-bold dark:text-warning'>Example:</span><br>3000:3000,3002:3002<br><br>Rolling update is not supported if you have a port mapped to the host." />
|
helper="A comma separated list of ports you would like to map to the host system. Useful when you do not want to use domains.<br><br><span class='inline-block font-bold dark:text-warning'>Example:</span><br>3000:3000,3002:3002<br><br>Rolling update is not supported if you have a port mapped to the host." />
|
||||||
@endif
|
@endif
|
||||||
|
@if (!$application->destination->server->isSwarm())
|
||||||
|
<x-forms.input id="application.custom_network_aliases" label="Network Aliases"
|
||||||
|
helper="A comma separated list of custom network aliases you would like to add for container in Docker network.<br><br><span class='inline-block font-bold dark:text-warning'>Example:</span><br>api.internal,api.local"
|
||||||
|
wire:model="application.custom_network_aliases" />
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($application->settings->is_container_label_readonly_enabled)
|
@if ($application->settings->is_container_label_readonly_enabled)
|
||||||
|
Reference in New Issue
Block a user