Building & embedding
Requires Java 25 and Gradle (wrapper included). Node/npm are only needed when building the shipping artifact (the console build is skipped otherwise).
Common tasks
bash
./gradlew build # compile + all tests (no console build)
./gradlew test # all tests
./gradlew test --tests "dev.totis.tinys3.S3ClientIntegrationTest"
./gradlew spotlessApply # format (Google Java Format)
./gradlew :tiny-s3-app:runTestServerSingleDisk # dev server :8000
./gradlew jibDockerBuild --no-configuration-cache # Docker image (amd64, includes console)
./gradlew build -PbuildConsole # jar with the console embeddedPackaging for Linux deployment
TinyS3 runs on any Linux host with no code changes. Pick the artifact that matches how you deploy. There is a single edition (:tiny-s3-app) with the full feature set including server pools and rack awareness; clusters larger than 2 nodes set license.enterprise: true in the config.
Docker image (recommended)
The container is the usual Linux deployment. Jib builds it with no Dockerfile and no Docker daemon required for the registry push, and always embeds the web console:
bash
# Multi-arch (amd64 + arm64) pushed to a registry — the normal release build:
./gradlew :tiny-s3-app:jib -PjibImage=<registry>/tinys3:<version>
# Load a single arch into the local Docker daemon (dev / one host — jibDockerBuild loads one arch):
./gradlew :tiny-s3-app:jibDockerBuild --no-configuration-cache -PjibPlatforms=amd64Optional: -PjibBaseImage=eclipse-temurin:25-jre-alpine (smaller image), -PjibGc=zgc (low-pause Generational ZGC). Run it as in Getting started.
Fat jar
One runnable jar for a Linux host that already has a Java 25 runtime:
bash
./gradlew :tiny-s3-app:fatJar # → app/build/libs/tinys3-<version>-all.jarCopy it to the host and run it. The jar's manifest already carries the JVM options it needs (Enable-Native-Access and the Add-Opens for the native fdatasync/fsync path), so no extra java flags are required:
bash
java -jar tinys3-<version>-all.jar --config /etc/tinys3/config.yamlAdd -PbuildConsole to embed the web console into the jar (the jib image always includes it). distZip / distTar wrap the same jar with a bin/tinys3 start script if you want a tarball with a launcher instead.
Self-contained binary (no JRE on the target)
For hosts with no Java runtime, the Go launcher embeds a trimmed jlink runtime plus the fat jar into a single native executable. Because the embedded runtime is jlinked from the target platform's JDK, a Linux binary is cross-built from any host by pointing at a Linux JDK 25's jmods:
bash
GOOS=linux GOARCH=amd64 JLINK_JMODS=/path/to/linux-jdk25/jmods integrations/launcher/build.sh
# → integrations/launcher/dist/tinys3-linux-amd64 (also GOARCH=arm64)The binary runs with tinys3 server --config config.yaml (or tinys3 server <dir> for the zero-config path). Full runbook — fetching the target jmods, both arches, smoke-testing — is in docs/releasing.md.
Module layout
| Module | Artifact | Purpose |
|---|---|---|
lib/ | tiny-s3-lib | Core S3 server (published to Maven Central) |
http/ | tiny-s3-http | Netty HTTP layer, TLS, filters |
app/ | — | Standalone server entry point, Docker |
rest/ | tiny-s3-rest | Admin REST API |
file-system/ | tiny-s3-file-system | Filesystem + erasure-coded storage |
JavaReedSolomon/ | — | Reed-Solomon codec (Backblaze) |
iam/ | tiny-s3-iam | IAM service |
replication/ | tiny-s3-replication | Bucket replication + transfer/sync job engine |
select/ | tiny-s3-select | S3 Select engine |
telemetry/ | tiny-s3-telemetry | In-memory metrics |
document-store/ | tiny-s3-document-store | Metadata storage |
Embedding
Full guide: Embedding TinyS3 in your application. Quick sketch:
java
// Simple storage
S3Server server = new S3Server.Builder()
.withPort(8000)
.withCredentials(new Credentials("access-key", "secret-key", "us-east-1"))
.withStorageDir("storage") // or .withInMemory()
.build();
server.start();java
// Erasure-coded storage
StorageConfig config = StorageConfig.create(
List.of("/disk1", "/disk2", "/disk3", "/disk4", "/disk5", "/disk6"),
new ErasureConfig(4, 2, 4096)); // 4 data + 2 parity
FileOperations fileOps = new ErasureCodedFileOperations(config);
S3Server server = new S3Server.Builder()
.withPort(8000)
.withCredentials(credentials)
.withFileOperations(fileOps)
.build();Builder options include withTls(...), withSseMasterKey(...), withCorsAllowOrigins(...) (dev), withRouter(...) for extra HTTP routes, custom authenticators and credential sources.
Tests
Integration tests run two S3 client SDKs (the AWS SDK and a second Java S3 client) against an in-memory server on port 9876 (credentials 12345/12345) — make sure that port is free. Conformance suites: S3 compatibility testing.