We are developing a software product whose production environments run entirely on AWS. Keeping local development as close as possible to those environments is important to us: it reduces surprises when deploying, shortens the feedback loop when debugging infrastructure-related issues, and means developers can work confidently without needing access to a shared cloud account.
To achieve that, we needed a way to run AWS services locally — specifically EKS, ECR, RDS — in a way that behaves like the real thing. That is where floci comes in.
Floci is a fast, free, and open-source local AWS emulator. It is MIT-licensed, requires no account or token, and runs entirely on your machine. It exposes the same AWS wire protocol on localhost:4566, so your existing AWS CLI commands, SDKs, and infrastructure code work against it without any modifications.
The services I needed to get started:
Floci can be run in different ways. My first approach was using the floci-cli, which works well for quick experiments. However, for our purposes the Docker Compose setup turned out to be the better fit: it makes the configuration explicit and is easier to share across the team.
Once Floci is running via Docker Compose, configure your environment so the AWS CLI and SDKs point to it instead of real AWS:
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
These dummy credentials are all Floci needs — no real AWS account required.
Floci needs a Docker-compatible socket to spin up the container-backed services (EKS, ECR, RDS, etc.). I went through a few iterations before landing on a working setup.
My first instinct, since I’m using a Fedora setup, was to use Podman in rootless mode: more secure, no root daemon. Authentication via aws ecr get-login-password worked fine, and Floci started up cleanly. However, as soon as I tried to create an EKS cluster, I hit a wall:
Error: unable to create cluster: permission denied: /var/dmesg
Under the hood, Floci’s EKS emulation spins up a real k3s node. k3s needs access to kernel-level resources — specifically /var/dmesg — which are simply not available in a rootless container namespace. This is a kernel capability restriction, not a Floci bug.
Docker rootless mode has the same limitation: it runs with a user-mapped namespace that cannot expose the kernel interfaces k3s requires. Same error, same outcome.
Switching to Docker in rootful mode (the standard daemon running as root) resolved the issue immediately. The Floci container got the socket it needed, k3s bootstrapped successfully, and the EKS cluster came up.
With Docker rootful running and the environment variables set, creating a cluster looks exactly like it would against real AWS:
aws eks create-cluster \
--name dev-cluster \
--role-arn arn:aws:iam::000000000000:role/eks-role \
--resources-vpc-config subnetIds=subnet-00000000,securityGroupIds=sg-00000000
Floci spins up a real k3s node in the background. Within seconds, the cluster is reachable and you can configure kubectl:
aws eks update-kubeconfig --name dev-cluster
kubectl get nodes
Creating a repository is equally straightforward:
aws ecr create-repository --repository-name majesticapp/api
Floci lazily starts a real OCI-compliant registry container behind the scenes. To push images to it, authenticate first:
aws ecr get-login-password \
| podman login --tls-verify=false --username AWS --password-stdin \
000000000000.dkr.ecr.us-east-1.localhost:5100
Then tag and push your image:
podman tag majesticapp/api:latest \
000000000000.dkr.ecr.us-east-1.localhost:5100/majesticapp/api:latest
podman push --tls-verify=false \
000000000000.dkr.ecr.us-east-1.localhost:5100/majesticapp/api:latest
The images land in the local registry, fully accessible via the ECR API, exactly as they would in production.
The EKS cluster (k3s) includes a kubelet and image pull client that communicates with ECR over HTTPS. That is the production-correct behavior. The problem? Floci’s local ECR registry is served over plain HTTP.
The EKS client expects to pull images over HTTPS, but the local ECR registry is intentionally served over plain HTTP for now. This mismatch means Kubernetes refuses to pull from it, and the pods will not start.
Solving this requires one of the following approaches, to be explored in Part 2:
Stay tuned: Part 2 will cover solving the HTTPS/TLS challenge between EKS and ECR, and eventually wiring up RDS with MySQL, so we can ditch the local MySQL container entirely and replicate the same setup we already use in production.
Did you find this article interesting? Does it match your skill set? Programming is at the heart of how we develop customized solutions. In fact, we’re currently hiring for roles just like this and others here at Würth IT.