Nowadays, applications run in the cloud. The challenge for developers is to replicate a cloud environment locally so they can develop and test applications quickly without deploying to the cloud after every small change.
In this tutorial, we'll see how to replicate an AWS cloud environment locally using Floci. You can find the tutorial repository here: https://github.com/vincenzo-racca/floci-aws-local.
Why Floci instead of LocalStack
I've previously covered how to replicate an AWS environment for local development (How to Use Spring Cloud AWS with LocalStack: Build and Test AWS Applications Locally) and for integration testing (Integration tests for DynamoDB with Spring Boot, Testcontainers, and Localstack).
Before March 23, 2026, LocalStack offered a free Community version and a paid Pro version.
On March 23, 2026, LocalStack officially discontinued the Community version. It was replaced by a
unified version that requires an account, and the free version (called Hobby) does not allow commercial use.
Using the updated version in a business context also requires a license that permits such use
(for more details, see Important Updates to Pricing & Packaging for LocalStack for AWS).
AWS services supported by Floci
At the time of writing, Floci supports 125 AWS services, from common ones such as S3, DynamoDB, SQS, and Lambda to more complex ones such as Step Functions, EventBridge, Kinesis, and Athena. You can find the current list of supported services here: https://floci.io/aws/#services.
Floci compared with LocalStack
The Floci container image is smaller than the LocalStack image (about 90 MB versus about 400 MB).
In a serverless environment such as CodeBuild, this means faster image pulls.
Floci also starts 138 times faster than LocalStack and uses 91% less memory (https://floci.io/aws/compare/).
Migrating from LocalStack to Floci for local development
In the article about using LocalStack for local development, we had the following Docker Compose file:
services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-4.0.3}"
image: localstack/localstack:4.0.3
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
- "127.0.0.1:4510-4559:4510-4559" # external services port range
environment:
- DEBUG=${DEBUG:-0}
- AWS_ACCESS_KEY_ID=test
- AWS_SECRET_ACCESS_KEY=test
- AWS_DEFAULT_REGION=us-east-1
volumes:
- "./config/init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh" # ready hook
- "/var/run/docker.sock:/var/run/docker.sock"
The init-aws.sh file initialized the local AWS resources using the AWS CLI:
#!/bin/bash
echo "Create SQS queue"
aws sqs create-queue --queue-name book-event-queue --endpoint-url http://localhost:4566
echo "Create DynamoDB table"
aws dynamodb create-table \
--table-name person \
--attribute-definitions \
AttributeName=id,AttributeType=S \
--key-schema \
AttributeName=id,KeyType=HASH \
--provisioned-throughput \
ReadCapacityUnits=5,WriteCapacityUnits=5 \
--endpoint-url http://localhost:4566
echo "Create Parameter Store"
aws ssm put-parameter \
--name "/config/localstack/env-value" \
--value "local" \
--type String \
--endpoint-url http://localhost:4566
To convert the Docker Compose file to use Floci instead of LocalStack, we only need to change the container image:
services:
aws-local:
container_name: "floci"
image: floci/floci:2.2.0-compat
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
- "127.0.0.1:4510-4559:4510-4559" # external services port range
environment:
- DEBUG=${DEBUG:-0}
- AWS_ACCESS_KEY_ID=test
- AWS_SECRET_ACCESS_KEY=test
- AWS_DEFAULT_REGION=us-east-1
volumes:
- "./config/init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh" # ready hook
- "/var/run/docker.sock:/var/run/docker.sock"
That's it! Floci is compatible with LocalStack's properties, paths, and environment variables, so only the image needs to change.
Adding the Floci UI
We can also add the Floci UI container to the Docker Compose file. It lets us interact with local AWS resources through a web interface at localhost:4500:
floci-ui:
container_name: "floci-ui"
image: floci/floci-ui:0.6.0
ports:
- "127.0.0.1:4500:4500"
environment:
- AWS_ACCESS_KEY_ID=test
- AWS_SECRET_ACCESS_KEY=test
- AWS_REGION=us-east-1
- FLOCI_ENDPOINT=http://aws-local:4566
depends_on:
- aws-local


Migrating from LocalStack to Floci for integration testing
In the article about integration testing with LocalStack and Testcontainers, we created a test configuration file that allowed multiple tests to share the same LocalStack container instead of starting and stopping it for each test. The configuration file was as follows:
@TestConfiguration
public class LocalStackConfiguration {
static LocalStackContainer localStack =
new LocalStackContainer(DockerImageName.parse("localstack/localstack:4.0.3"))
.withFileSystemBind(Path.of("config", "init-aws.sh").toAbsolutePath().toString(),
"/etc/localstack/init/ready.d/init-aws.sh", BindMode.READ_ONLY)
.withNetworkAliases("localstack")
.withEnv("AWS_ACCESS_KEY_ID", "test")
.withEnv("AWS_SECRET_ACCESS_KEY", "test")
.withEnv("AWS_DEFAULT_REGION", "us-east-1");
static {
localStack.start();
System.setProperty("spring.cloud.aws.endpoint", localStack.getEndpoint().toString());
}
}
To migrate to Floci, we first need to add the Floci Testcontainers dependency to pom.xml:
<dependency>
<groupId>io.floci</groupId>
<artifactId>testcontainers-floci</artifactId>
<version>2.16.1</version>
<scope>test</scope>
</dependency>
The test configuration file becomes:
@TestConfiguration
public class FlociConfiguration {
static final FlociContainer flociContainer =
new FlociContainer(DockerImageName.parse("floci/floci:2.2.0-compat"))
.withFileSystemBind(Path.of("config", "init-aws.sh").toAbsolutePath().toString(),
"/etc/localstack/init/ready.d/init-aws.sh", BindMode.READ_ONLY)
.withEnv("AWS_ACCESS_KEY_ID", "test")
.withEnv("AWS_SECRET_ACCESS_KEY", "test")
.withEnv("AWS_DEFAULT_REGION", "us-east-1");
static {
flociContainer.start();
System.setProperty("spring.cloud.aws.endpoint", flociContainer.getEndpoint());
}
}
As we can see, the migration again involves replacing the LocalStack image with the Floci image.
The tutorial's GitHub repository shows a class that uses this configuration through the @Import(FlociConfiguration.class) annotation.
Conclusions
In this tutorial, we've seen how to replicate an AWS cloud environment locally using Floci.
We've also seen how to use Floci with Testcontainers for integration testing.
Finally, we've seen how straightforward it is to migrate a project from LocalStack to Floci, since Floci is compatible with LocalStack's properties, paths, and environment variables.
Comments