MinIO provides an S3-compatible object storage API that works well for development, private clouds, backups, and application file storage. This guide starts with a single-node Docker Compose deployment and then explains what must change before exposing it to production traffic.
Prerequisites
Install Docker Engine and the Docker Compose plugin, then verify them:
1 | docker version |
Create directories for persistent data and configuration:
1 | sudo mkdir -p /srv/minio/data |
Docker Compose configuration
Create compose.yaml:
1 | services: |
Store credentials in a local .env file and keep it out of version control:
1 | MINIO_ROOT_USER=minio-root |
Start the service and inspect its health:
1 | docker compose up -d |
The S3 API listens on port 9000; the administration console uses 9001.
Configure the MinIO client
Install the official mc client, then create an alias:
1 | mc alias set local http://127.0.0.1:9000 minio-root 'your-password' |
Applications should not use the root account. Create a dedicated user and attach only the policy it needs:
1 | mc admin user add local app-user 'another-long-random-secret' |
For production, replace the broad readwrite policy with a bucket-specific policy.
Production checklist
A running container is not yet a resilient storage service:
- Terminate TLS at MinIO or a trusted reverse proxy, and do not expose the console publicly without access controls.
- Pin an image release, test upgrades in staging, and read the release notes before changing versions.
- Use multiple drives and nodes when availability matters. A single data directory has no disk redundancy.
- Back up configuration and critical objects to a separate failure domain.
- Monitor disk capacity, request errors, latency, and node health.
- Restrict ports with a firewall and rotate credentials regularly.
Common problems
If the container exits immediately, check directory ownership and docker compose logs. If S3 requests work locally but fail through a proxy, verify forwarded headers, the public server URL, TLS configuration, and request-size limits. Clock drift can also break signed S3 requests, so keep the host synchronized with NTP.
