feat: expand ContainerRequest with cpuLimit, ports, restart policy, additional networks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-08 20:20:13 +02:00
parent b7d00548c5
commit 55bdab472b
3 changed files with 52 additions and 9 deletions

View File

@@ -18,6 +18,7 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -99,11 +100,17 @@ public class DeploymentExecutor {
baseImage,
jarPath,
dockerNetwork,
List.of(),
envVars,
labels,
parseMemoryLimitBytes(containerMemoryLimit),
null,
containerCpuShares,
agentHealthPort);
null,
List.of(),
agentHealthPort,
"on-failure",
3);
String containerId = orchestrator.startContainer(request);
waitForHealthy(containerId, healthCheckTimeout);

View File

@@ -10,6 +10,7 @@ import com.github.dockerjava.api.model.Bind;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.api.model.HealthCheck;
import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.RestartPolicy;
import com.github.dockerjava.api.model.Volume;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
@@ -59,7 +60,6 @@ public class DockerRuntimeOrchestrator implements RuntimeOrchestrator {
List<String> envList = request.envVars().entrySet().stream()
.map(e -> e.getKey() + "=" + e.getValue()).toList();
// Volume bind: mount JAR into container
Bind jarBind = new Bind(request.jarPath(), new Volume("/app/app.jar"), AccessMode.ro);
HostConfig hostConfig = HostConfig.newHostConfig()
@@ -67,9 +67,17 @@ public class DockerRuntimeOrchestrator implements RuntimeOrchestrator {
.withMemorySwap(request.memoryLimitBytes())
.withCpuShares(request.cpuShares())
.withNetworkMode(request.network())
.withBinds(jarBind);
.withBinds(jarBind)
.withRestartPolicy(RestartPolicy.onFailureRestart(request.restartPolicyMaxRetries()));
var container = dockerClient.createContainerCmd(request.baseImage())
if (request.memoryReserveBytes() != null) {
hostConfig.withMemoryReservation(request.memoryReserveBytes());
}
if (request.cpuQuota() != null) {
hostConfig.withCpuQuota(request.cpuQuota());
}
var createCmd = dockerClient.createContainerCmd(request.baseImage())
.withName(request.containerName())
.withEnv(envList)
.withLabels(request.labels() != null ? request.labels() : Map.of())
@@ -77,17 +85,38 @@ public class DockerRuntimeOrchestrator implements RuntimeOrchestrator {
.withHealthcheck(new HealthCheck()
.withTest(List.of("CMD-SHELL",
"wget -qO- http://localhost:" + request.healthCheckPort() + "/cameleer/health || exit 1"))
.withInterval(10_000_000_000L) // 10s
.withTimeout(5_000_000_000L) // 5s
.withInterval(10_000_000_000L)
.withTimeout(5_000_000_000L)
.withRetries(3)
.withStartPeriod(30_000_000_000L)) // 30s
.exec();
.withStartPeriod(30_000_000_000L));
if (request.exposedPorts() != null && !request.exposedPorts().isEmpty()) {
var ports = request.exposedPorts().stream()
.map(p -> com.github.dockerjava.api.model.ExposedPort.tcp(p))
.toArray(com.github.dockerjava.api.model.ExposedPort[]::new);
createCmd.withExposedPorts(ports);
}
var container = createCmd.exec();
dockerClient.startContainerCmd(container.getId()).exec();
if (request.additionalNetworks() != null) {
for (String net : request.additionalNetworks()) {
dockerClient.connectToNetworkCmd()
.withContainerId(container.getId())
.withNetworkId(net)
.exec();
}
}
log.info("Started container {} ({})", request.containerName(), container.getId());
return container.getId();
}
public DockerClient getDockerClient() {
return dockerClient;
}
@Override
public void stopContainer(String containerId) {
try {

View File

@@ -1,5 +1,6 @@
package com.cameleer3.server.core.runtime;
import java.util.List;
import java.util.Map;
public record ContainerRequest(
@@ -7,9 +8,15 @@ public record ContainerRequest(
String baseImage,
String jarPath,
String network,
List<String> additionalNetworks,
Map<String, String> envVars,
Map<String, String> labels,
long memoryLimitBytes,
Long memoryReserveBytes,
int cpuShares,
int healthCheckPort
Long cpuQuota,
List<Integer> exposedPorts,
int healthCheckPort,
String restartPolicyName,
int restartPolicyMaxRetries
) {}