How to Self-Host MinIO on Coolify in 2026 (With a Full Admin Console)
If you want S3-compatible object storage on your own VPS, MinIO is still one of the most familiar options. The setup is different in 2026, though: the old one-click path is gone from Coolify, the community UI is far more limited, and older container images may no longer be the version you want to expose to production traffic.
🧰 TL;DR
This guide shows you how to deploy a patched MinIO server on Coolify, pair it with a full-featured OpenMaxIO admin console, connect both services to HTTPS domains, create proper credentials, and verify the setup using an S3 client.
- MinIO runs the S3-compatible storage layer.
- OpenMaxIO restores a fuller administration interface.
- Coolify manages deployment, domains, SSL, volumes, and environment variables.
- A quick Python test confirms uploads, downloads, listing, and presigned URLs.
s3.example.com, a separate browser-based console such as console.example.com, persistent data storage, and credentials you can use from WordPress, Python, n8n, backup tools, or other S3-compatible applications.
⚙ Personalize the copy-paste examples
Enter your two public domains below. The code examples on this page will update in your browser only.
No values are sent anywhere; this is simple in-page JavaScript.
Why MinIO on Coolify is different in 2026
Many MinIO tutorials published before late 2025 assume you can choose MinIO from a platform catalog, pull a current official Docker image, and use the bundled web console for users, policies, and access keys. That workflow is no longer a safe assumption.
1. The old one-click route changed
Coolify no longer gives you the same MinIO catalog experience older guides were built around, so a Docker Compose service is the more dependable route.
2. The community console changed
The newer community experience focuses on object browsing and does not expose the complete administration surface many self-hosters expect.
3. Image choice matters
A frozen or outdated container image can leave you stuck on an older server build. Pin the exact version you intend to run and review its provenance.
4. Reverse proxy URLs matter
S3 request signing is hostname-sensitive. MinIO needs to know the public URL that clients use through Coolify’s proxy.
minio/minio:latest example from a 2023 or 2024 tutorial. In 2026, treat the container source and release version as part of the security decision, not as an afterthought.
The stack you are building
The storage server and the administrator UI are separate pieces. MinIO stores objects and exposes the S3 API. OpenMaxIO gives you a more complete browser-based administration experience. Coolify sits in front and routes each public domain to the correct container port.
Port 9000
Port 9090
The console talks to MinIO over Coolify’s private Docker network. Your applications do not need to go through the console at all; they speak directly to the MinIO S3 endpoint.
Requirements before you start
- A VPS with Coolify already installed and working.
- Two DNS records you can point to the server, for example
s3.example.comandconsole.example.com. - Enough persistent disk space for the files you plan to store.
- Terminal access to your local computer for the final test.
- A plan for off-site backups. Self-hosted object storage is not a backup by itself.
If Coolify itself is unreachable, fix that before deploying storage. You can also see my related troubleshooting article: Coolify Server Not Reachable: common fixes.
Deploy MinIO and OpenMaxIO in Coolify
Open the Coolify project where you want the storage service. Choose New Resource → Docker Compose Empty. Paste the following Compose file, save it, and let Coolify create the generated passwords.
services:
minio:
image: hasanaboulhasan/minio:RELEASE.2025-10-15T17-29-55Z
command: server /data --console-address ":9001"
environment:
- SERVICE_FQDN_MINIO_9000
- MINIO_ROOT_USER=${SERVICE_USER_MINIO}
- MINIO_ROOT_PASSWORD=${SERVICE_PASSWORD_MINIO}
volumes:
- minio-data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 10s
timeout: 5s
retries: 5
console:
image: hasanaboulhasan/openmaxio-console:v1.7.6
environment:
- SERVICE_FQDN_CONSOLE_9090
- CONSOLE_MINIO_SERVER=http://minio:9000
- CONSOLE_PBKDF_PASSPHRASE=${SERVICE_PASSWORD_PBKDFPASS}
- CONSOLE_PBKDF_SALT=${SERVICE_PASSWORD_PBKDFSALT}
healthcheck:
disable: true
depends_on:
minio:
condition: service_healthy
volumes:
minio-data:
minio service exposes the storage API internally on port 9000 and mounts a named volume at /data. The console service connects to MinIO by the Docker service name minio, so the admin traffic stays on the private network.
About the images: this example uses a patched MinIO build mirrored from a Coolify-maintained build and an OpenMaxIO console image. If you prefer a different maintained MinIO distribution, replace the image only after checking compatibility and release notes. Pin versions in production instead of relying on a floating tag.
Connect the two domains
Create two DNS A records pointing at your Coolify server. Then open each service inside the stack and set its public domain.
MinIO service domain:
https://s3.example.comConsole service domain:
https://console.example.comYou normally do not need to append :9000 or :9090 to the public URLs. The SERVICE_FQDN_... variables tell Coolify which internal port to route.
Add the two public URL environment variables
This is the part that often separates a browser-visible deployment from a correctly working S3 deployment. Open the resource’s Environment Variables area and add the public MinIO URL plus the browser redirect URL as literal values.
MINIO_SERVER_URL=https://s3.example.com
MINIO_BROWSER_REDIRECT_URL=https://console.example.comDeploy, verify health, and log in
Click Deploy in Coolify. Wait until MinIO reports healthy and the console container is running. Then open the console domain in your browser.
Coolify creates the root credentials from the generated service variables. You can view those values on the MinIO service page. Use them for the first login, confirm you can see buckets and administration options, and then create a dedicated administrator account for everyday use.
Create a separate console administrator
Open the terminal for the MinIO container in Coolify and run the following commands. Replace CHANGE_THIS_TO_A_LONG_RANDOM_SECRET with a strong randomly generated value.
mc alias set local http://localhost:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD"
mc admin user add local console "CHANGE_THIS_TO_A_LONG_RANDOM_SECRET"
printf '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["admin:*"]},{"Effect":"Allow","Action":["s3:*"] ,"Resource":["arn:aws:s3:::*"]}]}' > /tmp/console-admin.json
mc admin policy create local consoleAdmin /tmp/console-admin.json
mc admin policy attach local consoleAdmin --user=consoleAfter that, sign out of the root account and use the dedicated console user for administration. For applications, create narrower keys with access limited to the exact bucket or actions they need.
Prove the S3 endpoint works from your own machine
A green container in Coolify does not prove that external S3 authentication, uploading, reading, listing, and presigned URLs all work through your public domain. Test the complete path.
Install the AWS-compatible Python client:
python3 -m pip install boto3Create a small file called test_minio.py. Replace the two credential placeholders with an access key and secret created for testing.
import boto3
from botocore.client import Config
ENDPOINT = "https://s3.example.com"
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
BUCKET = "coolify-minio-test"
s3 = boto3.client(
"s3",
endpoint_url=ENDPOINT,
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
region_name="us-east-1",
config=Config(signature_version="s3v4"),
)
# 1) Create a bucket if it does not exist
existing = [b["Name"] for b in s3.list_buckets().get("Buckets", [])]
if BUCKET not in existing:
s3.create_bucket(Bucket=BUCKET)
# 2) Upload an object
s3.put_object(
Bucket=BUCKET,
Key="hello.txt",
Body=b"MinIO on Coolify is working."
)
# 3) Read it back
obj = s3.get_object(Bucket=BUCKET, Key="hello.txt")
print(obj["Body"].read().decode())
# 4) List objects
result = s3.list_objects_v2(Bucket=BUCKET)
print([item["Key"] for item in result.get("Contents", [])])
# 5) Generate a presigned URL
url = s3.generate_presigned_url(
"get_object",
Params={"Bucket": BUCKET, "Key": "hello.txt"},
ExpiresIn=900,
)
print("Presigned URL:", url)Run it with:
python3 test_minio.pyYou want to see the uploaded text, the object name, and a presigned HTTPS URL that opens successfully before its expiration time.
Common MinIO + Coolify problems and fixes
“InvalidAccessKeyId” even though the credentials look correct
First confirm the key really exists. If it does, check MINIO_SERVER_URL. The endpoint must match the same public hostname your client signs requests against. Also redeploy after environment-variable changes.
The console opens but only looks like an object browser
That usually means you are looking at MinIO’s reduced browser experience rather than the separate OpenMaxIO administration service. Confirm the console container exists and that your console domain routes to port 9090.
Console cannot connect to MinIO
Verify CONSOLE_MINIO_SERVER=http://minio:9000. Inside the Docker network, the service name minio is the hostname. Do not point the console back through the external HTTPS domain unless you have a specific reason to do so.
Coolify shows the console as unhealthy
The OpenMaxIO container may not include a shell or utility suitable for a conventional health check. The Compose example disables that healthcheck intentionally. Check container logs and the public URL instead.
Uploads disappear after a redeploy
Make sure /data is backed by the named minio-data volume. If you change the service name, volume name, or mount configuration, verify that Coolify is still attaching the original persistent storage rather than creating a fresh one.
Large uploads fail through the domain
Check reverse-proxy timeouts, request-size limits, available disk, and filesystem permissions. Large multipart S3 uploads put more pressure on storage and proxy configuration than a small browser test.
Production hardening: do this before storing important data
The deployment above gets the service working. Production readiness is the next layer.
- Stop using the root account for routine work. Keep root credentials offline or in a password manager.
- Give each app its own access key. Avoid sharing one universal secret across WordPress, automation tools, and backup jobs.
- Use least-privilege policies. If an app only needs one bucket, do not grant access to every bucket.
- Back up the MinIO volume off-site. A second disk in the same server does not protect you from VPS loss or account compromise.
- Keep the server image patched. Review release information before upgrading and keep a rollback plan.
- Protect Coolify itself. Use SSH keys, firewall rules, 2FA where available, and keep the host OS current.
- Monitor disk capacity. Object storage can quietly fill a VPS and affect every service sharing that server.
Frequently asked questions
Can I still self-host MinIO in 2026?
Yes. The server remains useful for S3-compatible storage, but you should be deliberate about which maintained or patched container build you deploy and should not depend on outdated one-click instructions.
Why use OpenMaxIO with MinIO?
OpenMaxIO is useful when you want the fuller administration experience—such as identity, policies, and access-key management—that many people remember from older MinIO console releases.
Do I need two domains?
No, not strictly, but two domains make the architecture cleaner: one endpoint dedicated to the S3 API and another dedicated to the browser console.
Can WordPress use this MinIO server?
Yes, if the plugin or integration you choose supports custom S3-compatible endpoints. Use a dedicated access key restricted to the WordPress bucket instead of your root credentials.
Can I use MinIO for Coolify database backups?
Potentially, yes. Coolify supports S3-compatible backup destinations. Create a dedicated bucket and credentials, then validate the connection before depending on it for recovery.
Should the S3 endpoint be public?
The endpoint needs to be reachable by the applications that use it. If every client is on the same private network, public access may not be necessary. If remote applications need it, expose it through HTTPS and keep bucket permissions private by default.
What port does MinIO use?
The S3 API normally listens on port 9000 in this setup. The public Coolify domain terminates HTTPS and routes traffic to that internal port.
What port does OpenMaxIO use here?
This Compose setup routes the console through internal port 9090, exposed publicly through the separate console domain.
Next: connect MinIO to your apps
Once the S3 test passes, create one bucket and one least-privilege key per application. Then connect your backup jobs, media workflows, automation tools, or custom apps using the public endpoint.
Read Coolify Documentation →Last reviewed for this article: August 2026. Always verify current image provenance, release notes, and security advisories before exposing object storage to production traffic.