Overview
The storage layer is built on the AWS S3 SDK, providing compatibility with:- MinIO - Self-hosted, Docker-friendly (default for local development)
- RustFS - Lightweight Rust-based S3-compatible storage
- AWS S3 - Amazon’s cloud object storage
- Alibaba Cloud OSS - With S3 compatibility mode
- Any S3-compatible service - Backblaze B2, DigitalOcean Spaces, etc.
The Docker Compose setup uses MinIO and automatically creates the required bucket. No manual configuration needed for local development.
Quick Setup
Using Docker Compose (Default)
The included Docker setup handles everything:- MinIO server on port 9000 (API) and 9001 (console)
- Bucket named
interview-guidewith public read access - Default credentials:
minioadmin/minioadmin
Manual MinIO Setup
If running MinIO outside Docker:Storage Configuration Properties
Storage is configured through theStorageConfigProperties class mapped to app.storage in application.yml:
StorageConfigProperties.java at app/src/main/java/interview/guide/common/config/StorageConfigProperties.java:1
Configuration Properties
The complete URL endpoint for your S3-compatible storage service.Environment Variable:
APP_STORAGE_ENDPOINTDefault: http://localhost:9000Examples:- Local MinIO:
http://localhost:9000 - Docker network:
http://minio:9000 - AWS S3:
https://s3.amazonaws.com(or region-specific) - Alibaba Cloud OSS:
https://oss-cn-hangzhou.aliyuncs.com - RustFS: Your RustFS server URL
S3 access key ID (equivalent to a username).Environment Variable:
APP_STORAGE_ACCESS_KEYDefault: wr45VXJZhCxc6FAWz0YR (example key)For MinIO, default is minioadmin. For cloud providers, obtain from your IAM console.S3 secret access key (equivalent to a password).Environment Variable:
APP_STORAGE_SECRET_KEYDefault: GtKxV57WJkpw4CvASPBzTy2DYElLnRqh8dIXQa0m (example key)For MinIO, default is minioadmin.The S3 bucket name where all files will be stored.Environment Variable:
APP_STORAGE_BUCKETDefault: interview-guideThis bucket must exist before the application starts. The Docker setup creates it automatically.Bucket naming rules:- 3-63 characters
- Lowercase letters, numbers, hyphens
- Must start with letter or number
AWS region identifier.Environment Variable:
APP_STORAGE_REGIONDefault: us-east-1For MinIO/RustFS, this can be any value as regions aren’t enforced. The default us-east-1 is conventional.For AWS S3, use your bucket’s region (e.g., us-west-2, eu-west-1).S3 Client Configuration
TheS3Config class creates an AWS SDK v2 S3 client with path-style access for MinIO compatibility:
S3Config.java at app/src/main/java/interview/guide/common/config/S3Config.java:23
Path-Style vs Virtual-Hosted Style
TheforcePathStyle(true) setting is critical for MinIO and RustFS:
Understanding S3 URL Styles
Understanding S3 URL Styles
Path-Style (used by MinIO/RustFS):Virtual-Hosted Style (AWS S3 default):Without
forcePathStyle(true), the SDK tries to access http://interview-guide.localhost:9000/, causing DNS resolution failures.Storage Providers
MinIO (Default)
Self-hosted, S3-compatible object storage written in Go.9000- S3 API endpoint (used by application)9001- Web console (http://localhost:9001)
minioadmin / minioadmin
AWS S3
Amazon’s cloud object storage service.Create S3 bucket
In AWS Console:
- Go to S3 service
- Click Create bucket
- Enter bucket name (e.g.,
interview-guide-prod) - Choose region
- Configure permissions (private by default)
Create IAM user
- Go to IAM service
- Create user with programmatic access
- Attach policy:
- Save Access Key ID and Secret Access Key
Alibaba Cloud OSS
Alibaba Cloud’s object storage with S3 compatibility mode.RustFS
Lightweight S3-compatible storage written in Rust.Bucket Setup
Automatic (Docker Compose)
Thecreatebuckets service automatically initializes MinIO:
- Waits for MinIO to be healthy
- Creates the
interview-guidebucket - Sets public read permissions
- Exits successfully
Manual (MinIO Client)
Using the MinIO Client (mc):
Manual (AWS CLI)
For AWS S3 or S3-compatible services:File Upload Configuration
Spring Boot multipart upload settings inapplication.yml:
Maximum size for individual uploaded files.Set to
50MB to support knowledge base document uploads. Resume uploads have additional business-layer size checks.Maximum size for the entire multipart request (all files combined).
Allowed File Types
Resume upload restrictions configured viaAppConfigProperties:
- PDF -
application/pdf(.pdf) - Word (Legacy) -
application/msword(.doc) - Word (Modern) -
application/vnd.openxmlformats-officedocument.wordprocessingml.document(.docx) - Plain Text -
text/plain(.txt)
Production Checklist
Configure bucket policies
Set appropriate permissions. Most buckets should be private with signed URLs for access.
Troubleshooting
Error: The specified bucket does not exist
Error: The specified bucket does not exist
The bucket hasn’t been created:
- Check bucket exists:
mc ls local/ - Create it:
mc mb local/interview-guide - Verify
APP_STORAGE_BUCKETmatches the actual bucket name
Error: Access Denied / 403 Forbidden
Error: Access Denied / 403 Forbidden
Credential or permission issues:
- Verify
APP_STORAGE_ACCESS_KEYandAPP_STORAGE_SECRET_KEYare correct - Check IAM user has necessary S3 permissions
- For MinIO, ensure credentials match
MINIO_ROOT_USER/MINIO_ROOT_PASSWORD - Verify bucket policy allows the operation
Error: Connection refused / UnknownHostException
Error: Connection refused / UnknownHostException
Cannot reach storage endpoint:
- Verify MinIO is running:
docker ps | grep minio - Check
APP_STORAGE_ENDPOINTis correct - In Docker, use service name:
http://minio:9000 - Outside Docker, use:
http://localhost:9000 - Check firewall rules allow port 9000
Error: DNS resolution failed (bucket.endpoint)
Error: DNS resolution failed (bucket.endpoint)
Missing
forcePathStyle(true) configuration:The SDK is trying to use virtual-hosted style URLs. This happens when:forcePathStyle(true)is not set inS3Config- Using MinIO or RustFS without this setting
S3Config.java includes .forcePathStyle(true) at line 33.File upload fails with 'Maximum upload size exceeded'
File upload fails with 'Maximum upload size exceeded'
File too large for configured limits:
- Check
spring.servlet.multipart.max-file-sizein application.yml - Increase to larger value (e.g.,
100MB) - Also increase
max-request-sizeto match - Restart application after changes
MinIO console not accessible
MinIO console not accessible
Console port issues:
- Verify MinIO started with
--console-address ":9001" - Check port 9001 is exposed and not in use
- Access at http://localhost:9001 (not 9000)
- Login with MinIO root credentials
See Also
- Environment Variables - Storage environment variables reference
- MinIO Documentation - Official MinIO guide
- AWS S3 SDK for Java - AWS SDK documentation
- MinIO Client Guide - mc command reference
