Skip to content

hx deploy doesn't handle multiple EXPOSE ports #247

Description

@half-ogre

Description

When a Docker image has multiple exposed ports (e.g., from a base image like nginx:alpine which has EXPOSE 80 plus a user-added EXPOSE 8080), hx extracts ports by iterating over a Go map build from the results f docker inspect, resulting in non-deterministic port ordering. Since the deployment uses ports[0], any of the ports might get used.

Steps to Reproduce

  1. Create a Dockerfile using nginx:alpine as base (which has EXPOSE 80)
  2. Add EXPOSE 8080 to the Dockerfile
  3. Run hx deploy multiple times

Expected Behavior

The user-specified port (8080) should be consistently used.

Actual Behavior

Sometimes port 80 is selected, sometimes port 8080, depending on Go's map iteration order at runtime.

Root Cause

In internal/build/service.go, ports are extracted by iterating over inspectData.Config.ExposedPorts:

ports := make([]int, 0)
for port := range inspectData.Config.ExposedPorts {
    // ...
    ports = append(ports, portInt)
}

Go maps have undefined iteration order (per the spec), so the resulting ports slice has non-deterministic ordering.

Impact

Deployments intermittently fail with errors like:

"The container X did not have a container port 8080 defined"

This happens when a previous deployment used port 8080 (lucky iteration order), but a subsequent deployment creates a task definition with port 80 (unlucky iteration order), causing a mismatch with the existing ECS service load balancer configuration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions