feat: DockerNetworkManager with lazy network creation and container attachment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
|||||||
|
package com.cameleer3.server.app.runtime;
|
||||||
|
|
||||||
|
import com.github.dockerjava.api.DockerClient;
|
||||||
|
import com.github.dockerjava.api.model.Network;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DockerNetworkManager {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(DockerNetworkManager.class);
|
||||||
|
public static final String TRAEFIK_NETWORK = "cameleer-traefik";
|
||||||
|
public static final String ENV_NETWORK_PREFIX = "cameleer-env-";
|
||||||
|
|
||||||
|
private final DockerClient dockerClient;
|
||||||
|
|
||||||
|
public DockerNetworkManager(DockerClient dockerClient) {
|
||||||
|
this.dockerClient = dockerClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String ensureNetwork(String networkName) {
|
||||||
|
List<Network> existing = dockerClient.listNetworksCmd()
|
||||||
|
.withNameFilter(networkName)
|
||||||
|
.exec();
|
||||||
|
|
||||||
|
for (Network net : existing) {
|
||||||
|
if (net.getName().equals(networkName)) {
|
||||||
|
return net.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String id = dockerClient.createNetworkCmd()
|
||||||
|
.withName(networkName)
|
||||||
|
.withDriver("bridge")
|
||||||
|
.withCheckDuplicate(true)
|
||||||
|
.exec()
|
||||||
|
.getId();
|
||||||
|
|
||||||
|
log.info("Created Docker network: {} ({})", networkName, id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connectContainer(String containerId, String networkName) {
|
||||||
|
String networkId = ensureNetwork(networkName);
|
||||||
|
try {
|
||||||
|
dockerClient.connectToNetworkCmd()
|
||||||
|
.withContainerId(containerId)
|
||||||
|
.withNetworkId(networkId)
|
||||||
|
.exec();
|
||||||
|
log.debug("Connected container {} to network {}", containerId, networkName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (!e.getMessage().contains("already exists")) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String envNetworkName(String envSlug) {
|
||||||
|
return ENV_NETWORK_PREFIX + envSlug;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,4 +25,12 @@ public class RuntimeOrchestratorAutoConfig {
|
|||||||
log.info("No Docker socket or K8s detected - runtime management disabled (observability-only mode)");
|
log.info("No Docker socket or K8s detected - runtime management disabled (observability-only mode)");
|
||||||
return new DisabledRuntimeOrchestrator();
|
return new DisabledRuntimeOrchestrator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DockerNetworkManager dockerNetworkManager(RuntimeOrchestrator orchestrator) {
|
||||||
|
if (orchestrator instanceof DockerRuntimeOrchestrator docker) {
|
||||||
|
return new DockerNetworkManager(docker.getDockerClient());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user