object-storage
Installation
SKILL.md
Object Storage
Configure and manage object storage solutions including AWS S3, MinIO (self-hosted), and compatible providers. Covers CLI operations, bucket policies, lifecycle rules, versioning, encryption, and the MinIO client (mc).
When to Use
- Storing application assets, backups, logs, or media files
- Setting up an S3-compatible object store on-premises with MinIO
- Configuring lifecycle rules to transition or expire objects automatically
- Implementing access control with bucket policies and IAM
- Syncing data between local filesystems and object storage
- Serving static content from S3 or MinIO
Prerequisites
- AWS CLI v2 installed and configured (
aws configure) for S3 operations - Docker installed for MinIO self-hosted setup
- MinIO client (
mc) installed for MinIO management - IAM credentials with appropriate S3 permissions
- Network access to the object storage endpoint
AWS S3 CLI Operations
Bucket Management
# Create a new bucket
aws s3 mb s3://my-app-assets-prod
# Create a bucket in a specific region
aws s3 mb s3://my-app-assets-eu --region eu-west-1
# List all buckets
aws s3 ls
# List objects in a bucket (with sizes)
aws s3 ls s3://my-app-assets-prod --recursive --human-readable --summarize
# Delete an empty bucket
aws s3 rb s3://my-old-bucket
# Delete a bucket and ALL its contents (destructive)
aws s3 rb s3://my-old-bucket --force
Upload and Download
# Upload a single file
aws s3 cp ./report.pdf s3://my-app-assets-prod/reports/
# Upload with a specific storage class
aws s3 cp ./archive.tar.gz s3://my-app-assets-prod/archives/ --storage-class GLACIER
# Upload with server-side encryption (AES-256)
aws s3 cp ./sensitive.dat s3://my-app-assets-prod/data/ --sse AES256
# Download a file
aws s3 cp s3://my-app-assets-prod/reports/report.pdf ./downloads/
# Sync a local directory to S3 (upload only changed files)
aws s3 sync ./build/ s3://my-app-assets-prod/static/ --delete
# Sync from S3 to local
aws s3 sync s3://my-app-assets-prod/static/ ./local-copy/
# Sync with exclusion patterns
aws s3 sync ./logs/ s3://my-app-logs/ --exclude "*.tmp" --exclude ".git/*"
# Copy between buckets
aws s3 sync s3://source-bucket/ s3://destination-bucket/ --source-region us-east-1 --region eu-west-1
# Generate a pre-signed URL (temporary access, 1 hour)
aws s3 presign s3://my-app-assets-prod/reports/report.pdf --expires-in 3600
# Recursive delete of a prefix
aws s3 rm s3://my-app-assets-prod/old-data/ --recursive
Versioning
# Enable versioning on a bucket
aws s3api put-bucket-versioning \
--bucket my-app-assets-prod \
--versioning-configuration Status=Enabled
# Check versioning status
aws s3api get-bucket-versioning --bucket my-app-assets-prod
# List object versions
aws s3api list-object-versions --bucket my-app-assets-prod --prefix reports/
# Restore a previous version (copy old version to current)
aws s3api copy-object \
--bucket my-app-assets-prod \
--copy-source "my-app-assets-prod/reports/report.pdf?versionId=abc123" \
--key reports/report.pdf
# Delete a specific version permanently
aws s3api delete-object \
--bucket my-app-assets-prod \
--key reports/old-report.pdf \
--version-id abc123
Bucket Policies
# Apply a bucket policy from a JSON file
aws s3api put-bucket-policy --bucket my-app-assets-prod --policy file://policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadForStaticSite",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-app-assets-prod/static/*"
},
{
"Sid": "DenyUnencryptedUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-app-assets-prod/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
},
{
"Sid": "RestrictToVPC",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-app-assets-prod",
"arn:aws:s3:::my-app-assets-prod/*"
],
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-abc123"
}
}
}
]
}
Lifecycle Rules
# Apply lifecycle configuration
aws s3api put-bucket-lifecycle-configuration \
--bucket my-app-assets-prod \
--lifecycle-configuration file://lifecycle.json
{
"Rules": [
{
"ID": "TransitionLogsToIA",
"Filter": { "Prefix": "logs/" },
"Status": "Enabled",
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
}
],
"Expiration": {
"Days": 365
}
},
{
"ID": "CleanupIncompleteUploads",
"Filter": { "Prefix": "" },
"Status": "Enabled",
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
}
},
{
"ID": "ExpireOldVersions",
"Filter": { "Prefix": "" },
"Status": "Enabled",
"NoncurrentVersionExpiration": {
"NoncurrentDays": 30
}
}
]
}
# View current lifecycle rules
aws s3api get-bucket-lifecycle-configuration --bucket my-app-assets-prod
# Enable S3 access logging
aws s3api put-bucket-logging --bucket my-app-assets-prod --bucket-logging-status '{
"LoggingEnabled": {
"TargetBucket": "my-app-logs",
"TargetPrefix": "s3-access-logs/"
}
}'
MinIO Self-Hosted Setup
Docker Deployment
# Single-node MinIO with persistent storage
docker run -d \
--name minio \
--restart unless-stopped \
-p 9000:9000 \
-p 9001:9001 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minio-secret-key-change-me \
-v /data/minio:/data \
minio/minio server /data --console-address ":9001"
Docker Compose (Multi-Drive)
# docker-compose.yml
version: "3.8"
services:
minio:
image: minio/minio:latest
command: server /data{1...4} --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minio-secret-key-change-me
MINIO_BROWSER_REDIRECT_URL: https://minio-console.example.com
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio-data1:/data1
- minio-data2:/data2
- minio-data3:/data3
- minio-data4:/data4
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
volumes:
minio-data1:
minio-data2:
minio-data3:
minio-data4:
# Start the stack
docker compose up -d
# Check health
docker compose ps
curl -s http://localhost:9000/minio/health/live
MinIO Client (mc) Commands
# Install mc
curl -O https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc && mv mc /usr/local/bin/
# Configure an alias for the MinIO server
mc alias set myminio http://localhost:9000 minioadmin minio-secret-key-change-me
# Configure an alias for AWS S3
mc alias set aws https://s3.amazonaws.com AKIAEXAMPLE SECRETKEYEXAMPLE
# Bucket operations
mc mb myminio/app-data
mc mb myminio/backups
mc ls myminio/
# Upload and download
mc cp ./backup.tar.gz myminio/backups/
mc cp myminio/backups/backup.tar.gz ./restore/
# Sync a directory (mirror)
mc mirror ./static/ myminio/app-data/static/
mc mirror --watch ./static/ myminio/app-data/static/ # Continuous sync
# Set bucket policy (download = public read)
mc anonymous set download myminio/app-data/static
# Set a specific policy from JSON
mc anonymous set-json policy.json myminio/app-data
# Enable versioning
mc version enable myminio/app-data
# Set lifecycle rule: expire objects in tmp/ after 7 days
mc ilm rule add --expiry-days 7 --prefix "tmp/" myminio/app-data
# List lifecycle rules
mc ilm rule ls myminio/app-data
# Create a service account (for applications)
mc admin user svcacct add myminio minioadmin --access-key myapp-key --secret-key myapp-secret
# View server info and disk usage
mc admin info myminio
# Check bucket disk usage
mc du myminio/app-data
# Set a notification target (webhook on object creation)
mc event add myminio/app-data arn:minio:sqs::myqueue:webhook --event put
mc event ls myminio/app-data
Troubleshooting
| Symptom | Diagnostic Command | Common Fix |
|---|---|---|
| Access Denied on S3 | aws s3api get-bucket-policy --bucket name |
Check IAM policy, bucket policy, and block public access settings |
| Slow uploads | aws s3 cp --debug |
Use multipart: aws configure set s3.multipart_threshold 64MB |
| 403 on pre-signed URL | Check clock skew, URL expiry | Sync system clock with NTP; regenerate URL |
| MinIO unhealthy | mc admin info myminio |
Check disk space, container logs, port availability |
| Lifecycle rules not applying | aws s3api get-bucket-lifecycle-configuration |
Rules run once per day; check Filter prefix matches |
| Objects not versioned | aws s3api get-bucket-versioning |
Enable versioning; it does not apply retroactively |
| mc: connection refused | mc alias ls |
Verify endpoint URL, port, and credentials |
| Large sync is slow | Monitor with mc mirror --watch |
Use --multi-thread flag, increase bandwidth |
Related Skills
block-storage-- Underlying disk storage for MinIO data volumesbackup-recovery-- Using S3/MinIO as a backup destination with resticnfs-storage-- Alternative shared storage for file-level accesslinux-administration-- Server setup and maintenance for MinIO hosts
Weekly Installs
31
Repository
bagelhole/devop…t-skillsGitHub Stars
18
First Seen
5 days ago
Security Audits