diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerNetworkManager.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerNetworkManager.java new file mode 100644 index 00000000..40ae28d8 --- /dev/null +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerNetworkManager.java @@ -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 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; + } +} diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java index 10c569ef..2ff23601 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java @@ -25,4 +25,12 @@ public class RuntimeOrchestratorAutoConfig { log.info("No Docker socket or K8s detected - runtime management disabled (observability-only mode)"); return new DisabledRuntimeOrchestrator(); } + + @Bean + public DockerNetworkManager dockerNetworkManager(RuntimeOrchestrator orchestrator) { + if (orchestrator instanceof DockerRuntimeOrchestrator docker) { + return new DockerNetworkManager(docker.getDockerClient()); + } + return null; + } }