AWS CLI + MinIO S3
At a glance#
- Purpose: Configure the AWS CLI to manage buckets and objects on our self-hosted MinIO server.
- Applies to: AWS CLI v2 on Linux and Windows, against MinIO with the S3 API.
- Risk: Medium — the delete commands are immediate and irreversible.
- Time: About 20 minutes for setup.
Overview#
MinIO implements the S3 API, so the standard AWS CLI works against it without modification. Two settings make the difference:
| Setting | Why it is needed |
|---|---|
endpoint_url | Points the CLI at our MinIO server instead of Amazon |
addressing_style = path | MinIO uses endpoint/bucket, not bucket.endpoint as AWS does |
Getting the addressing style wrong is the most common cause of setup failing — requests go to a hostname that does not resolve.
Note: The mc (MinIO Client) tool is the native alternative and is better for administrative work such as user and policy management. Use the AWS CLI when you want one tool that works against both MinIO and AWS, or when scripting something portable between them.
Before you start#
- MinIO access key and secret key.
- The MinIO endpoint URL —
https://s3.example.comin these examples. - Network access to that endpoint.
Procedure#
1. Install the AWS CLI#
Ubuntu / Debian:
sudo apt update
sudo apt install unzip -y
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --versionRHEL / Rocky / AlmaLinux:
sudo yum install unzip -y
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --versionWindows: download and run https://awscli.amazonaws.com/AWSCLIV2.msi, then confirm in a new PowerShell window:
aws --versionVersion output should begin aws-cli/2.x. Version 1 is missing options used below.
2. Store the credentials#
aws configure --profile minio-adminAnswer the prompts:
AWS Access Key ID : <YOUR_MINIO_ACCESS_KEY>
AWS Secret Access Key : <YOUR_MINIO_SECRET_KEY>
Default region name : us-east-1
Default output format : jsonNote: MinIO ignores the region, but the CLI refuses to run without one. us-east-1 is the conventional placeholder.
This writes credentials to ~/.aws/credentials in plain text. Restrict access to that file:
chmod 600 ~/.aws/credentials3. Add the endpoint and addressing style#
Credentials alone are not enough — the CLI still needs to know where MinIO is.
nano ~/.aws/config[profile minio-admin]
region = us-east-1
output = json
s3 =
endpoint_url = https://s3.example.com
addressing_style = pathWarning: The indentation under s3 = is required. Those lines must be indented, or the CLI ignores them and silently tries to reach Amazon instead.
4. Select the profile#
For the current shell session:
export AWS_PROFILE=minio-adminTo make it permanent for your user:
echo 'export AWS_PROFILE=minio-admin' >> ~/.bashrcAlternatively, pass --profile minio-admin on each command.
Common operations#
Buckets#
# Create a bucket
aws s3 mb s3://mybucket
# List all buckets
aws s3 lsUploading#
# Single file
aws s3 cp /path/to/localfile.txt s3://mybucket/
# Whole directory
aws s3 cp /path/to/folder s3://mybucket/ --recursive
# Mirror a directory, removing files on the target that no longer exist locally
aws s3 sync /path/to/folder s3://mybucket/ --deleteWarning:sync --deleteremoves objects from the bucket that are absent locally. Preview first with--dryrun.
Listing objects#
aws s3 ls s3://mybucket --recursive --human-readable --summarize--summarize appends a total object count and size, which is handy for verifying a migration.
Downloading#
# Single object
aws s3 cp s3://mybucket/file.txt /local/path/
# Entire bucket
aws s3 cp s3://mybucket/ /local/path/ --recursiveDeleting#
Warning: These take effect immediately. Unless versioning is enabled on the bucket, deleted objects cannot be recovered.
# One object
aws s3 rm s3://mybucket/file.txt
# All objects in a bucket
aws s3 rm s3://mybucket --recursive
# The bucket itself - must be empty first
aws s3api delete-bucket --bucket mybucketAlways dry-run a recursive delete before committing to it:
aws s3 rm s3://mybucket --recursive --dryrunVerification#
Confirm the CLI is talking to MinIO rather than AWS:
aws s3 lsIf this returns your MinIO buckets, the endpoint is correct. If it returns an Amazon credentials error, the ~/.aws/config endpoint block is not being read — check the indentation.
Run a full round trip:
echo "test $(date)" > /tmp/test.txt
aws s3 cp /tmp/test.txt s3://mybucket/
aws s3 ls s3://mybucket/
aws s3 cp s3://mybucket/test.txt /tmp/test-download.txt
diff /tmp/test.txt /tmp/test-download.txt && echo "Round trip OK"
aws s3 rm s3://mybucket/test.txtTroubleshooting#
| Symptom | Cause and fix |
|---|---|
Could not connect to the endpoint URL | Endpoint wrong or unreachable. Test with curl -I https://s3.example.com. |
Requests go to amazonaws.com | The s3 block in ~/.aws/config is not indented, so it is ignored. |
SSL validation failed | MinIO is using a self-signed certificate. Install the CA properly, or as a temporary measure add --no-verify-ssl. |
NoSuchBucket on a bucket that exists | Path addressing not set. Confirm addressing_style = path. |
AccessDenied | Key lacks a policy for that bucket. Check the user's policy in the MinIO console. |
InvalidAccessKeyId | Wrong profile in use. Confirm with echo $AWS_PROFILE. |