Oggigiorno tutte le applicazione girano nel cloud. La sfida per gli sviluppatori è quella di replicare un ambiente cloud in locale, in modo tale da poter sviluppare e testare le applicazioni velocemente senza la necessità di rilasciare ogni volta nel cloud per ogni micro-sviluppo.

In questo tutorial vedremo come replicare un ambiente cloud AWS in locale utilizzando Floci. Trovi il repository del tutorial a questo link: https://github.com/vincenzo-racca/floci-aws-local.

Floci supporta non solo AWS ma anche Azure e GCP. In questo tutorial ci concentreremo solo su AWS.

Perché Floci al posto di LocalStack

In passato ho già parlato di come replicare un ambiente AWS per lo sviluppo in locale (Come utilizzare Spring Cloud AWS con LocalStack: Costruire e testare le applicazioni AWS in locale) e per i test di integrazione (Integration test per DynamoDB con Spring Boot, Testcontainers e Localstack).

Prima del 23 marzo 2026, LocalStack aveva una versione Community (free) e una versione Pro (a pagamento).
Dal 23 marzo 2026, LocalStack ha ufficialmente abbandonato la versione Community. Al suo posto è arrivata una versione unificata che richiede un account e la versione free (chiamata Hobby) non permette l'utilizzo commerciale. Inoltre per utilizzare la versione aggiornata in un contesto aziendale serve una licenza che autorizzi tale utilizzo (per saperne di più: Important Updates to Pricing & Packaging for LocalStack for AWS).

Servizi AWS supportati da Floci

Alla stesura di questo articolo, Floci integra ben 125 servizi AWS, da quelli più comuni come S3, DynamoDB, SQS, Lambda, a quelli più complessi come Step Functions, EventBridge, Kinesis e Athena. Puoi vedere la lista aggiornata dei servizi supportati da Floci a questo link: https://floci.io/aws/#services.

Floci meglio di LocalStack

L'immagine del container di Floci è più leggera di quella di Localstack (400 MB Di Localstack circa contro i 90 MB circa di Floci).
In un ambiente serverless come CodeBuild, significa tempi di pull dell'immagine più rapidi.
Inoltre Floci è più veloce di LocalStack nello startup di 138 volte e consuma il 91% in meno di memoria (https://floci.io/aws/compare/).

Migrazione da LocalStack a Floci per lo sviluppo locale

Nell'articolo dedicato a Localstack per lo sviluppo locale, avevamo il seguente file docker compose:

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"

Il file init-aws.sh inizializzava le risorse AWS locali usando 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

Per convertire il file docker compose in modo tale da utilizzare Floci al posto di LocalStack, basta cambiare solo l'immagine del container:

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"

Fatto! Floci è compatible con properties, paths, envs di Localstack, quindi è necessario cambiare solo l'immagine.

Abbiamo utilizzato l'immagine floci/floci:2.2.0-compat al posto di floci/floci:2.2.0 perché la versione compat contiene strumenti aggiuntivi per inizializzare l'infrastruttura, come la AWS CLI e boto3.

Aggiunta della UI di Floci

Possiamo aggiungere nel file docker compose anche il container della UI di Floci, che ci permette di interagire con le risorse AWS locali tramite un'interfaccia web (all'URL 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
Floci UI: tabella DynamoDB person in modalità chiaraFloci UI: tabella DynamoDB person in modalità scura

Migrazione da LocalStack a Floci per i test di integrazione

Nell'articolo dedicato ai test di integrazione con LocalStack e Testcontainers, avevamo creato un file di configurazione di test che permetteva a più test di condividere lo stesso container di LocalStack, evitando di doverlo avviare e fermare per ogni test. Il file di configurazione era il seguente:

@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());
    }
}

Per migrare a Floci, dobbiamo innanzitutto aggiungere la dipendenza di Floci per Testcontainers nel file pom.xml:

<dependency>
    <groupId>io.floci</groupId>
    <artifactId>testcontainers-floci</artifactId>
    <version>2.16.1</version>
    <scope>test</scope>
</dependency>

Il file di configurazione dei test diventa:

@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());
    }
}

Come possiamo vedere, anche questa volta la migrazione riguarda solo la sostituzione dell'immagine di LocalStack con quella di Floci.

Nel repository GitHub del tutorial, viene mostrata una classe che usa questa configurazione tramite l'annotation @Import(FlociConfiguration.class).

Conclusioni

In questo tutorial abbiamo visto come replicare un ambiente cloud AWS in locale utilizzando Floci.
Abbiamo visto anche come utilizzare Floci con Testcontainers per i test di integrazione.
Infine, abbiamo visto come la migrazione di un progetto da LocalStack a Floci, sia davvero semplice, in quanto Floci è compatibile con le properties, paths ed envs di LocalStack.