From 543d3c33f11eba1f751f5063dad018882d11850a Mon Sep 17 00:00:00 2001 From: Charles d'Avernas Date: Tue, 22 Jul 2025 21:36:48 +0200 Subject: [PATCH] fix(Docker): Fixed the `DockerRuntime` to apply the provided `HostConfig`, thereby supporting volume mount functionality fix(Docker): Fixed the `DockerContainerPlatform` to properly initialize containers binds, thereby supporting volume mount functionality fix(DockerCompose): Fixed the docker-compose deployment by replacing `Garnet` by `Redis` Signed-off-by: Charles d'Avernas --- deployments/docker-compose/.env | 2 +- deployments/docker-compose/docker-compose.yml | 22 +++++++++---------- .../DockerContainerPlatform.cs | 2 +- .../Resources/DockerRuntimeConfiguration.cs | 10 +++++++-- .../Synapse.Dashboard/Layout/MainLayout.razor | 2 +- .../Synapse.Dashboard/Services/JsInterop.cs | 2 +- .../Synapse.Dashboard/wwwroot/index.html | 4 ++-- .../Services/DockerRuntime.cs | 10 ++++----- 8 files changed, 28 insertions(+), 26 deletions(-) diff --git a/deployments/docker-compose/.env b/deployments/docker-compose/.env index 57e3307da..bdfe000a5 100644 --- a/deployments/docker-compose/.env +++ b/deployments/docker-compose/.env @@ -1 +1 @@ -GARNET_URI=garnet:6379 \ No newline at end of file +REDIS_URI=redis:6379 \ No newline at end of file diff --git a/deployments/docker-compose/docker-compose.yml b/deployments/docker-compose/docker-compose.yml index 7b1bb782b..c0a73650f 100644 --- a/deployments/docker-compose/docker-compose.yml +++ b/deployments/docker-compose/docker-compose.yml @@ -1,14 +1,14 @@ services: - garnet: - image: ghcr.io/microsoft/garnet + redis: + image: redis:8.0.0 volumes: - - garnet_data:/data + - redis_data:/data api: image: ghcr.io/serverlessworkflow/synapse/api environment: - CONNECTIONSTRINGS__REDIS: ${GARNET_URI} + CONNECTIONSTRINGS__REDIS: ${REDIS_URI} SYNAPSE_DASHBOARD_SERVE: 'true' SYNAPSE_API_AUTH_TOKEN_FILE: /app/tokens.yaml SYNAPSE_API_JWT_AUTHORITY: http://api:8080 @@ -18,12 +18,12 @@ services: ports: - 8080:8080 depends_on: - - garnet + - redis operator: image: ghcr.io/serverlessworkflow/synapse/operator environment: - CONNECTIONSTRINGS__REDIS: ${GARNET_URI} + CONNECTIONSTRINGS__REDIS: ${REDIS_URI} SYNAPSE_OPERATOR_NAMESPACE: default SYNAPSE_OPERATOR_NAME: operator-1 SYNAPSE_RUNNER_API: http://api:8080 @@ -37,25 +37,23 @@ services: - /var/run/docker.sock:/var/run/docker.sock user: root depends_on: - - garnet + - redis correlator: image: ghcr.io/serverlessworkflow/synapse/correlator environment: - CONNECTIONSTRINGS__REDIS: ${GARNET_URI} + CONNECTIONSTRINGS__REDIS: ${REDIS_URI} SYNAPSE_CORRELATOR_NAMESPACE: default SYNAPSE_CORRELATOR_NAME: correlator-1 ports: - 8081:8080 depends_on: - - garnet + - redis volumes: - - garnet_data: + redis_data: driver: local networks: - default: name: synapse \ No newline at end of file diff --git a/src/core/Synapse.Core.Infrastructure.Containers.Docker/DockerContainerPlatform.cs b/src/core/Synapse.Core.Infrastructure.Containers.Docker/DockerContainerPlatform.cs index 320d2dcb5..0e8f5540f 100644 --- a/src/core/Synapse.Core.Infrastructure.Containers.Docker/DockerContainerPlatform.cs +++ b/src/core/Synapse.Core.Infrastructure.Containers.Docker/DockerContainerPlatform.cs @@ -100,7 +100,7 @@ public virtual async Task CreateAsync(ContainerProcessDefinition def HostConfig = new() { PortBindings = definition.Ports?.ToDictionary(kvp => kvp.Value.ToString(), kvp => (IList)[new PortBinding() { HostPort = kvp.Key.ToString() }]), - Binds = definition.Volumes?.Select(e => $"{e.Key}={e.Value}")?.ToList() ?? [] + Binds = definition.Volumes?.Select(e => $"{e.Key}:{e.Value}")?.ToList() ?? [] } }; var response = await this.Docker.Containers.CreateContainerAsync(parameters, cancellationToken).ConfigureAwait(false); diff --git a/src/core/Synapse.Core/Resources/DockerRuntimeConfiguration.cs b/src/core/Synapse.Core/Resources/DockerRuntimeConfiguration.cs index 8721a6a59..2cea7f609 100644 --- a/src/core/Synapse.Core/Resources/DockerRuntimeConfiguration.cs +++ b/src/core/Synapse.Core/Resources/DockerRuntimeConfiguration.cs @@ -80,16 +80,22 @@ public DockerRuntimeConfiguration() [DataMember(Order = 4, Name = "containerTemplate"), JsonPropertyOrder(4), JsonPropertyName("containerTemplate"), YamlMember(Order = 4, Alias = "containerTemplate")] public virtual Config ContainerTemplate { get; set; } = LoadContainerTemplate(); + /// + /// Gets/sets the configuration of the host to use when running runner containers + /// + [DataMember(Order = 5, Name = "hostConfig"), JsonPropertyOrder(5), JsonPropertyName("hostConfig"), YamlMember(Order = 5, Alias = "hostConfig")] + public virtual HostConfig? HostConfig { get; set; } + /// /// Gets/sets the path to the directory that contains the secrets to mount in runner containers on a per workflow configuration basis /// - [DataMember(Order = 5, Name = "secrets"), JsonPropertyOrder(5), JsonPropertyName("secrets"), YamlMember(Order = 5, Alias = "secrets")] + [DataMember(Order = 6, Name = "secrets"), JsonPropertyOrder(6), JsonPropertyName("secrets"), YamlMember(Order = 6, Alias = "secrets")] public virtual DockerRuntimeSecretsConfiguration Secrets { get; set; } = new(); /// /// Gets/sets the name of the network, if any, to connect Runner containers to /// - [DataMember(Order = 6, Name = "network"), JsonPropertyOrder(6), JsonPropertyName("network"), YamlMember(Order = 6, Alias = "network")] + [DataMember(Order = 7, Name = "network"), JsonPropertyOrder(7), JsonPropertyName("network"), YamlMember(Order = 7, Alias = "network")] public virtual string Network { get; set; } = DefaultNetwork; /// diff --git a/src/dashboard/Synapse.Dashboard/Layout/MainLayout.razor b/src/dashboard/Synapse.Dashboard/Layout/MainLayout.razor index d7ed7090d..0f01bc2bc 100644 --- a/src/dashboard/Synapse.Dashboard/Layout/MainLayout.razor +++ b/src/dashboard/Synapse.Dashboard/Layout/MainLayout.razor @@ -133,7 +133,7 @@ { user = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User; AuthenticationStateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged; - theme = await Storage.GetItemAsync("preferedTheme") ?? "dark"; + theme = await Storage.GetItemAsync("preferredTheme") ?? "dark"; await MonacoEditorHelper.ChangePreferredThemeAsync(theme); await base.OnInitializedAsync(); } diff --git a/src/dashboard/Synapse.Dashboard/Services/JsInterop.cs b/src/dashboard/Synapse.Dashboard/Services/JsInterop.cs index f4386af2e..a3a8b6b5f 100644 --- a/src/dashboard/Synapse.Dashboard/Services/JsInterop.cs +++ b/src/dashboard/Synapse.Dashboard/Services/JsInterop.cs @@ -61,7 +61,7 @@ public async ValueTask SetThemeAsync(string theme) { var module = await moduleTask.Value; await module.InvokeVoidAsync("setTheme", theme); - await storage.SetItemAsync("preferedTheme", theme); + await storage.SetItemAsync("preferredTheme", theme); await monacoEditorHelper.ChangePreferredThemeAsync(theme); } diff --git a/src/dashboard/Synapse.Dashboard/wwwroot/index.html b/src/dashboard/Synapse.Dashboard/wwwroot/index.html index 7bf828124..4bfcdf36c 100644 --- a/src/dashboard/Synapse.Dashboard/wwwroot/index.html +++ b/src/dashboard/Synapse.Dashboard/wwwroot/index.html @@ -43,8 +43,8 @@ diff --git a/src/runtime/Synapse.Runtime.Docker/Services/DockerRuntime.cs b/src/runtime/Synapse.Runtime.Docker/Services/DockerRuntime.cs index 044c699d1..2f177f6e7 100644 --- a/src/runtime/Synapse.Runtime.Docker/Services/DockerRuntime.cs +++ b/src/runtime/Synapse.Runtime.Docker/Services/DockerRuntime.cs @@ -104,18 +104,16 @@ public override async Task CreateProcessAsync(Workflow workflo container.SetEnvironmentVariable("DOCKER_HOST", "unix:///var/run/docker.sock"); container.User = "root"; if (this.Runner.Certificates?.Validate == false) container.SetEnvironmentVariable(SynapseDefaults.EnvironmentVariables.SkipCertificateValidation, "true"); - var hostConfig = new HostConfig() - { - Mounts = [] - }; + var hostConfig = this.Runner.Runtime.Docker.HostConfig?.Clone()! ?? new(); if (!Directory.Exists(this.Runner.Runtime.Docker.Secrets.Directory)) Directory.CreateDirectory(this.Runner.Runtime.Docker.Secrets.Directory); - hostConfig.Mounts.Add(new() + hostConfig.Mounts ??= []; + hostConfig.Mounts.Insert(0, new() { Type = "bind", Source = this.Runner.Runtime.Docker.Secrets.Directory, Target = this.Runner.Runtime.Docker.Secrets.MountPath }); - hostConfig.Mounts.Add(new() + hostConfig.Mounts.Insert(1, new() { Type = "bind", Source = "/var/run/docker.sock",