or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

aws-sdk-integration.mdaws-services.mdcontainer-configuration.mdendpoint-configuration.mdindex.mdnetwork-configuration.md
tile.json

index.mddocs/

LocalStack Testcontainers Module

The LocalStack Testcontainers module provides a Java library that enables developers to create and manage LocalStack containers for testing AWS service integrations. LocalStack is a fully functional local AWS cloud stack emulator that allows developers to develop and test cloud and serverless applications locally without connecting to actual AWS services.

This module wraps LocalStack in a Docker container managed by Testcontainers, providing a simple Java API to start LocalStack instances with specific AWS services enabled (S3, SQS, Lambda, DynamoDB, etc.), configure endpoints and credentials, and integrate seamlessly with JUnit tests.

Key Information for Agents

Required Dependencies:

  • org.testcontainers:localstack (this package)
  • org.testcontainers:testcontainers is required (provided transitively)
  • Docker must be installed and running
  • AWS SDK v1 or v2 (depending on usage) is required for client operations (not provided by testcontainers)
  • JUnit 4 or JUnit 5 (optional, for test framework integration)

Default Behaviors:

  • Default port: 4566 (LocalStack edge port, automatically exposed and mapped to random host port)
  • Default image: Must be specified in constructor (typically localstack/localstack:2.0 or localstack/localstack:latest)
  • Default credentials: Access key "test", secret key "test" (can be overridden via environment variables)
  • Default region: "us-east-1" (can be overridden via DEFAULT_REGION environment variable)
  • Default services: None (must be specified with withServices() for versions < 0.13; optional for versions >= 0.13)
  • Health check: Waits for "Ready." log message before start() returns
  • Startup timeout: Inherited from GenericContainer (typically 60 seconds, configurable)
  • Port mapping: Random available ports on host (use getEndpoint() to retrieve)
  • Container reuse: Not enabled by default (new container per test)
  • Network isolation: Each container runs in isolated network by default
  • Version detection: Automatically detects LocalStack version from image tag to configure legacy mode
  • Endpoint format: Returns IP address (not hostname) for proper S3 path-style access
  • Legacy mode: Automatically enabled for LocalStack versions < 0.11 (each service on different port)

Threading Model:

  • Container operations are synchronous (blocking)
  • start() method blocks until container is ready
  • stop() method blocks until container is stopped
  • Container instances are not thread-safe for concurrent modification
  • Multiple containers can run concurrently in separate instances (each gets unique ports)
  • Client connections from AWS SDK are independent of container lifecycle
  • Container lifecycle methods should not be called concurrently on the same instance
  • JUnit rules handle lifecycle automatically (start before tests, stop after)

Lifecycle:

  • Container must be started with localstack.start() before use
  • Container automatically waits for "Ready." log message before start() returns
  • Container must be stopped with localstack.stop() for cleanup
  • Always stop containers in finally blocks or use test framework cleanup hooks
  • Container stops automatically when JVM exits (if not explicitly stopped)
  • Failed containers may leave Docker resources; always call stop() even on errors
  • Use JUnit @ClassRule or @Container for automatic lifecycle management (recommended)
  • getEndpoint() and credential methods can only be called after start() completes
  • Services start lazily (versions >= 0.13) or eagerly (versions < 0.13) based on configuration

Exceptions:

  • ContainerLaunchException - Container failed to start (timeout, image pull failure, etc.)
  • IllegalStateException - Called getEndpoint() before container started, or network configuration error
  • IllegalArgumentException - Invalid Docker image name or service configuration
  • PortBindingException - Port binding conflicts
  • DockerNotAvailableException - Docker daemon not accessible
  • ImagePullException - Failed to pull Docker image
  • TimeoutException - Container startup timeout (container started but not ready)
  • AWS SDK exceptions - Service-specific errors (S3, SQS, etc.) from AWS SDK clients
  • SdkClientException (SDK v2) - Connection failures, authentication errors
  • AmazonClientException (SDK v1) - Connection failures, authentication errors

Edge Cases:

  • Port conflicts: Testcontainers automatically finds available ports, but conflicts can occur in CI/CD
  • Image pull failures: Network issues or invalid image tags cause startup failures
  • Startup timeouts: Slow container startup may exceed timeout (adjust with withStartupTimeout())
  • Multiple containers: Each container gets unique ports; coordinate if testing multi-container scenarios
  • Container reuse: Enable with withReuse(true) to reuse containers across test runs (requires testcontainers configuration)
  • Network isolation: Containers cannot communicate by default; use withNetwork() and withNetworkAliases() for multi-container tests
  • Resource cleanup: Always stop containers even if tests fail; use try/finally or test framework hooks
  • Concurrent tests: Each test should use separate container instances to avoid port conflicts
  • CI/CD environments: May require Docker-in-Docker or remote Docker configuration
  • Legacy mode: Services use different ports (< 0.11); use getEndpointOverride(Service) for service-specific endpoints
  • S3 path-style access: getEndpoint() returns IP address to ensure path-style access works correctly
  • Service availability: Some services require LocalStack Pro (e.g., X-Ray, AppSync, QLDB)
  • Lazy service loading: Services start on first API call (versions >= 0.13); may cause first request to be slow
  • Credential override: Environment variables override defaults; check getAccessKey() after start to verify
  • Region override: DEFAULT_REGION environment variable overrides default region
  • Network aliases: Last alias in withNetworkAliases() is used as HOSTNAME_EXTERNAL or LOCALSTACK_HOST
  • Version detection: Image tag parsing may fail for non-standard tags; use explicit version tags
  • Endpoint resolution: getEndpoint() resolves hostname to IP; may fail if DNS resolution issues
  • Service-specific endpoints: In legacy mode, each service has different port; use getEndpointOverride(Service)
  • Container restart: Data persists within container lifecycle; lost on container stop (unless using persistence volumes)
  • Lambda container labels: LocalStack automatically labels spawned Lambda containers for cleanup
  • S3 signature validation: May need S3_SKIP_SIGNATURE_VALIDATION=1 for some SDK configurations
  • LocalStack Pro: Requires LOCALSTACK_API_KEY environment variable for Pro features

Common Pitfalls:

  • Forgetting to call start() before using container (causes IllegalStateException)
  • Using hostname instead of IP in endpoint (causes S3 path-style access failures)
  • Not stopping container in finally block (leaves Docker resources)
  • Using wrong endpoint format for Docker network (should use network alias, not getEndpoint())
  • Forgetting to specify services for LocalStack < 0.13 (causes startup failure)
  • Using deprecated constructors (may break in future versions)
  • Not handling IllegalStateException from getEndpoint() if container fails to start
  • Assuming all services available in Community edition (some require Pro)
  • Not waiting for container ready state (may cause race conditions)
  • Using localhost in endpoint URL (should use IP from getEndpoint())
  • Not configuring credentials provider correctly (causes authentication errors)
  • Mixing SDK v1 and v2 patterns (inconsistent behavior)
  • Not handling version-specific behavior differences (legacy vs modern mode)

Package Information

  • Package Name: org.testcontainers:localstack
  • Package Type: Maven
  • Language: Java
  • Installation:
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>localstack</artifactId>
        <version>1.21.4</version>
        <scope>test</scope>
    </dependency>

For Gradle:

testImplementation 'org.testcontainers:localstack:1.21.4'

Core Imports

import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.containers.localstack.LocalStackContainer.Service;
import org.testcontainers.containers.localstack.LocalStackContainer.EnabledService;
import org.testcontainers.utility.DockerImageName;

Basic Usage

Simple Example with S3 and SQS

import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.containers.localstack.LocalStackContainer.Service;
import org.testcontainers.utility.DockerImageName;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;

// Create and start LocalStack container
LocalStackContainer localstack = new LocalStackContainer(
    DockerImageName.parse("localstack/localstack:2.0")
)
    .withServices(Service.S3, Service.SQS);

localstack.start();

try {
    // Get configuration for AWS SDK clients
    String endpoint = localstack.getEndpoint().toString();
    String accessKey = localstack.getAccessKey();
    String secretKey = localstack.getSecretKey();
    String region = localstack.getRegion();

    // Use with AWS SDK v2
    S3Client s3 = S3Client.builder()
        .endpointOverride(localstack.getEndpoint())
        .credentialsProvider(
            StaticCredentialsProvider.create(
                AwsBasicCredentials.create(accessKey, secretKey)
            )
        )
        .region(Region.of(region))
        .build();

    // Create a bucket and use S3
    s3.createBucket(b -> b.bucket("test-bucket"));
} finally {
    localstack.stop();
}

JUnit Integration

import org.junit.ClassRule;
import org.junit.Test;
import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.containers.localstack.LocalStackContainer.Service;
import org.testcontainers.utility.DockerImageName;

public class MyAwsIntegrationTest {

    @ClassRule
    public static LocalStackContainer localstack = new LocalStackContainer(
        DockerImageName.parse("localstack/localstack:2.0")
    )
        .withServices(Service.S3, Service.DYNAMODB, Service.LAMBDA);

    @Test
    public void testS3Operations() {
        // Container automatically started before test
        // Test code using localstack.getEndpoint(), etc.
        // Container automatically stopped after test
    }
}

Architecture

The LocalStack Testcontainers module is built around several key components:

  • LocalStackContainer Class: Main entry point extending GenericContainer, providing fluent configuration API
  • Service Enumeration: Predefined AWS services (S3, SQS, Lambda, DynamoDB, etc.) with service names and legacy port mappings
  • EnabledService Interface: Flexible interface allowing custom service names beyond the predefined enum
  • Version Detection: Automatic detection of LocalStack version to determine legacy mode vs single-port mode
  • Network Integration: Support for both bridge networking (host access) and Docker networks (container-to-container)
  • Credential Management: Provides default test credentials and region configuration
  • Container Lifecycle: Inherits full Testcontainers lifecycle management (start, stop, configuration)

Version Compatibility

The module automatically adapts to different LocalStack versions:

  • Versions < 0.11: Legacy mode with each service on a different port (4567-4599)
  • Versions >= 0.11: Single-port mode with all services on port 4566
  • Versions >= 0.13: Optional services list (lazy loading)
  • Versions >= 2.0: Uses LOCALSTACK_HOST environment variable (instead of deprecated HOSTNAME_EXTERNAL)

Capabilities

Container Configuration

Create and configure LocalStack containers with specific services, environment variables, and Docker settings.

/**
 * Creates a LocalStack container with the specified Docker image
 * @param dockerImageName Docker image name for LocalStack (e.g., "localstack/localstack:2.0")
 */
public LocalStackContainer(DockerImageName dockerImageName);

/**
 * Creates a LocalStack container with default image and default tag
 * @deprecated Use LocalStackContainer(DockerImageName) instead
 */
@Deprecated
public LocalStackContainer();

/**
 * Creates a LocalStack container with default image and specified version
 * @param version Version tag for LocalStack
 * @deprecated Use LocalStackContainer(DockerImageName) instead
 */
@Deprecated
public LocalStackContainer(String version);

/**
 * Declares AWS services to be launched by the container
 * @param services One or more Service enum values
 * @return This container object for method chaining
 */
public LocalStackContainer withServices(Service... services);

/**
 * Declares AWS services using the EnabledService interface (for custom services)
 * @param services One or more EnabledService implementations
 * @return This container object for method chaining
 */
public LocalStackContainer withServices(EnabledService... services);

Container Configuration

Endpoint Configuration

Retrieve endpoint URLs and credentials for configuring AWS SDK clients to communicate with LocalStack.

/**
 * Provides the main endpoint to communicate with LocalStack
 * Intended for AWS SDK clients running on the test host
 * @return URI endpoint with host IP and mapped port
 * @throws IllegalStateException if cannot obtain endpoint URL
 */
public URI getEndpoint();

/**
 * Provides endpoint override for a specific service
 * Useful in legacy mode where services have different ports
 * @param service The AWS service to access
 * @return URI endpoint override for the service
 * @throws IllegalStateException if cannot obtain endpoint URL
 */
public URI getEndpointOverride(EnabledService service);

/**
 * Provides default AWS access key ID for LocalStack
 * @return Access key (default: "test", or from AWS_ACCESS_KEY_ID env var)
 */
public String getAccessKey();

/**
 * Provides default AWS secret access key for LocalStack
 * @return Secret key (default: "test", or from AWS_SECRET_ACCESS_KEY env var)
 */
public String getSecretKey();

/**
 * Provides default AWS region for LocalStack
 * @return Region (default: "us-east-1", or from DEFAULT_REGION env var)
 */
public String getRegion();

Endpoint Configuration

AWS Services

Predefined AWS services that can be enabled in LocalStack, with support for custom service names.

/**
 * Predefined AWS services supported by LocalStack
 */
public enum Service implements EnabledService {
    S3,              // Amazon S3 object storage
    SQS,             // Amazon SQS message queuing
    DYNAMODB,        // Amazon DynamoDB NoSQL database
    LAMBDA,          // AWS Lambda serverless functions
    SNS,             // Amazon SNS pub/sub messaging
    KINESIS,         // Amazon Kinesis streaming
    CLOUDFORMATION,  // AWS CloudFormation infrastructure as code
    CLOUDWATCH,      // Amazon CloudWatch monitoring
    CLOUDWATCHLOGS,  // Amazon CloudWatch Logs
    SECRETSMANAGER,  // AWS Secrets Manager
    KMS,             // AWS Key Management Service
    IAM,             // AWS Identity and Access Management
    STS,             // AWS Security Token Service
    SSM,             // AWS Systems Manager Parameter Store
    // ... and more (see full list in documentation)
}

/**
 * Interface for enabled services, allows custom service names
 */
public interface EnabledService {
    /**
     * Returns the LocalStack service name
     */
    String getName();

    /**
     * Returns the port for the service (default: 4566)
     */
    default int getPort() {
        return 4566;
    }

    /**
     * Creates an EnabledService with a custom name
     * @param name The LocalStack service name
     * @return EnabledService instance
     */
    static EnabledService named(String name);
}

AWS Services

AWS SDK Integration

Examples and patterns for integrating with AWS SDK v1 and v2.

AWS SDK Integration

Network Configuration

Advanced Docker networking setup for container-to-container communication.

Network Configuration