Skip to content

feat: integrate ContainerDetector for improved container detection in ElastiCache, ECS, and RDS managers#343

Merged
hectorvent merged 1 commit intofloci-io:mainfrom
cfranzen:feat/container-detector
Apr 11, 2026
Merged

feat: integrate ContainerDetector for improved container detection in ElastiCache, ECS, and RDS managers#343
hectorvent merged 1 commit intofloci-io:mainfrom
cfranzen:feat/container-detector

Conversation

@cfranzen
Copy link
Copy Markdown
Contributor

Summary

Added ContainerDetector for improved detection if Floci is running inside a container. All services that start up container backends use this detector now.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

AWS Compatibility

Not requied

Checklist

  • ./mvnw test passes locally
  • New or updated integration test added
  • Commit messages follow Conventional Commits

Copilot AI review requested due to automatic review settings April 10, 2026 21:34
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a centralized ContainerDetector to determine whether Floci is running inside a container, and wires that detection into container-backend startup logic (ElastiCache, ECS, RDS) and Docker host resolution.

Changes:

  • Added ContainerDetector with multiple heuristics (marker files, env vars, cgroup, mountinfo) and a cached result.
  • Updated ElastiCache/ECS/RDS container managers to use ContainerDetector to decide between host port publishing vs using container IPs.
  • Moved/updated DockerHostResolver to rely on ContainerDetector, and added unit tests for container detection.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/main/java/io/github/hectorvent/floci/core/common/docker/ContainerDetector.java New container-runtime detection utility with cached evaluation.
src/test/java/io/github/hectorvent/floci/core/common/docker/ContainerDetectorTest.java Unit tests covering the detection heuristics and caching behavior.
src/main/java/io/github/hectorvent/floci/core/common/docker/DockerHostResolver.java Uses ContainerDetector instead of ad-hoc marker/cgroup logic to pick container-to-host address.
src/main/java/io/github/hectorvent/floci/services/elasticache/container/ElastiCacheContainerManager.java Uses ContainerDetector to choose port binding vs container IP for backend connectivity.
src/main/java/io/github/hectorvent/floci/services/ecs/container/EcsContainerManager.java Uses ContainerDetector to decide whether to publish ports and how to compute network bindings.
src/main/java/io/github/hectorvent/floci/services/rds/container/RdsContainerManager.java Uses ContainerDetector to choose port binding vs container IP for backend connectivity.
src/main/java/io/github/hectorvent/floci/services/lambda/launcher/ContainerLauncher.java Updates import to the new DockerHostResolver package.
Comments suppressed due to low confidence (3)

src/main/java/io/github/hectorvent/floci/services/elasticache/container/ElastiCacheContainerManager.java:171

  • When a user configures dockerNetwork/networkMode as host, Docker rejects containers that also specify port bindings ("conflicting options: port publishing and the container type network mode"). With the new !containerDetector.isRunningInContainer() condition, port bindings are now added for all host runs, which can break the previously-working networkMode=host setup on native Linux. Consider skipping port bindings when the configured network mode is host (and other incompatible modes), or compute the bind/inspect strategy after resolving the effective network mode instead of basing it solely on isRunningInContainer().
    private HostConfig buildHostConfig() {
        HostConfig hostConfig = HostConfig.newHostConfig();
        if (!containerDetector.isRunningInContainer()) {
            // Bind BACKEND_PORT → random host port so the JVM can reach the container
            int freePort = findFreePort();
            Ports portBindings = new Ports();
            portBindings.bind(ExposedPort.tcp(BACKEND_PORT), Ports.Binding.bindPort(freePort));
            hostConfig.withPortBindings(portBindings);
            LOG.debugv("Native mode: binding container port 6379 → host port {0}", freePort);

src/main/java/io/github/hectorvent/floci/services/rds/container/RdsContainerManager.java:174

  • Same issue as ElastiCache: if dockerNetwork/networkMode is set to host, Docker does not allow port bindings. Since port bindings are now applied whenever Floci is not running in a container, starting an RDS backend with networkMode=host can fail on native Linux. Please gate port-binding logic on the effective network mode (skip for host/other incompatible modes) rather than only on isRunningInContainer().
    private HostConfig buildHostConfig(int enginePort) {
        HostConfig hostConfig = HostConfig.newHostConfig();
        if (!containerDetector.isRunningInContainer()) {
            int freePort = findFreePort();
            Ports portBindings = new Ports();
            portBindings.bind(ExposedPort.tcp(enginePort), Ports.Binding.bindPort(freePort));
            hostConfig.withPortBindings(portBindings);
            LOG.debugv("Native mode: binding container port {0} → host port {1}", enginePort, freePort);
        }

src/main/java/io/github/hectorvent/floci/services/ecs/container/EcsContainerManager.java:183

  • Port bindings are applied whenever Floci is not running in a container, but Docker forbids publishing ports when HostConfig.networkMode is host. Since the ECS container network mode can be set via config, this can make task startup fail for dockerNetwork=host on native Linux. Consider determining the effective network mode first and skipping withPortBindings(...) when it is host (or other incompatible modes).
    private HostConfig buildHostConfig(ContainerDefinition def, List<ExposedPort> exposedPorts) {
        HostConfig hostConfig = HostConfig.newHostConfig();

        if (def.getMemory() != null) {
            hostConfig.withMemory((long) def.getMemory() * 1024 * 1024);
        }

        if (!containerDetector.isRunningInContainer() && !exposedPorts.isEmpty()) {
            Ports portBindings = new Ports();
            for (ExposedPort ep : exposedPorts) {
                portBindings.bind(ep, Ports.Binding.bindPort(0)); // 0 = dynamic host port
            }
            hostConfig.withPortBindings(portBindings);
        }

Copy link
Copy Markdown
Collaborator

@hectorvent hectorvent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @cfranzen

@hectorvent
Copy link
Copy Markdown
Collaborator

@cfranzen conflicts need to be resolved

@cfranzen cfranzen force-pushed the feat/container-detector branch from 7ee80e1 to d87ee89 Compare April 11, 2026 15:37
@cfranzen
Copy link
Copy Markdown
Contributor Author

@hectorvent just resolved it a minute ago

@hectorvent hectorvent self-assigned this Apr 11, 2026
@hectorvent hectorvent merged commit bc45823 into floci-io:main Apr 11, 2026
10 checks passed
@cfranzen cfranzen deleted the feat/container-detector branch April 11, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants