diff --git a/pom.xml b/pom.xml
index 90ac54e42..18cb3f7ae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,7 +86,7 @@
amazon/dynamodb-local:3.0.0@sha256:2fed5e3a965a4ba5aa6ac82baec57058b5a3848e959d705518f3fd579a77e76b
- localstack/localstack:3.5.0
+ localstack/localstack:4@sha256:5a97e0f9917a3f0d9630bb13b9d8ccf10cbe52f33252807d3b4e21418cc21348
redis:7.4-alpine@sha256:af1d0fc3f63b02b13ff7906c9baf7c5b390b8881ca08119cd570677fe2f60b55
docker.io/bitnami/redis-cluster:7.4@sha256:a53d023fdfaf8a8d7ddc58da040d3494e4cb45772644618ffa44c42dcd32b9af
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/S3LocalStackExtension.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/S3LocalStackExtension.java
index 968c4e6ea..02e8d84e8 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/S3LocalStackExtension.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/S3LocalStackExtension.java
@@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.storage;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3;
+import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
@@ -31,9 +32,16 @@ import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
public class S3LocalStackExtension implements BeforeEachCallback, AfterEachCallback, BeforeAllCallback,
AfterAllCallback {
- private final static DockerImageName LOCAL_STACK_IMAGE = DockerImageName.parse(TestcontainersImages.getLocalStack());
+ private final static DockerImageName LOCAL_STACK_IMAGE = DockerImageName.parse(TestcontainersImages.getLocalStack())
+ .asCompatibleSubstituteFor(
+ // Workaround: DockerImageName#parse does not correctly handle registry/image:tag@sha256:hash,
+ // and so it doesn't consider the image to be "localstack/localstack"
+ StringUtils.substringBefore(
+ StringUtils.substringBefore(TestcontainersImages.getLocalStack(), "@"),
+ ":"));
- private static LocalStackContainer LOCAL_STACK = new LocalStackContainer(LOCAL_STACK_IMAGE).withServices(S3);
+ private static LocalStackContainer LOCAL_STACK = new LocalStackContainer(LOCAL_STACK_IMAGE).withServices(S3)
+ .withExposedPorts(4566);
private final String bucketName;
private S3AsyncClient s3Client;