Just spend a day making it right. Here we go!
The goal is: run docker-compose with localstack, create S3 bucket s3://this-is-my-bucket and copy over some json files from project source
LOCALSTACK_BUILD_VERSION: latest today, 2.1.1.dev
Docker compose:
localstack:
image: localstack/localstack:latest
networks:
- hmpps
container_name: localstack
ports:
- "4566-4597:4566-4597"
- 8999:8080
- 9080:9080
environment:
- SERVICES=s3
- PORT_WEB_UI=9080
- DEBUG=${DEBUG- }
- DATA_DIR=/tmp/localstack/data
- DOCKER_HOST=unix:///var/run/docker.sock
- DEFAULT_REGION=eu-west-2
volumes:
- "./src/test/resources/test-data:/tmp/localstack/test-data"
- "$PWD/src/test/resources/localstack/setup-s3.sh:/etc/localstack/init/ready.d/init-aws.sh"
- "/var/run/docker.sock:/var/run/docker.sock"
Two important things here:
- src/test/resources/test-data - is the source folder for your json files
- src/test/resources/localstack/setup-s3.sh - is a script file to run during docker-compose

Script file setup-s3.sh
#!/usr/bin/env bash
set -e
export TERM=ansi
export AWS_ACCESS_KEY_ID=foobar
export AWS_SECRET_ACCESS_KEY=foobar
export AWS_DEFAULT_REGION=eu-west-2
export PAGER=
echo "S3 Configuration started"
aws --endpoint-url=http://localhost:4566 s3 mb s3://this-is-my-bucket
aws --endpoint-url=http://localhost:4566 s3 cp /tmp/localstack/test-data/ s3://this-is-my-bucket/chart --recursive
echo "S3 Configured"
Look at "--recursive" param for "aws cp" command.
That took us 4 hours!
Does not work without "--recursive". Crazy!
logstack docker logs:
2023-06-22 17:07:00 S3 Configuration started
2023-06-22 17:07:01 2023-06-22T16:07:01.070 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.CreateBucket => 200
2023-06-22 17:07:01 make_bucket: this-is-my-bucket
2023-06-22 17:07:01 2023-06-22T16:07:01.431 INFO --- [ asgi_gw_0] localstack.request.aws : AWS s3.PutObject => 200
upload: ../../../tmp/localstack/test-data/1a.json to s3://this-is-my-bucket/chart/1a.json
2023-06-22 17:07:01 S3 Configured
UI for localstack S3 buckets is here
http://s3.localhost.localstack.cloud:4566/this-is-my-bucket

Not sure if required, we have application-test.yml properties
aws:
region-name: eu-west-2
endpoint-url: "http://localhost:4566"
access_key: foobar
secret_access_key: foobar
s3:
access_key: foobar
secret_access_key: foobar
bucket_name: this-is-my-bucket
Next goal is to write an integration test, point to localstack s3://this-is-my-bucket bucket, load "chart/1a.json" file, and run the assertion magic.
Thanks!