KB
Object Storage & S3

AWS CLI + MinIO S3

4 min read858 words18 code blocks

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:

SettingWhy it is needed
endpoint_urlPoints the CLI at our MinIO server instead of Amazon
addressing_style = pathMinIO 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.com in these examples.
  • Network access to that endpoint.

Procedure#

1. Install the AWS CLI#

Ubuntu / Debian:

bash
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 --version

RHEL / Rocky / AlmaLinux:

bash
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 --version

Windows: download and run https://awscli.amazonaws.com/AWSCLIV2.msi, then confirm in a new PowerShell window:

powershell
aws --version

Version output should begin aws-cli/2.x. Version 1 is missing options used below.

2. Store the credentials#

bash
aws configure --profile minio-admin

Answer the prompts:

text
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 : json
Note: 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:

bash
chmod 600 ~/.aws/credentials

3. Add the endpoint and addressing style#

Credentials alone are not enough — the CLI still needs to know where MinIO is.

bash
nano ~/.aws/config
ini
[profile minio-admin]
region = us-east-1
output = json
s3 =
    endpoint_url = https://s3.example.com
    addressing_style = path
Warning: 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:

bash
export AWS_PROFILE=minio-admin

To make it permanent for your user:

bash
echo 'export AWS_PROFILE=minio-admin' >> ~/.bashrc

Alternatively, pass --profile minio-admin on each command.

Common operations#

Buckets#

bash
# Create a bucket
aws s3 mb s3://mybucket

# List all buckets
aws s3 ls

Uploading#

bash
# 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/ --delete
Warning: sync --delete removes objects from the bucket that are absent locally. Preview first with --dryrun.

Listing objects#

bash
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#

bash
# Single object
aws s3 cp s3://mybucket/file.txt /local/path/

# Entire bucket
aws s3 cp s3://mybucket/ /local/path/ --recursive

Deleting#

Warning: These take effect immediately. Unless versioning is enabled on the bucket, deleted objects cannot be recovered.
bash
# 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 mybucket

Always dry-run a recursive delete before committing to it:

bash
aws s3 rm s3://mybucket --recursive --dryrun

Verification#

Confirm the CLI is talking to MinIO rather than AWS:

bash
aws s3 ls

If 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:

bash
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.txt

Troubleshooting#

SymptomCause and fix
Could not connect to the endpoint URLEndpoint wrong or unreachable. Test with curl -I https://s3.example.com.
Requests go to amazonaws.comThe s3 block in ~/.aws/config is not indented, so it is ignored.
SSL validation failedMinIO is using a self-signed certificate. Install the CA properly, or as a temporary measure add --no-verify-ssl.
NoSuchBucket on a bucket that existsPath addressing not set. Confirm addressing_style = path.
AccessDeniedKey lacks a policy for that bucket. Check the user's policy in the MinIO console.
InvalidAccessKeyIdWrong profile in use. Confirm with echo $AWS_PROFILE.