Repository: localstack/localstack

Issue:
bug: PORTS_CHECK_DOCKER_IMAGE is not configurable which prevents ECS tasks from running on air-gapped environments
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

`PORTS_CHECK_DOCKER_IMAGE` is not configurable which prevents ECS tasks from running on air-gapped environment



### Expected Behavior

`PORTS_CHECK_DOCKER_IMAGE` can be configured via configuration option to allow use of any available image 

### How are you starting LocalStack?

With a docker-compose file

### Steps To Reproduce

Run an ECS task in an environment where localstack/localstack is not available.

### Environment

```markdown
- OS: RHEL8
- Docker runtime version: Podman v4.2.0
- LocalStack: 1.3.1
```


### Anything else?

_No response_


Discussion:

Resolving patch:
diff --git a/localstack/config.py b/localstack/config.py
--- a/localstack/config.py
+++ b/localstack/config.py
@@ -16,6 +16,7 @@
     DEFAULT_PORT_EDGE,
     DEFAULT_SERVICE_PORTS,
     DEFAULT_VOLUME_DIR,
+    DOCKER_IMAGE_NAME,
     ENV_INTERNAL_TEST_COLLECT_METRIC,
     ENV_INTERNAL_TEST_RUN,
     FALSE_STRINGS,
@@ -433,6 +434,11 @@ def in_docker():
 # use the command line docker client instead of the new sdk version, might get removed in the future
 LEGACY_DOCKER_CLIENT = is_env_true("LEGACY_DOCKER_CLIENT")
 
+# Docker image to use when starting up containers for port checks
+PORTS_CHECK_DOCKER_IMAGE = (
+    os.environ.get("PORTS_CHECK_DOCKER_IMAGE", "").strip() or DOCKER_IMAGE_NAME
+)
+
 # whether to forward edge requests in-memory (instead of via proxy servers listening on backend ports)
 # TODO: this will likely become the default and may get removed in the future
 FORWARD_EDGE_INMEM = True
@@ -825,6 +831,7 @@ def in_docker():
     "OUTBOUND_HTTP_PROXY",
     "OUTBOUND_HTTPS_PROXY",
     "PERSISTENCE",
+    "PORTS_CHECK_DOCKER_IMAGE",
     "REQUESTS_CA_BUNDLE",
     "S3_SKIP_SIGNATURE_VALIDATION",
     "S3_SKIP_KMS_KEY_VALIDATION",
diff --git a/localstack/utils/docker_utils.py b/localstack/utils/docker_utils.py
--- a/localstack/utils/docker_utils.py
+++ b/localstack/utils/docker_utils.py
@@ -6,7 +6,7 @@
 from typing import List, Optional
 
 from localstack import config
-from localstack.constants import DEFAULT_VOLUME_DIR, DOCKER_IMAGE_NAME
+from localstack.constants import DEFAULT_VOLUME_DIR
 from localstack.utils.container_utils.container_client import (
     ContainerClient,
     PortMappings,
@@ -17,8 +17,6 @@
 
 LOG = logging.getLogger(__name__)
 
-# Docker image to use when starting up containers for port checks
-PORTS_CHECK_DOCKER_IMAGE = DOCKER_IMAGE_NAME
 
 # port range instance used to reserve Docker container ports
 PORT_START = 1024
@@ -146,7 +144,7 @@ def container_port_can_be_bound(port: int) -> bool:
     ports.add(port, port)
     try:
         result = DOCKER_CLIENT.run_container(
-            PORTS_CHECK_DOCKER_IMAGE,
+            config.PORTS_CHECK_DOCKER_IMAGE,
             entrypoint="",
             command=["echo", "test123"],
             ports=ports,


Test patch:
diff --git a/tests/integration/docker_utils/test_docker.py b/tests/integration/docker_utils/test_docker.py
--- a/tests/integration/docker_utils/test_docker.py
+++ b/tests/integration/docker_utils/test_docker.py
@@ -11,7 +11,6 @@
 
 from localstack import config
 from localstack.config import in_docker
-from localstack.utils import docker_utils
 from localstack.utils.common import is_ipv4_address, safe_run, save_file, short_uid, to_str
 from localstack.utils.container_utils.container_client import (
     AccessDenied,
@@ -1378,7 +1377,7 @@ def test_reserve_container_port(self, docker_client, monkeypatch):
         if isinstance(docker_client, CmdDockerClient):
             pytest.skip("Running test only for one Docker executor")
 
-        monkeypatch.setattr(docker_utils, "PORTS_CHECK_DOCKER_IMAGE", "alpine")
+        monkeypatch.setattr(config, "PORTS_CHECK_DOCKER_IMAGE", "alpine")
 
         # reserve available container port
         port = reserve_available_container_port(duration=1)
@@ -1402,7 +1401,7 @@ def test_container_port_can_be_bound(self, docker_client, monkeypatch):
         if isinstance(docker_client, CmdDockerClient):
             pytest.skip("Running test only for one Docker executor")
 
-        monkeypatch.setattr(docker_utils, "PORTS_CHECK_DOCKER_IMAGE", "alpine")
+        monkeypatch.setattr(config, "PORTS_CHECK_DOCKER_IMAGE", "alpine")
 
         # reserve available container port
         port = reserve_available_container_port(duration=1)