4 releases in a weekend: Testcontainers Java module, AWS CLI bundled, Step Functions intrinsics, RDS Data stubs. Free, open-source, MIT licensed.
TL;DR
We shipped 4 releases this weekend (v1.2.6 through v1.2.9):
-
org.ministack:testcontainers-ministack:0.1.0on Maven Central - 62 bug fixes found by running 2,490 tests across all 41 services
- AWS CLI bundled in the Docker image β init scripts just work
- Step Functions intrinsics β 7 new functions (ArrayContains, MathAdd, UUID, etc.)
- RDS Data API stubs β test database provisioning without Docker-in-Docker
What is MiniStack?
MiniStack is a free, MIT-licensed local AWS emulator. One Docker image, one port (4566), 41 services. It started as a response to LocalStack moving core services behind a paid plan.
- Image size: 269MB (was 242MB before CLI)
- Startup time: <2 seconds
- Services: S3, DynamoDB, SQS, SNS, Lambda, Step Functions, CloudFormation, EC2, ECS, and 32 more
-
Docker:
ministackorg/ministack - GitHub: ministackorg/ministack
No license keys. No pro tiers. Just run it.
docker run -d -p 4566:4566 ministackorg/ministack
Testcontainers Module
<dependency>
<groupId>org.ministack</groupId>
<artifactId>testcontainers-ministack</artifactId>
<version>0.1.0</version>
<scope>test</scope>
</dependency>
@Testcontainers
class S3IntegrationTest {
@Container
static MiniStackContainer ministack = new MiniStackContainer("ministackorg/ministack:latest");
@Test
void shouldCreateBucketAndPutObject() {
S3Client s3 = S3Client.builder()
.endpointOverride(ministack.getEndpoint())
.credentialsProvider(ministack.getCredentialsProvider())
.region(Region.US_EAST_1)
.build();
s3.createBucket(b -> b.bucket("test-bucket"));
s3.putObject(
b -> b.bucket("test-bucket").key("hello.txt"),
RequestBody.fromString("Hello MiniStack!")
);
String body = s3.getObjectAsBytes(
b -> b.bucket("test-bucket").key("hello.txt")
).asUtf8String();
assertEquals("Hello MiniStack!", body);
}
}
Works with JUnit 5 and Spring Boot's @DynamicPropertySource. The container starts in under 2 seconds.
AWS CLI Bundled (v1.2.9)
The Docker image now ships with AWS CLI v1. Init scripts just work without any credential configuration:
# ready.d/01-create-resources.sh
aws s3 mb s3://my-bucket
aws sqs create-queue --queue-name my-queue
# ready.d/02-seed-data.py
import boto3, os
s3 = boto3.client("s3", endpoint_url=os.environ["AWS_ENDPOINT_URL"])
s3.put_object(Bucket="my-bucket", Key="config.json", Body=b'{"env": "local"}')
Both .sh and .py init scripts are supported. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION, and AWS_ENDPOINT_URL are automatically set for init scripts.
The Flea Hunt: 62 Bugs Found and Fixed
We ran what we call a "Flea Hunt" β 2,490 tests across all 41 services using 10 parallel MiniStack instances. Some highlights:
-
S3 versioning β
GetObjectbyVersionIdwas returning the wrong version. Delete markers were missing entirely fromListObjectVersions. -
Lambda β internal
_request_idwas leaking into handler events.PublishVersionARN was missing the:versionqualifier. - DynamoDB β Go SDK v2 requires a CRC32 header on every response. Without it, the SDK throws an integrity error before your code sees anything.
-
Java SDK v2 β
time.time()floats in scientific notation broke the timestamp parser across 14 services. Fixed withint(time.time()). - EC2 β TagSpecifications were silently ignored on 11 create operations. DeleteVpc succeeded even with subnets attached.
After the fixes: 1,327 regression tests (1,196 Python + 131 Java), zero failures.
Quick Start
Docker:
docker run -d -p 4566:4566 ministackorg/ministack
Terraform:
provider "aws" {
endpoints {
s3 = "http://localhost:4566"
dynamodb = "http://localhost:4566"
sqs = "http://localhost:4566"
}
region = "us-east-1"
access_key = "test"
secret_key = "test"
}
Links
- Website: ministack.org
- GitHub: ministackorg/ministack
- Docker Hub: ministackorg/ministack
- Maven Central:
org.ministack:testcontainers-ministack:0.1.0
If you give it a try, open an issue or tell us which service you want improved next.
MiniStack is MIT licensed. Star us on GitHub if this saves you from mocking AmazonS3Client one more time.













