Emulasi S3 di Floci: bucket CRUD, object put/get/delete/copy, listing, presigned URL, dan virtual-hosted style addressing via my-bucket.s3.localhost.floci.io — plus skrip sync file lokal dengan AWS CLI & SDK

S3 adalah layanan paling universal di AWS — hampir semua aplikasi menyentuhnya untuk file upload, backup, artifact, atau data lake. Karena itu emulasi S3 adalah tolok ukur kualitas sebuah emulator lokal, dan Floci menaruh perhatian besar di sini.
Episode ini membahas cakupan fitur S3 di Floci — termasuk dua fitur yang sering jadi batu sandungan emulator lain: presigned URL dan virtual-hosted style addressing — lalu menutup dengan praktik sinkronisasi file nyata.
Operasi inti yang didukung:
aws --endpoint-url=http://localhost:4566 s3 mb s3://app-assets
aws --endpoint-url=http://localhost:4566 s3 ls
aws --endpoint-url=http://localhost:4566 s3 rb s3://app-assets # hapus saat kosongecho "v1" > app.js
aws --endpoint-url=http://localhost:4566 s3 cp app.js s3://app-assets/js/app.js # put
aws --endpoint-url=http://localhost:4566 s3 cp s3://app-assets/js/app.js - # get
aws --endpoint-url=http://localhost:4566 s3 cp s3://app-assets/js/app.js s3://app-assets/js/backup.js # copy
aws --endpoint-url=http://localhost:4566 s3 rm s3://app-assets/js/backup.js # deleteListing mendukung prefix delimiter seperti aslinya (s3 ls s3://app-assets/js/, --recursive), sehingga tooling yang bergantung pada struktur listing tetap bekerja.
Fitur yang membedakan emulator serius dari mock: generate URL ber-timeout yang bisa dipakai klien tanpa credentials:
aws --endpoint-url=http://localhost:4566 s3 presign s3://app-assets/js/app.js --expires-in 300
# http://localhost:4566/app-assets/js/app.js?X-Amz-Signature=...
curl "$(aws --endpoint-url=http://localhost:4566 s3 presign s3://app-assets/js/app.js)"Sangat berguna menguji flow upload/download browser atau mobile app secara lokal — signature v4 dihitung sungguhan oleh Floci.
AWS punya dua gaya addressing S3. Path-style (yang selama ini kita pakai):
http://localhost:4566/app-assets/js/app.jsVirtual-hosted style — bucket menjadi subdomain, persis perilaku AWS produksi:
http://my-bucket.s3.localhost.floci.io:4566/js/app.jsKenapa penting? Banyak SDK/library modern (SDK v3 default, presigner, beberapa framework) memakai virtual-hosted style secara default. Emulator tanpa dukungan ini membuat app error NoSuchBucket misterius. Floci melayani keduanya — domain *.localhost.floci.io di-resolve ke loopback, jadi tidak ada konfigurasi DNS ekstra.
Tip
Di SDK, kontrol gaya addressing lewat opsi forcePathStyle. Saat testing parity, uji kedua gaya — beberapa bug integrasi baru terlihat pada salah satunya.
Skenario umum aplikasi web: user upload avatar, app menyimpannya, dan file lama dibersihkan berkala. Di S3 sungguhan kita pakai lifecycle policy; di Floci operasi dasarnya identik:
aws --endpoint-url=http://localhost:4566 s3 mb s3://user-uploads
aws --endpoint-url=http://localhost:4566 s3 cp ./avatar.png s3://user-uploads/u123/avatar.png
aws --endpoint-url=http://localhost:4566 s3api head-object --bucket user-uploads --key u123/avatar.png \
--query '{size:ContentLength,type:ContentType}'
aws --endpoint-url=http://localhost:4566 s3 ls --recursive s3://user-uploadsUntuk lifecycle rules (PutBucketLifecycleConfiguration), verifikasi dukungan pada versi floci kalian — coverage operasi niche selalu dicek di matrix resmi (episode 14).
Target outline: skrip sync file lokal↔S3 floci dengan AWS CLI & SDK.
#!/usr/bin/env bash
set -euo pipefail
export AWS_ENDPOINT_URL=http://localhost:4566
SRC=${1:-./dist}
DEST=${2:-s3://app-assets}
aws s3 sync "$SRC" "$DEST" --delete --exact-timestamps
echo "sync selesai: $(find "$SRC" -type f | wc -l) file terpantau"Jalankan sync, lalu verifikasi hasilnya lewat SDK yang berbeda — pola "tulis dengan satu klien, baca dengan klien lain" adalah smoke test parity murah yang menangkap banyak bug konfigurasi.
Rangkuman episode ini:
my-bucket.s3.localhost.floci.io:4566) didukung di samping path-style — kompatibel SDK modern default.s3 sync yang diverifikasi lintas-klien.Layanan stateless sudah; sekarang masuk dunia database. Episode 5: emulasi DynamoDB — CreateTable, query pattern akses nyata, GSI/LSI, sampai catatan penting soal API conformance gaps yang wajib kalian waspadai. Sampai jumpa!