Intro
Upgrading or migrating a MinIO deployment is a routine operation that can turn into a service outage if done without a clear plan. This guide provides a practical, command-driven approach for developers, DevOps engineers, and technical startup teams who need to move from a known problem to a verified result. We focus on the operational workflow: identifying the current version and topology, preparing for the change, executing the upgrade or migration, validating the result, and rolling back if needed.
The goal is operational safety. Before changing anything, you observe the current state. You limit the blast radius by upgrading one component at a time. You use placeholders instead of real credentials in scripts and documentation. You verify the outcome with explicit commands and expected output. And you document recovery steps before you need them.
Every example in this article uses placeholders like http://minio.example.com or access-key-placeholder. Replace them with values from your environment. Never put production secrets in scripts, config files, or version control.
Version and Environment Inventory
Before any upgrade or migration, you must know exactly what you have. This inventory step is read-only and safe. It establishes a baseline for comparison later.
Identify the Installed Version
The first command checks the MinIO server version. The method depends on how you access the deployment.
For a local binary or systemd service:
minio --version
Expected output:
minio version RELEASE.2024-01-16T16-07-38Z (commit=...)
The date-based version string tells you the release date and build. Note this exact string in your runbook.
For a Docker container:
docker exec minio-container minio --version
Replace minio-container with the actual container name or ID.
For a Kubernetes deployment:
kubectl exec -n minio-namespace deploy/minio -- minio --version
If the deployment has multiple replicas, run the command on one pod and also check the image tag in the deployment spec:
kubectl get deploy minio -n minio-namespace -o jsonpath='{.spec.template.spec.containers[0].image}'
Record the Deployment Topology
You need to know if this is a single-node single-drive (SNSD), single-node multi-drive (SNMD), or distributed multi-node multi-drive setup. The topology determines the upgrade procedure and rollback options. MinIO's erasure coding provides redundancy, but only if the cluster is healthy before the upgrade.
Check the cluster health with mc admin info:
mc admin info myminio
Example healthy output:
● minio1.example.com:9000
Uptime: 12 days
Version: RELEASE.2024-01-16T16-07-38Z
Drives: 4/4 OK
● minio2.example.com:9000
Uptime: 12 days
Version: RELEASE.2024-01-16T16-07-38Z
Drives: 4/4 OK
If any drive is not OK, resolve that before proceeding. An upgrade does not fix failing hardware.
Check Compatibility and Prerequisites
Review the MinIO release notes for the target version. Look for breaking changes, configuration file format changes, or required migration steps. For example, moving from a version before 2022 may require changes to the MINIO_ROOT_USER and MINIO_ROOT_PASSWORD environment variables (now mandatory).
Verify that your client tools, especially mc, are compatible with the server version. The mc client is usually backward compatible, but new features may require a newer client.
mc --version
If you use S3 SDKs in applications, check their compatibility with the target MinIO version. Most S3-compatible SDKs work, but features like object locking or versioning may have specific requirements.
Capture a Read-Only Snapshot
Record the current configuration. For Docker, get the environment variables and mounts:
docker inspect minio-container --format '{{json .Config.Env}}'
docker inspect minio-container --format '{{json .Mounts}}'
For Kubernetes, export the deployment and statefulset YAML:
kubectl get deploy minio -n minio-namespace -o yaml > minio-deploy-backup.yaml
If you have a custom config.json for MinIO (rare, but possible), back it up:
cp /etc/minio/config.json /backup/minio-config-$(date +%Y%m%d).json
This snapshot is your rollback reference.
Safe Configuration Path
The upgrade itself must follow a path that minimizes risk. We describe the steps for Docker and Kubernetes, the most common deployment methods.
Docker Upgrade Procedure
The smallest justified change is to update the container image to the new version. But do it in a controlled way.
Step 1: Pull the new image.
docker pull minio/minio:RELEASE.2024-02-17T17-12-33Z
Replace the tag with your target version. Verify the image signature if you use Docker Content Trust.
Step 2: Stop the current container.
docker stop minio-container
Step 3: Start a new container with the same volumes and environment.
docker run -d --name minio-container-new \
-p 9000:9000 -p 9001:9001 \
-v /data/minio:/data \
-e MINIO_ROOT_USER=access-key-placeholder \
-e MINIO_ROOT_PASSWORD=secret-key-placeholder \
minio/minio:RELEASE.2024-02-17T17-12-33Z server /data
Do not reuse the same container name. Use a new name so you can roll back by stopping the new container and starting the old one.
Step 4: Verify the new version.
docker exec minio-container-new minio --version
Step 5: Validate functionality (see Verification and Diagnostics). Only after successful validation, remove the old container.
Kubernetes Upgrade Procedure
For Kubernetes, update the image tag in the deployment or statefulset. If you have a multi-node distributed MinIO, use a StatefulSet with persistent volumes. The upgrade should be rolling to avoid downtime.
Step 1: Update the image tag.
kubectl set image statefulset/minio minio=minio/minio:RELEASE.2024-02-17T17-12-33Z -n minio-namespace
Step 2: Monitor the rolling update.
kubectl rollout status statefulset/minio -n minio-namespace
Expected output:
Waiting for 1 pods to be ready...
statefulset rolling update complete
Step 3: Check pod versions.
kubectl exec -n minio-namespace minio-0 -- minio --version
Single-Node Multi-Drive (SNMD) Upgrade
On a single node with multiple drives, you can stop the MinIO service, replace the binary, and restart. But first stop all client traffic. Use a maintenance window.
Step 1: Stop the service.
sudo systemctl stop minio
Step 2: Download the new binary.
wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio
chmod +x /usr/local/bin/minio
Step 3: Start the service.
sudo systemctl start minio
Step 4: Check the version.
minio --version
Migration Path: Moving Data to New Version or New Hardware
Sometimes you need to migrate data from an old MinIO instance to a new one, either because you are upgrading the underlying infrastructure or moving to a new cluster. The safest migration uses mc mirror.
Example: Mirror data from old MinIO to new MinIO.
Set up aliases:
mc alias set old-minio http://old-minio.example.com access-key-placeholder secret-key-placeholder
mc alias set new-minio http://new-minio.example.com new-access-key-placeholder new-secret-key-placeholder
Run the mirror command:
mc mirror --watch --remove old-minio/bucket-name new-minio/bucket-name
The --watch flag keeps the mirror running to catch new changes. The --remove flag deletes files in the destination that do not exist in the source (useful for a final cutover).
After the initial sync, perform a final sync during a maintenance window when no new writes are expected. Then switch your application endpoints to the new MinIO.
Verification and Diagnostics
After upgrading or migrating, you must verify that the system works correctly. Do not assume success because the process exited without error. Run explicit checks.
Check Server Health
Use mc admin info again:
mc admin info myminio
Compare the version and drive status with the baseline. All drives should be OK.
Test S3 Operations
Use mc to perform basic operations:
mc ls myminio
mc mb myminio/test-bucket
mc cp test-file.txt myminio/test-bucket/
mc cat myminio/test-bucket/test-file.txt
If you have buckets with objects, list a sample:
mc ls myminio/existing-bucket --recursive | head
For more thorough testing, use an S3 client like aws cli or s3cmd with test credentials.
Check Logs
Look for errors in the MinIO logs. In Docker:
docker logs minio-container-new --tail 100
In Kubernetes:
kubectl logs -n minio-namespace minio-0 --tail 100
Watch for messages about drive failures, authentication errors, or configuration problems.
Validate Application Connectivity
If you have applications using the MinIO endpoint, run their integration tests or manually test a few requests. Check that pre-signed URLs still work if you use them.
Performance Smoke Test
Run a quick upload and download to ensure performance is acceptable:
mc cp /tmp/100MB-test-file myminio/test-bucket/
time mc cp myminio/test-bucket/100MB-test-file /tmp/restored-file
Compare the times with pre-upgrade baselines if you have them.
Failure Modes and Recovery
Even with careful planning, things can go wrong. Here are common failure modes and recovery actions.
Upgrade Fails: New Version Does Not Start
Symptoms: The new container exits immediately or the pod crashes. Logs show errors like incompatible configuration or missing dependencies.
Recovery: Roll back to the previous version.
For Docker:
docker stop minio-container-new
docker start minio-container
For Kubernetes:
kubectl rollout undo statefulset/minio -n minio-namespace
For systemd:
sudo systemctl stop minio
# restore old binary from backup
sudo cp /backup/minio-old /usr/local/bin/minio
sudo systemctl start minio
Upgrade Succeeds but Data Is Corrupted or Missing
Symptoms: Objects not found, checksum errors, or application failures. This is rare but possible if the upgrade had a bug or if drives were disrupted during the process.
Recovery: If you have a backup, restore from backup. Otherwise, try to repair using mc admin heal:
mc admin heal -r myminio/bucket-name
The heal command attempts to reconstruct missing or corrupt data using erasure coding. But it cannot fix data that was overwritten or deleted.
Migration Incomplete or Lost Data
Symptoms: After migration, some objects are missing in the destination. This can happen if the mirror process was interrupted or if new writes occurred after the final sync.
Recovery: Re-run the mirror with --watch until no differences remain. Then stop the source writes and perform a final sync. Verify object counts:
mc ls old-minio/bucket-name --recursive | wc -l
mc ls new-minio/bucket-name --recursive | wc -l
The counts should match.
Configuration Error After Upgrade
Symptoms: MinIO starts but clients cannot authenticate or access buckets. Logs show AccessDenied or InvalidAccessKeyId.
Recovery: Check that environment variables for root credentials are correct. If you changed the access key or secret key during the upgrade, update all clients. If you use a config file, verify its syntax and permissions.
Network or DNS Issues After Cutover
Symptoms: Applications cannot reach the new MinIO endpoint. This may be due to firewall rules, security groups, or DNS not updated.
Recovery: Test connectivity:
mc alias set test-new http://new-minio.example.com access-key-placeholder secret-key-placeholder
mc ls test-new
If connection fails, check network policies and DNS. Temporarily revert to the old endpoint if necessary.
Operations Checklist
Use this checklist before, during, and after the upgrade or migration.
Before the Operation
- [ ] Read the release notes for the target version and note any breaking changes.
- [ ] Verify cluster health with
mc admin info. Ensure all drives are OK. - [ ] Back up configuration files (e.g.,
config.json, environment variables, Kubernetes YAML). - [ ] Take a snapshot of important data if possible (e.g.,
mc mirrorto a backup location). - [ ] Plan a maintenance window with sufficient time for validation and rollback.
- [ ] Notify stakeholders and application teams about the scheduled change.
- [ ] Prepare rollback commands and test them in a staging environment if available.
- [ ] Ensure you have access to both old and new artifacts (binary, container image).
During the Operation
- [ ] Execute the upgrade or migration steps as documented.
- [ ] Monitor logs and health checks in real time.
- [ ] Record the exact commands and their outputs for the runbook.
- [ ] If any step fails or shows unexpected output, stop and assess before proceeding.
- [ ] For rolling upgrades in Kubernetes, watch
kubectl rollout statusto completion.
After the Operation
- [ ] Verify the new version with
minio --versionor equivalent. - [ ] Run
mc admin infoto confirm all drives are healthy. - [ ] Test basic S3 operations: list, put, get, delete.
- [ ] Test application connectivity and functionality.
- [ ] Check for any error logs over a period (e.g., 24 hours).
- [ ] Update documentation and runbooks with the new version and any configuration changes.
- [ ] If everything is stable, remove old containers or binaries after a retention period.
Conclusion
MinIO upgrade and migration are manageable when you follow a disciplined operational process. Start with a complete inventory of the current state. Make the smallest possible change, whether it is updating a container image or mirroring data to a new cluster. Verify the result with explicit commands and expected outputs. And always have a tested rollback plan.
The examples in this guide are generic but adaptable to your environment. The key principles remain: observe before changing, limit blast radius, protect sensitive values, verify outcomes, and document recovery steps. By applying these practices, you reduce the risk of downtime and data loss during MinIO operations.
Next step: identify the next upgrade or migration you need to perform, run through the Version and Environment Inventory checklist, and practice the procedure in a non-production environment. Build your confidence before touching production.