| name | object-storage |
| description | Configure object storage with S3, GCS, and MinIO. Implement lifecycle policies and access controls. Use when managing object storage. |
| license | MIT |
| metadata | {"author":"devops-skills","version":"1.0"} |
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
aws s3 mb s3://my-app-assets-prod
aws s3 mb s3://my-app-assets-eu --region eu-west-1
aws s3 ls
aws s3 ls s3://my-app-assets-prod --recursive --human-readable --summarize
aws s3 rb s3://my-old-bucket
aws s3 rb s3://my-old-bucket --force
Upload and Download
aws s3 cp ./report.pdf s3://my-app-assets-prod/reports/
aws s3 cp ./archive.tar.gz s3://my-app-assets-prod/archives/ --storage-class GLACIER
aws s3 cp ./sensitive.dat s3://my-app-assets-prod/data/ --sse AES256
aws s3 cp s3://my-app-assets-prod/reports/report.pdf ./downloads/
aws s3 sync ./build/ s3://my-app-assets-prod/static/ --delete
aws s3 sync s3://my-app-assets-prod/static/ ./local-copy/
aws s3 sync ./logs/ s3://my-app-logs/ --exclude "*.tmp" --exclude ".git/*"
aws s3 sync s3://source-bucket/ s3://destination-bucket/ --source-region us-east-1 --region eu-west-1
aws s3 presign s3://my-app-assets-prod/reports/report.pdf --expires-in 3600
aws s3 rm s3://my-app-assets-prod/old-data/ --recursive
Versioning
aws s3api put-bucket-versioning \
--bucket my-app-assets-prod \
--versioning-configuration Status=Enabled
aws s3api get-bucket-versioning --bucket my-app-assets-prod
aws s3api list-object-versions --bucket my-app-assets-prod --prefix reports/
aws s3api copy-object \
--bucket my-app-assets-prod \
--copy-source "my-app-assets-prod/reports/report.pdf?versionId=abc123" \
--key reports/report.pdf
aws s3api delete-object \
--bucket my-app-assets-prod \
--key reports/old-report.pdf \
--version-id abc123
Bucket Policies
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":
Lifecycle Rules
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":
aws s3api get-bucket-lifecycle-configuration --bucket my-app-assets-prod
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
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)
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:
docker compose up -d
docker compose ps
curl -s http://localhost:9000/minio/health/live
MinIO Client (mc) Commands
curl -O https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc && mv mc /usr/local/bin/
mc alias set myminio http://localhost:9000 minioadmin minio-secret-key-change-me
mc alias set aws https://s3.amazonaws.com AKIAEXAMPLE SECRETKEYEXAMPLE
mc mb myminio/app-data
mc mb myminio/backups
mc ls myminio/
mc cp ./backup.tar.gz myminio/backups/
mc cp myminio/backups/backup.tar.gz ./restore/
mc mirror ./static/ myminio/app-data/static/
mc mirror --watch ./static/ myminio/app-data/static/
mc anonymous set download myminio/app-data/static
mc anonymous set-json policy.json myminio/app-data
mc version enable myminio/app-data
mc ilm rule add --expiry-days 7 --prefix "tmp/" myminio/app-data
mc ilm rule ls myminio/app-data
mc admin user svcacct add myminio minioadmin --access-key myapp-key --secret-key myapp-secret
mc admin info myminio
mc du myminio/app-data
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 volumes
backup-recovery -- Using S3/MinIO as a backup destination with restic
nfs-storage -- Alternative shared storage for file-level access
linux-administration -- Server setup and maintenance for MinIO hosts