docker compose up 한 줄이면 S3·DynamoDB·Lambda·SQS 등 AWS 서비스 54개를 인증 토큰 없이 24ms 안에 시작. (저장소: floci-io/floci · Java 100% · MIT)Floci는 로컬 환경에서 AWS 서비스 54개 이상을 에뮬레이션하는 무료 오픈소스 도구입니다. docker compose up 한 줄이면 S3, DynamoDB, Lambda, SQS 등을 인증 토큰 없이 즉시 사용할 수 있습니다. Java + Quarkus + GraalVM 네이티브 이미지로 만들어져 시작 시간 24ms, 유휴 메모리 13MiB라는 극한의 경량화를 달성했습니다.
AWS에 배포하기 전에 로컬에서 테스트하려면 실제 계정이 필요하고, 실수하면 비용이 발생합니다. Floci는 AWS와 똑같이 동작하는 가짜 AWS를 내 컴퓨터 안에서 돌리는 것입니다.
AWS CLI, boto3, Terraform 등 모든 AWS 도구가 endpoint_url만 바꾸면 그대로 동작합니다. 계정, 토큰, 인터넷 연결이 필요 없습니다.
가장 유명한 AWS 로컬 에뮬레이터인 LocalStack이 커뮤니티 에디션에 인증 토큰 필수화, CI/CD 지원 중단, 보안 업데이트 동결을 단행했습니다. 수천 개의 CI/CD 파이프라인이 localstack/localstack:latest를 pull하는 순간 깨졌습니다.
Floci는 계정, 토큰, 텔레메트리가 일체 불필요합니다. LocalStack CE 대비 138배 빠른 시작, 11배 적은 메모리, MIT 라이선스로 CI/CD 제한도 없습니다.
| 항목 | Floci | LocalStack CE |
|---|---|---|
| 인증 토큰 | 불필요 | 필수 (2026.03~) |
| CI/CD 지원 | 무제한 무료 | 유료 전환 |
| 시작 시간 | ~24ms | ~3.3s (138배 느림) |
| 유휴 메모리 | ~13 MiB | ~143 MiB (11배 많음) |
| Docker 이미지 | ~90 MB | ~1.0 GB |
| 네이티브 바이너리 | 지원 (~40 MB) | 미지원 |
| 라이선스 | MIT | 제한적 |
| SDK 테스트 | 1,969건 통과 (6개 SDK + 3개 IaC 도구) | 다수 통과 |
| 기술 | 버전 | 역할 |
|---|---|---|
| Java | 25 (소스 및 네이티브 모두 JDK 25) | 메인 언어 |
| Quarkus | 3.36.0 | 마이크로서비스 프레임워크 (GraalVM 1급 지원) |
| Vert.x | Quarkus 내장 | 비동기 이벤트 루프 |
| Jackson | Quarkus BOM | JSON/CBOR/YAML 직렬화 |
| REST Assured | 테스트 | API 통합 테스트 |
| 기술 | 역할 |
|---|---|
| Maven 3.9.12 | 빌드 시스템 |
| GraalVM Mandrel (JDK 24) | 네이티브 이미지 빌드 |
| Docker (멀티스테이지) | 컨테이너화 (빌드/런타임 분리) |
| docker-java 3.7.1 | Lambda 컨테이너 관리 |
| Semantic Release | 자동 버전 관리 |
| MkDocs | 문서 사이트 생성 |
| 프로토콜 | 사용 서비스 |
|---|---|
| REST XML | S3 |
| REST JSON | Lambda, API Gateway |
| JSON 1.1 | DynamoDB, Cognito, KMS, Kinesis, Secrets Manager, Step Functions, EventBridge, CloudWatch |
| Query | CloudFormation, IAM, STS, ElastiCache, RDS, SNS, SQS |
| RESP proxy | ElastiCache (Redis) |
| Wire proxy | RDS (PostgreSQL/MySQL) |
모든 AWS 서비스가 하나의 포트(4566)에서 서비스됩니다. 요청의 Authorization 헤더나 X-Amz-Target 헤더를 분석하여 어떤 서비스로 라우팅할지 결정합니다.
AWS 서비스마다 다른 프로토콜(REST XML, JSON 1.1, Query)을 사용합니다. Floci는 각 프로토콜에 대한 파서를 두고, 내부적으로는 통일된 서비스 인터페이스로 변환합니다.
4가지 스토리지 모드를 서비스별로 독립 설정합니다. DynamoDB는 WAL, S3는 Persistent, 단위 테스트는 Memory처럼 용도에 맞게 조합할 수 있습니다.
| 모드 | 동작 | 적합한 용도 |
|---|---|---|
| Memory | HashMap 기반, 디스크 I/O 없음 | 단위 테스트, CI |
| Persistent | 동기식 디스크 쓰기 | 영속성 필요한 개발 |
| Hybrid (기본값) | 메모리 읽기 + 비동기 디스크 플러시 | 일반 로컬 개발 |
| WAL | Append-Only 로그 + 주기적 컴팩션 | 쓰기 집약 워크로드 |
floci:
storage:
mode: hybrid # 글로벌 기본값
persistent-path: ./data
wal:
compaction-interval: 30s
services:
dynamodb:
mode: wal # DynamoDB만 WAL 모드
s3:
mode: persistent # S3는 동기 저장
Lambda 서비스는 docker-java 라이브러리를 통해 실제 Docker 컨테이너를 생성하여 함수를 실행합니다. Docker 소켓(/var/run/docker.sock)을 마운트하는 이유가 바로 이것입니다.
RDS와 ElastiCache는 단순 HTTP API가 아니라 실제 데이터베이스 프로토콜을 에뮬레이션합니다. 실제 psql, redis-cli로 직접 접속할 수 있습니다.
Quarkus의 빌드 타임 최적화가 어떻게 24ms 시작 시간을 달성하는지, GraalVM Mandrel을 사용한 네이티브 컴파일 파이프라인, 리플렉션 제한 환경에서의 Java 프로그래밍 패턴을 배웁니다.
# Stage 1: 빌드 (Mandrel builder, 수 GB)
FROM quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-24 AS build
COPY pom.xml .
RUN mvn dependency:go-offline # 의존성 캐시 레이어
COPY src ./src
RUN mvn clean package -Dnative -DskipTests
# Stage 2: 런타임 (마이크로 이미지, ~90MB)
FROM quay.io/quarkus/quarkus-micro-image:2.0
COPY --from=build /app/target/*-runner /app/application
ENTRYPOINT ["/app/application"]
인터페이스 기반 스토리지 추상화 설계, Memory/Persistent/Hybrid/WAL 4가지 모드의 트레이드오프, WAL(Write-Ahead Log) 구현: append-only 쓰기 + 30초 주기 컴팩션, 서비스별 스토리지 모드 독립 설정을 배웁니다.
AWS SDK가 내부적으로 사용하는 4가지 프로토콜(REST XML, REST JSON, JSON 1.1, Query), 단일 포트(4566)에서 멀티 프로토콜 라우팅, X-Amz-Target 헤더를 이용한 서비스 디스패칭을 배웁니다.
docker-java 라이브러리를 사용한 프로그래매틱 컨테이너 관리, Docker 소켓 마운트의 보안 고려사항, Lambda 함수를 Docker 컨테이너로 격리 실행하는 패턴을 배웁니다.
PostgreSQL/MySQL 와이어 프로토콜을 Java로 구현하는 방법, Redis RESP 프로토콜 프록시 구현, IAM 인증을 데이터베이스 프로토콜 레벨에서 처리하는 패턴을 배웁니다.
| 항목 | 네이티브 이미지 | JVM 이미지 |
|---|---|---|
| RAM | 64 MiB | 256 MiB |
| 디스크 | ~90 MB (이미지) | ~1 GB (이미지) |
| Docker | 필수 | 필수 |
| CPU | x86_64 / ARM64 | 모든 JVM 플랫폼 |
Lambda 사용 시 추가 요구사항: Docker 소켓 접근 권한, 최초 1회 Lambda 런타임 이미지 다운로드, 함수 크기에 따라 128MB~512MB 추가 RAM.
RDS/ElastiCache 추가 포트: PostgreSQL proxy 7001~7099, Redis proxy 6379~6399.
docker run -d -p 4566:4566 floci/floci:latest
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
aws s3 mb s3://my-test-bucket
echo "Hello Floci" > test.txt
aws s3 cp test.txt s3://my-test-bucket/
aws sqs create-queue --queue-name my-queue
aws sqs send-message --queue-url http://localhost:4566/000000000000/my-queue \
--message-body '{"event":"file_uploaded","key":"test.txt"}'
Python boto3를 사용하여 DynamoDB 테이블 생성(파티션 키+정렬 키), CRUD 작업, Streams 활성화 후 변경 이벤트 캡처, GSI(글로벌 보조 인덱스) 생성으로 다양한 쿼리 패턴을 테스트합니다.
# provider.tf
provider "aws" {
region = "us-east-1"
access_key = "test"
secret_key = "test"
skip_credentials_validation = true
skip_metadata_api_check = true
endpoints {
s3 = "http://localhost:4566"
dynamodb = "http://localhost:4566"
lambda = "http://localhost:4566"
}
}
Terraform plan → apply → destroy 전체 주기를 로컬에서 무료로 반복 연습합니다.
# .github/workflows/test.yml
services:
floci:
image: floci/floci:latest
ports:
- 4566:4566
env:
FLOCI_STORAGE_MODE: memory # CI 속도 최적화
GitHub Actions에서 Floci를 서비스 컨테이너로 실행하고, AWS SDK 통합 테스트를 수행합니다.
오픈소스 기여 수준의 과제입니다. AWS 서비스 API 스펙 분석 → services/ 아래 새 패키지 생성 → 프로토콜 파서 선택 → 스토리지 인터페이스 구현 → SDK 테스트로 호환성 검증.
| 키워드 | 설명 |
|---|---|
| Quarkus | Red Hat의 쿠버네티스 네이티브 Java 프레임워크. 빌드 타임에 메타데이터를 처리하여 시작 시간과 메모리를 극적으로 줄임 |
| GraalVM | Oracle의 다국어 VM. native-image 도구로 Java를 OS 네이티브 바이너리로 AOT 컴파일 |
| Mandrel | Red Hat이 Quarkus용으로 최적화한 GraalVM 배포판. native-image 기능에 집중 |
| AOT 컴파일 | Ahead-of-Time 컴파일. 실행 전에 미리 기계어로 번역. JIT(Just-in-Time)의 반대 개념 |
| Vert.x | Eclipse 재단의 비동기 이벤트 드리븐 프레임워크. Quarkus의 내부 반응형 엔진 |
| WAL | Write-Ahead Log. 데이터 변경을 먼저 로그에 기록한 뒤 실제 데이터를 업데이트하는 내구성 패턴 |
| Wire Protocol | 데이터베이스 클라이언트와 서버 간의 네트워크 통신 프로토콜 (예: PostgreSQL Frontend/Backend Protocol) |
| RESP | Redis Serialization Protocol. Redis 클라이언트-서버 통신에 사용되는 텍스트 기반 프로토콜 |
| S3 Object Lock | S3 객체를 일정 기간 삭제/수정 불가하게 잠그는 기능. COMPLIANCE(관리자도 해제 불가)와 GOVERNANCE 모드 |
| DynamoDB Streams | DynamoDB 변경사항의 시간순 시퀀스. Lambda 트리거로 이벤트 드리븐 아키텍처 구현에 활용 |
| STS | Security Token Service. 임시 보안 자격 증명 발급. AssumeRole로 교차 계정 접근에 사용 |
| Docker-in-Docker | Docker 컨테이너 안에서 Docker를 실행하는 패턴. 소켓 마운트 방식과 DinD 방식이 있음 |
| Semantic Release | Git 커밋 메시지 컨벤션을 분석하여 자동으로 버전을 올리고 릴리즈를 생성하는 도구 |
| LocalStack | 가장 유명했던 AWS 로컬 에뮬레이터. 2026년 3월 커뮤니티 에디션 정책 변경으로 논란 |