Production-ready, fully interactive MinIO installer for Ubuntu Server 22.04+ using Docker Compose v2. No manual editing of .env or docker-compose.yml is required.
- Interactive menu — pick an action, no need to remember commands
- CLI mode — pass a command directly for automation
- Automatic Docker installation (optional)
- Auto-generated configuration from templates
- Bind-mount storage (no Docker volumes)
- Optional host port exposure or internal-only Docker network
- Health checks and post-install verification
- Automatic bucket creation via MinIO Client (
mc) - Application user with least-privilege IAM policy (ListBucket, GetObject, PutObject, DeleteObject)
- Optional anonymous (public) read access per bucket
- Backup and restore support
- Lifecycle commands: start, stop, restart, logs, status, update
- Ubuntu Server 22.04 or newer
- Docker Compose v2 (
docker compose) curl,openssl,systemctl- User with permission to run Docker (member of
dockergroup) or root/sudo
git clone <repository-url> minio-setup
cd minio-setup
chmod +x setup.sh
./setup.shThe interactive menu opens automatically. Select 1) Install MinIO and follow the prompts. When installation completes, credentials and endpoints are displayed once — save them securely.
Pass a command directly without opening the menu:
./setup.sh install
./setup.sh status
./setup.sh backup.
├── setup.sh # Main entry point (menu + CLI)
├── docker-compose.yml.tpl # Compose template
├── .env.tpl # Environment template
├── README.md
└── lib/
├── bootstrap.sh # Library loader
├── menu.sh # Interactive action menu
├── commands.sh # Command dispatcher
├── install.sh # Install entry point
├── uninstall.sh # Uninstall entry point
├── ui.sh # Banners and interactive prompts
├── validation.sh # System and input validation
├── docker.sh # Docker install and container ops
├── generator.sh # Template rendering
├── credentials.sh # Root credential reset (IAM store)
├── mc.sh # MinIO Client helpers (buckets, IAM, anonymous access)
├── access.sh # Bucket/user access setup and manage menu
├── installer.sh # Install flow, backup, restore
├── network.sh # Docker network management
└── utils.sh # Shared utilities
Generated at install time (do not edit manually):
.envdocker-compose.yml
| # | Action | Description |
|---|---|---|
| 1 | Install | Run interactive MinIO installation |
| 2 | Uninstall | Remove containers, network, and config |
| 3 | Start | Start MinIO |
| 4 | Stop | Stop MinIO |
| 5 | Restart | Restart MinIO |
| 6 | Status | Show container and endpoint status |
| 7 | Logs | Show recent container logs |
| 8 | Update | Pull latest MinIO image and recreate |
| 9 | Backup | Create compressed backup |
| 10 | Restore | Restore from backup archive |
| 11 | Update Public URLs | Set or update MINIO_SERVER_URL / MINIO_BROWSER_REDIRECT_URL |
| 12 | Reset Root Password | Reset root username/password (keeps bucket data) |
| 13 | Diagnose | Troubleshoot login and credential issues |
| 14 | Manage Buckets & User Access | Create buckets, public access, application user, and IAM policy |
| 0 | Exit | Close the menu |
| Command | Description |
|---|---|
./setup.sh |
Open interactive menu |
./setup.sh install |
Run interactive installation |
./setup.sh uninstall |
Remove containers, network, and config |
./setup.sh start |
Start MinIO |
./setup.sh stop |
Stop MinIO |
./setup.sh restart |
Restart MinIO |
./setup.sh logs |
Show recent container logs (-f to follow) |
./setup.sh diagnose |
Troubleshoot login and credential issues |
./setup.sh status |
Show container and endpoint status |
./setup.sh update |
Pull latest MinIO image and recreate |
./setup.sh update-urls |
Update public API and Console URLs |
./setup.sh reset-password |
Reset root username and password |
./setup.sh manage-access |
Configure buckets, public access, and application user |
./setup.sh backup |
Create compressed backup |
./setup.sh restore [file] |
Restore from backup archive |
The installer asks for:
- Container name (default:
minio) - Storage path (default:
/opt/minio/data) — created automatically - Expose to host — if yes, configure API (9000) and Console (9001) ports
- Root username (default:
minioadmin) - Password — auto-generated (24+ alphanumeric chars) or manual (letters and numbers, min 24)
- Buckets — create one or more buckets during setup
- Public access — choose which buckets allow anonymous download
- Application user — optional IAM user (default:
app-user) with least-privilege policy on selected buckets - Public URLs — optional; for domain + reverse proxy (HTTPS)
It then:
- Validates Ubuntu version, Docker, disk space, RAM, and ports
- Generates
.envanddocker-compose.yml - Creates the
minio-networkDocker network - Starts MinIO and waits until healthy
- Waits for the API to accept
mccommands, then creates buckets, IAM policy, and application user (idempotent) - Configures anonymous read access only on selected public buckets
- Displays a final summary with root admin, application user, bucket access, and endpoints
If you choose not to expose ports, MinIO is reachable only on the Docker network minio-network. Other containers on that network can connect at:
http://<container-name>:9000 # API
http://<container-name>:9001 # Console
When MinIO is accessed via a public domain behind Nginx, Traefik, or another reverse proxy with TLS, configure these MinIO environment variables:
| Variable | Purpose | Example |
|---|---|---|
MINIO_SERVER_URL |
Public S3 API URL (presigned URLs, hostname) | https://s3.example.com |
MINIO_BROWSER_REDIRECT_URL |
Public Console URL (login redirect) | https://console.example.com |
During install, you can set them in the optional step at the end.
For an existing installation (including setups created before this feature), update anytime:
./setup.sh update-urlsOr select 11) Update Public URLs from the menu.
The command updates only the public URL entries in .env and refreshes docker-compose.yml — root password and other settings are not modified. The container is then recreated to apply changes. You can also clear previously set URLs from the same prompt.
Important: After setting MINIO_BROWSER_REDIRECT_URL, open the Console using that public URL (via your reverse proxy). Logging in at http://<server-ip>:9001 often fails because MinIO redirects the session to the configured public URL.
If you cannot log in (lost password or .env out of sync with MinIO), reset root credentials:
./setup.sh reset-passwordOr select 12) Reset Root Password from the menu.
This will:
- Stop MinIO
- Remove the MinIO config store on disk (
.minio.sys/config) — users, groups, service accounts, and policies (backup created automatically) - Set a new root username and password in
.env - Start MinIO and apply the new credentials
Buckets and object data are preserved. IAM users, groups, and policies are cleared automatically and must be recreated if needed.
Credentials are written to secrets/root_password and mounted via MINIO_ROOT_PASSWORD_FILE (MinIO's recommended method), so passwords reach the container exactly as stored in .env.
Pull the latest MinIO image and recreate the container:
./setup.sh updateOr select 8) Update from the menu.
This preserves your data directory and configuration.
Create a timestamped archive containing configuration and data:
./setup.sh backupOutput example:
backups/backup-20250627-143022.tar.gz
Contents:
config/docker-compose.ymlconfig/.envdata.tar(MinIO data directory)
Restore from a backup archive:
./setup.sh restore backups/backup-20250627-143022.tar.gzOr select 10) Restore from the menu (you will be prompted for the archive path).
Restore stops MinIO, replaces configuration and data, then restarts and verifies health.
./setup.sh uninstallOr select 2) Uninstall from the menu.
You will be prompted to:
- Confirm removal of containers and generated config
- Optionally delete the data directory
Templates and setup scripts remain in the project directory.
Add your user to the docker group and re-login:
sudo usermod -aG docker "$USER"
newgrp dockerChoose different API/Console ports during installation, or free the port:
sudo ss -tulpn | grep :9000Check logs:
./setup.sh logsVerify data directory permissions:
ls -la /opt/minio/dataRestart:
./setup.sh restart- Confirm ports are exposed if accessing from outside Docker
- Check firewall rules:
sudo ufw status
sudo ufw allow 9000/tcp
sudo ufw allow 9001/tcp- Verify status:
./setup.sh statusCredentials are written to secrets/root_password and mounted via MINIO_ROOT_PASSWORD_FILE (MinIO's recommended method), so the exact password reaches the container without Docker Compose interpolation issues.
Run diagnostics first:
./setup.sh diagnoseThis checks container status, tests API login with your .env credentials, shows the correct Console URL, and prints recent logs.
Common causes:
- Wrong Console URL — If
MINIO_BROWSER_REDIRECT_URLis set, log in via that public URL, nothttp://<ip>:9001. - Stale IAM credentials — Reinstalling over existing data without IAM reset leaves old passwords active. Run
./setup.sh reset-password. - Container not running —
./setup.sh logsshowed nothing because the container was stopped. Run./setup.sh startthen./setup.sh diagnose. - Outdated config — Pull latest code, then
./setup.sh reset-passwordto migrate toMINIO_ROOT_PASSWORD_FILE.
This is usually not a password change. MinIO stores root credentials on first install in the data volume; update-urls does not reset them.
Common causes:
- Wrong URL — Use the public Console URL (
MINIO_BROWSER_REDIRECT_URL), nothttp://<ip>:9001, after redirect is configured. - Reverse proxy — Ensure your proxy forwards WebSocket and cookies to MinIO Console correctly.
- Outdated installer — Pull the latest code and run
./setup.sh reset-password.
To clear public URLs and restore direct IP access:
./setup.sh update-urls
# Choose to clear existing public URLs when promptedIf login still fails on both IP and public URL, reset credentials:
./setup.sh reset-passwordThe reset recreates the Docker container so new credentials from .env are applied. If MINIO_BROWSER_REDIRECT_URL is set, log in via that public URL — not http://<ip>:9001.
Ensure MinIO is healthy, then re-run the access wizard:
./setup.sh manage-accessOr check status and logs:
./setup.sh status
./setup.sh logsValidate scripts locally:
shellcheck setup.sh lib/*.shAfter installation, use menu 14) Manage Buckets & User Access or:
./setup.sh manage-accessSub-menu options:
- Configure buckets and public access — add buckets and set anonymous download
- Create or update application user — set username/password and attach IAM policy
- Apply full access setup — run the complete interactive wizard (same as install)
- Show current access summary — display configured buckets and endpoints
CLI shortcuts:
./setup.sh manage-access buckets # buckets + public access only
./setup.sh manage-access user # application user only
./setup.sh manage-access full # full wizard
./setup.sh manage-access summary # print summaryThe application user receives a generated IAM policy with only ListBucket, GetObject, PutObject, and DeleteObject on the configured buckets. Operations are idempotent — re-running setup updates policies and users without failing on existing resources.
Application passwords are stored in secrets/app_password (not in .env).
.envis written with mode600and contains the root password- Use strong passwords; manual entry requires at least 24 alphanumeric characters (uppercase, lowercase, and numbers)
- For production, place MinIO behind a reverse proxy with TLS
- Restrict host port exposure with firewall rules when enabled
- Back up
.envand data regularly
MIT — use freely in your infrastructure.