Nest3 is a lightweight, open-source, S3-compatible object storage server with a built-in admin console.
Give it a disk, and it stores your files via standard S3 API.
| Tenant Dashboard | Bucket Management |
|---|---|
![]() |
![]() |
| Access Key Creation | Public Bucket Toggle |
|---|---|
![]() |
![]() |
- S3-Compatible API - Works with AWS CLI, SDKs, and any S3 client
- Multi-Tenant - Isolated storage per tenant with quotas
- Public/Private Buckets - Configure public-read access for assets
- Admin Console - Web UI to manage tenants, users, and access keys
- Single JAR - No external dependencies, just Java
- SQLite - Embedded database, no setup required
- Apache 2.0 - Fully open source
# Build the image
docker build -t nest3 .
# Run with persistent storage
docker run -d -p 8080:8080 -v nest3-data:/data --name nest3 nest3With custom admin credentials:
docker run -d -p 8080:8080 \
-v nest3-data:/data \
-e NEST3_ADMIN_USER=myadmin \
-e NEST3_ADMIN_PASS=mysecretpass \
--name nest3 nest3Docker commands:
# View logs
docker logs -f nest3
# Stop
docker stop nest3
# Start
docker start nest3
# Remove (data persists in volume)
docker rm nest3# Build
mvn clean package
# Run
java -jar target/nest3-0.1.0.jar- Default username:
admin - Default password:
admin
Environment variables:
| Variable | Description | Default |
|---|---|---|
NEST3_PORT |
Server port | 8080 |
NEST3_STORAGE_PATH |
File storage directory | ./data |
NEST3_DB_PATH |
SQLite database path | ./nest3.db |
NEST3_ADMIN_USER |
Admin username | admin |
NEST3_ADMIN_PASS |
Admin password | admin |
A tenant is an isolated organization/account. Each tenant has its own users, buckets, and storage quota.
- Login to admin console at http://localhost:8080
- Click Tenants in the navigation
- Click + New Tenant
- Enter a name (e.g., "Acme Corp")
- Click Create
After creation, you can set a storage quota (in GB) by editing the tenant.
Users belong to a tenant and can have access keys to use the S3 API.
- Click on the tenant you just created
- Click Manage users or go to the Users section
- Click + New User
- Enter:
- Email: User's email address
- Password: (optional, for future portal login)
- Role: USER or ADMIN
- Click Create
Access keys are used to authenticate S3 API requests.
- From the tenant page, click Manage access keys
- Click + New Access Key
- Select the user
- Add an optional description (e.g., "Production server")
- Click Create Access Key
IMPORTANT: Copy both the Access Key ID and Secret Access Key immediately. The secret key is only shown once!
Example credentials:
Access Key ID: NEST7X9K2M4P1Q8R3S6T
Secret Access Key: aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ5
Now you can use any S3 client with your access keys.
# Configure AWS CLI
aws configure set aws_access_key_id NEST1234567890ABCDEF
aws configure set aws_secret_access_key your-secret-key
# Create bucket
aws --endpoint-url http://localhost:8080/s3 s3 mb s3://my-bucket
# Upload file
aws --endpoint-url http://localhost:8080/s3 s3 cp myfile.txt s3://my-bucket/
# List files
aws --endpoint-url http://localhost:8080/s3 s3 ls s3://my-bucket/
# Download file
aws --endpoint-url http://localhost:8080/s3 s3 cp s3://my-bucket/myfile.txt ./downloaded.txtS3Client s3 = S3Client.builder()
.endpointOverride(URI.create("http://localhost:8080/s3"))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create("your-access-key", "your-secret-key")))
.region(Region.US_EAST_1)
.build();
// Upload
s3.putObject(
PutObjectRequest.builder().bucket("my-bucket").key("file.txt").build(),
Path.of("local-file.txt")
);Buckets can be configured as public-read, allowing anyone to download objects without authentication.
Via Admin Console:
- Go to Tenants > Select tenant > Buckets
- Click the Private badge next to the bucket name
- It will toggle to Public
Via API (coming soon): Public bucket configuration will be exposed via S3 ACL API.
Public buckets allow unauthenticated GET requests:
# No AWS credentials needed for public buckets
curl http://localhost:8080/s3/my-public-bucket/image.png -o image.png
# Or via browser
# http://localhost:8080/s3/my-public-bucket/image.png- Public-read only: Objects can be read publicly, but uploads still require authentication
- No public-write: For security, anonymous uploads are not supported
- Bucket listing (ListObjectsV2) is also allowed on public buckets
- HEAD requests work without authentication on public buckets
| Operation | Status |
|---|---|
| ListBuckets | ✅ |
| CreateBucket | ✅ |
| DeleteBucket | ✅ |
| HeadBucket | ✅ |
| ListObjectsV2 | ✅ |
| PutObject | ✅ |
| GetObject | ✅ |
| HeadObject | ✅ |
| DeleteObject | ✅ |
- Multipart uploads
- Presigned URLs
- Object versioning
- CORS configuration
┌──────────────────────────────────────────┐
│ Nest3 Server │
│ │
│ Admin Console ←→ SQLite ←→ S3 API │
│ ↓ ↓ │
│ Tenants Storage │
│ Users Backend │
│ Access Keys (Local Disk/NFS) │
└──────────────────────────────────────────┘
| Version | Database | Storage | Use Case |
|---|---|---|---|
| v1 | SQLite | Local Disk | Single node |
| v1.5 | PostgreSQL | NFS | Multi-node |
| v2 | PostgreSQL | S3 Backend | Large scale |
Apache License 2.0
Contributions welcome! Please read the spec in SPEC.md first.



