In this tutorial, you will learn how to install MinIO on Ubuntu 24.04 server. MinIO is a high-performance, open-source object storage server that is compatible with the Amazon S3 API (Simple Storage Service). It’s designed to handle large-scale unstructured data like photos, videos, log files, backups, and container images. In this step-by-step guide, we’ll walk you through installing and configuring MinIO on Ubuntu 24.04, including setting up a secure Nginx reverse proxy and Let’s Encrypt SSL.
Table of Contents
How to Install MinIO on Ubuntu 24.04: Step-by-Step
Why Choose MinIO as your Object Storage?
MinIO stands out as a the best alternative to cloud-based storage solutions like Amazon S3. Some of the reasons why you may consider for your local object storage include:
- Open-Source and Cost-Effective: MinIO is free to use, with no licensing fees, making it ideal for startups, developers, and enterprises looking to reduce costs.
- Amazon S3 Compatibility: MinIO supports the S3 API, allowing seamless integration with tools and applications designed for AWS S3. If you feel like you are ready to use AWS S3, you can simply make the switch with very little changes on your applications, and vice versa is true (switching from AWS S3 to MinIO).
- High Performance: Built in Go, MinIO delivers exceptional speed for data-intensive workloads like machine learning and analytics.
- Self-Hosted Flexibility: Host MinIO on your own infrastructure, giving you full control over data privacy and compliance.
- Scalability: MinIO scales from a single server to distributed clusters, handling petabytes of data effortlessly.
- Enterprise Features: Includes encryption, erasure coding, and versioning for robust data protection.
Whether you’re building a private cloud or need a local S3-compatible storage solution, MinIO is a versatile choice.
What are the Common Use Cases for MinIO?
MinIO object storage provides a scalable, high-performance alternative to traditional storage solutions. Some of the most common use cases for MinIO object storage include:
- Data Backup and Archiving: Store backups securely with MinIO’s versioning and encryption, perfect for Veeam or custom backup solutions. Organizations can implement tiered retention policies and benefit from immutable backups for ransomware protection.
- Big Data and Analytics: Serve as a data lake for Hadoop, Spark, or Presto, enabling fast access to large datasets. MinIO’s high throughput makes it ideal for data-intensive workloads where performance matters.
- Machine Learning Workflows: Store training datasets and models for ML pipelines, with high throughput for frameworks like TensorFlow. The S3 API compatibility ensures seamless integration with popular ML tools and platforms.
- Content Delivery: Host media files (e.g., images, videos) for web applications, with MinIO’s low-latency access. Content can be easily distributed and managed at scale across global deployments.
- Private Cloud Storage: Replace public cloud storage with MinIO for GDPR or HIPAA-compliant environments. Organizations maintain full control over their data while benefiting from cloud-like elasticity.
- Development and Testing: Simulate S3 environments locally for developers building S3-compatible applications. This accelerates development cycles and reduces cloud costs during testing phases.
- IoT Data Collection: Capture and store high-velocity data streams from IoT devices and sensors. MinIO’s lightweight architecture makes it suitable for edge deployments while maintaining compatibility with central data processing systems.
- Hybrid Cloud Deployments: Bridge on-premises and cloud environments with consistent object storage interfaces. MinIO provides the flexibility to move workloads between environments without changing application code.
- Log and Metrics Storage: Store application logs, system metrics, and monitoring data at scale. MinIO integrates well with observability tools like Prometheus, Grafana, and the ELK stack.
MinIO Deployment Topology Options
MinIO can be deployed using various topology options depending on your requirements for availability, scalability, and data protection. From simple development setups to enterprise-grade distributed systems, MinIO offers flexible deployment models to meet different needs:
- Single Node, Single Drive (SNSD): A basic MinIO installation running on a single server with one storage volume. This configuration provides zero data redundancy or fault tolerance. If the server or disk fails, your data is lost. Suitable only for development, testing, or learning environments where data persistence isn’t critical.
- Single Node, Multi-Drive (SNMD/JBOD (Just a Bunch of Drives)): MinIO running on a single server but utilizing multiple disks (Just a Bunch Of Disks). This increases storage capacity and can provide data redundancy through erasure coding across the drives. However, if the server itself fails, the entire system is down. Good for environments needing more storage and some data protection, but not mission-critical workloads.
- Distributed (Multi-Node, Multi-Drive): MinIO deployed across at least four independent servers, each with one or more drives. Uses erasure coding to distribute data across nodes, ensuring data remains available even if servers fail. This configuration provides true high availability, fault tolerance, and horizontal scalability. Recommended for production environments where uptime and data integrity are critical.
- Multi-Site Active-Active: Two or more complete MinIO clusters deployed in different physical locations that continuously replicate data between them. This setup enables geographic disaster recovery – if an entire data center fails, data remains accessible from another location. Provides the highest level of availability and protection against catastrophic failures. Ideal for globally distributed applications or mission-critical systems.
More info on documentation page.
Installing MinIO on Ubuntu 24.04
As you can see, there are multiple deployment options for MinIO for various use cases. In this tutorial, we will deploy MinIO on Ubuntu 24.04 using single node, multi drive topology just for the purposes of demonstrating how to set it up.
So, how can one deploy MinIO object storage on Ubuntu 24.04? Let’s dive in;
Before you proceed, ensure you have access to a non-root account with sudo rights on your Ubuntu 24.04 LTS.
Step 1: MinIO Resource Requirements
The summary outlines the compute and storage requirements for deploying MinIO in production, based on MinIO’s recommended configuration. These are baseline guidelines and should be validated with MinIO’s Performance Diagnostics or support for specific workloads. All nodes in a server pool must have identical hardware and software configurations to ensure consistent performance.
Compute Requirements:
- Hosts:
- Minimum: 4 dedicated baremetal or virtual hosts.
- Recommended: 8+ dedicated hosts for scalability and reliability.
- CPU:
- Minimum: 8 CPU cores/socket or vCPUs per host, supporting modern SIMD instructions (e.g., AVX-512, Intel® Xeon® Scalable or better).
- Recommended: 16+ CPU cores/socket or vCPUs per host for high-performance workloads (e.g., AI/ML, analytics).
- Identical CPUs across all nodes to avoid performance bottlenecks.
- Memory:
- Minimum: 32GB of available RAM per host.
- Recommended: 128GB+ per host, especially for concurrent connections or large-scale workloads.
- Starting with RELEASE.2024-01-28T22-35-53Z, MinIO preallocates 2GB (distributed) or 1GB (single-node) per node.
- Memory scales with storage:
- Up to 1 TiB: 8GB
- Up to 10 TiB: 16GB
- Up to 100 TiB: 32GB
- Up to 1 PiB: 64GB
- Over 1 PiB: 128GB
- Identical memory across nodes to prevent constraints on concurrent requests.
Networking:
- Minimum: 25GbE network infrastructure.
- Recommended: 100GbE for maximum throughput (supports ~12.5GBps aggregated storage throughput).
- Network bandwidth is critical, as it directly impacts performance (e.g., 25GbE supports ~30 spinning disks at 100MB/s each).
Storage Requirements:
- Drives:
- Minimum: 4 drives per MinIO server (locally attached).
- Recommended: 8+ drives per server for better redundancy and performance.
- Exclusive access required; no other processes should modify MinIO’s data shards, parity shards, or metadata.
- Storage Type:
- Recommended: Flash-based storage (NVMe preferred, SSD acceptable) for all workloads due to superior performance.
- HDD Usage: Only for cold-tier storage (e.g., aged data transitioned via Object Transition). HDDs underperform for modern workloads, negating cost benefits.
- Use Direct-Attached Storage (DAS) like JBOD arrays, avoiding networked storage (NAS, SAN, NFS) for performance and consistency.
- Drive Consistency:
- Identical drive type (NVMe, SSD, or HDD) and capacity across all nodes in a server pool. Mixing types or sizes limits usable capacity to the smallest drive (e.g., one 1TB drive in a pool of 10TB drives caps all at 1TB).
- Filesystem Settings:
- Format drives as XFS with unique labels (e.g., mkfs.xfs /dev/vdb -L MINIODRIVE1).
- Mount drives consistently via /etc/fstab using labels, not UUIDs, for easier drive replacement (e.g., LABEL=MINIODRIVE1 /mnt/drive-1 xfs defaults,noatime 0 2).
- Disable XFS retry-on-error for EIO, ENOSPC, and default errors to avoid latency (e.g., set max_retries to 0 via a script run at @reboot with cron).
Read more on the documentation page.
As already mentioned, we will be setting up an SNMD MinIO server.
We have four drives to use;
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
vda 253:0 0 8.5G 0 disk
├─vda1 253:1 0 7.5G 0 part /
├─vda14 253:14 0 4M 0 part
├─vda15 253:15 0 106M 0 part /boot/efi
└─vda16 259:0 0 913M 0 part /boot
vdb 253:16 0 5G 0 disk
vdc 253:32 0 5G 0 disk
vdd 253:48 0 5G 0 disk
vde 253:64 0 5G 0 disk
As recommended, the drives need to be formatted with an XFS filesystem each with its unique label.
sudo mkfs.xfs /dev/vdb -L MINIODRIVE0
sudo mkfs.xfs /dev/vdc -L MINIODRIVE1
sudo mkfs.xfs /dev/vdd -L MINIODRIVE2
sudo mkfs.xfs /dev/vde -L MINIODRIVE3
Create the Drives mount points. We will be using /opt/minio in this setup:
sudo mkdir -p /opt/minio/{miniodrive0,miniodrive1,miniodrive2,miniodrive3}
Mount the drives;
sudo mount /dev/vdb /opt/minio/miniodrive0
sudo mount /dev/vdc /opt/minio/miniodrive1
sudo mount /dev/vdd /opt/minio/miniodrive2
sudo mount /dev/vde /opt/minio/miniodrive3
Update the FSTAB for automounting during system reboot. MinIO strongly recommends using label-based mounting rules over UUID-based rules. Hence:
echo "
LABEL=MINIODRIVE0 /opt/minio/miniodrive0 xfs defaults,noatime 0 2
LABEL=MINIODRIVE1 /opt/minio/miniodrive1 xfs defaults,noatime 0 2
LABEL=MINIODRIVE2 /opt/minio/miniodrive2 xfs defaults,noatime 0 2
LABEL=MINIODRIVE3 /opt/minio/miniodrive3 xfs defaults,noatime 0 2" \
| sudo tee -a /etc/fstab
If you have not mounted them already, just run;
sudo mount -a
Create a script to disable XFS retry on error. In the script below, replace the /opt/minio path to match the pattern used for your MinIO drives.
cat /opt/minio/disable-xfs-retry-on-error.sh
#!/bin/bash
for dev in $(df -h | grep /opt/minio | awk '{ print $1 }'); do
mountPath="$(df -h | grep $dev | awk '{ print $6 }')"
deviceName="$(basename $dev)"
echo "Modifying xfs max_retries and retry_timeout_seconds for drive $dev mounted at $mountPath"
echo 0 > /sys/fs/xfs/$deviceName/error/metadata/EIO/max_retries
echo 0 > /sys/fs/xfs/$deviceName/error/metadata/ENOSPC/max_retries
echo 0 > /sys/fs/xfs/$deviceName/error/metadata/default/max_retries
done
exit 0
Ensure the script is executable;
sudo chmod +x /opt/minio/disable-xfs-retry-on-error.sh
Run the script;
sudo /opt/minio/disable-xfs-retry-on-error.sh
Sample output;
Modifying xfs max_retries and retry_timeout_seconds for drive /dev/vdb mounted at /opt/minio/miniodrive0
Modifying xfs max_retries and retry_timeout_seconds for drive /dev/vdc mounted at /opt/minio/miniodrive1
Modifying xfs max_retries and retry_timeout_seconds for drive /dev/vdd mounted at /opt/minio/miniodrive2
Modifying xfs max_retries and retry_timeout_seconds for drive /dev/vde mounted at /opt/minio/miniodrive3
If you have multiple nodes, ensure the script is installed on all of them.
Schedule the script on run on every node reboot;
echo "@reboot /opt/minio/disable-xfs-retry-on-error.sh" | sudo crontab -
You can list jobs to confirm;
sudo crontab -l
Step 2: Update Your System
Start by updating your Ubuntu 24.04 system to ensure all packages are current. Run the command below to update your system;
sudo apt update
Next, install some of the commands that we may require;
sudo apt install wget curl -y
Step 2: Create a MinIO User and Directories
For security purposes, run MinIO as a non-root user. Therefore, create a system user and group called minio. You can use any suitable system account name.
sudo useradd -r -M -s /sbin/nologin minio
Let’s create MinIO configs directory as well (We will use this to keep TLS certs).
sudo mkdir /etc/minio
Update MinIO data directories ownership;
sudo chown -R minio: /opt/minio /etc/minio
Step 3: Download and Install MinIO on Ubuntu 24.04
MinIO provides precompiled binaries for various system architectures for easy installation. Follow these steps to download and install MinIO on Ubuntu 24.04.
Download the MinIO DEB Binary
On the MinIO binary releases page, navigate into your respective OS architecture page, for example, I am running an Ubuntu 24.04 under AMD64 Arch, hence, MinIO binary would be in the linux-amd64 directory.
You will find a DEB binary file in that directory. Grab its link and pull it into the MinIO server using wget or curl command.
wget https://dl.min.io/server/minio/release/linux-amd64/minio_20250422221226.0.0_amd64.deb -P /tmp
The command above will download MinIO DEB binary and store it under the /tmp directory.
Similarly, you can download respective SHASUM file to calculate the hash and check the integrity of the binary.
wget https://dl.min.io/server/minio/release/linux-amd64/minio_20250422221226.0.0_amd64.deb.sha256sum -P /tmp
To calcuate the hashes, navigate into the directory where both files are;
cd /tmp
The check the HASH;
sha256sum -c minio_20250422221226.0.0_amd64.deb.sha256sum
The output should be Ok to confirm that the integrity of the file is intact. Sample output;
minio_20250422221226.0.0_amd64.deb: OK
cd
Install MinIO on Ubuntu 24.04
Next, run the command below to install MinIO;
sudo apt install /tmp/minio_20250422221226.0.0_amd64.deb
This will install the minio binary under /usr/local/bin directory as /usr/local/bin/minio. As such, MinIO should already be available on CLI. Just to verify, let’s check its version;
minio --version
Output;
minio version RELEASE.2025-04-22T22-12-26Z (commit-id=0d7408fc9969caf07de6a8c3a84f9fbb10a6739e)
Runtime: go1.24.2 linux/amd64
License: GNU AGPLv3 - https://www.gnu.org/licenses/agpl-3.0.html
Copyright: 2015-2025 MinIO, Inc.
It also creates a Systemd service unit (minio.service) under, /usr/lib/systemd/system/minio.service.
Step 4: Configure MinIO Environment
Next, let create a few configurations for MinIO server.
To begin with, let’s create MinIO environment variables to get us started with.
sudo vim /etc/default/minio
Sample configs;
# MINIO_ROOT_USER and MINIO_ROOT_PASSWORD sets the root account for the MinIO server.
# This user has unrestricted permissions to perform S3 and administrative API operations on any resource in the deployment.
# Omit to use the default values 'minioadmin:minioadmin'.
# MinIO recommends setting non-default values as a best practice, regardless of environment.
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minIO-s3c-change-me
# MINIO_VOLUMES sets the storage volumes or paths to use for the MinIO server.
# The specified path uses MinIO expansion notation to denote a sequential series of drives between 1 and 4, inclusive.
# All drives or paths included in the expanded drive list must exist *and* be empty or freshly formatted for MinIO to start successfully.
MINIO_VOLUMES="/opt/minio/miniodrive{0...3}"
# MINIO_OPTS sets any additional commandline options to pass to the MinIO server.
# For example, `--console-address :9001` sets the MinIO Console listen port
MINIO_OPTS="--address :9000 --console-address :9001"
MinIO recommends access credentials with at least 3-character access key (starting with a letter) and 8-character secret key. Replace the values provided above.
MinIO, by default, uses port 9000 for its S3 API and port 9001 for the MinIO Console (web interface)
Replace the path to the MinIO volumes accordingly.
Save and exit the file.
Step 5: Set Up MinIO as a Systemd Service
As mentioned above, when you install MinIO via DEB, it will create a systemd service unit.
The service unit comes pre-configured. Let’s update it to make a few changes.
The default contents of the file;
cat /usr/lib/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
Type=notify
WorkingDirectory=/usr/local
User=minio-user
Group=minio-user
ProtectProc=invisible
EnvironmentFile=-/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
# Let systemd restart this service always
Restart=always
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=1048576
# Turn-off memory accounting by systemd, which is buggy.
MemoryAccounting=no
# Specifies the maximum number of threads this process can create
TasksMax=infinity
# Disable timeout logic and wait until process is stopped
TimeoutSec=infinity
# Disable killing of MinIO by the kernel's OOM killer
OOMScoreAdjust=-1000
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
# Built for ${project.name}-${project.version} (${project.name})
We will only make a few adjustments here:
- the minio user/group
- make the envs file non-optional (remove dash (-))
- the working directory of the service
The final unit file now looks like below;
cat /usr/lib/systemd/system/minio.service
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
Type=notify
WorkingDirectory=/opt/minio
User=minio
Group=minio
ProtectProc=invisible
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
# Let systemd restart this service always
Restart=always
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=1048576
# Turn-off memory accounting by systemd, which is buggy.
MemoryAccounting=no
# Specifies the maximum number of threads this process can create
TasksMax=infinity
# Disable timeout logic and wait until process is stopped
TimeoutSec=infinity
# Disable killing of MinIO by the kernel's OOM killer
OOMScoreAdjust=-1000
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
# Built for ${project.name}-${project.version} (${project.name})
Reload systemd;
sudo systemctl daemon-reload
Start MinIO;
sudo systemctl enable --now minio
Check the status;
systemctl status minio
● minio.service - MinIO
Loaded: loaded (/usr/lib/systemd/system/minio.service; enabled; preset: enabled)
Active: active (running) since Wed 2025-04-30 10:17:34 UTC; 3s ago
Docs: https://docs.min.io
Main PID: 4754 (minio)
Tasks: 10
CPU: 1.398s
CGroup: /system.slice/minio.service
└─4754 /usr/local/bin/minio server --address :9000 --console-address :9001 /opt/minio/miniodrive{0...3}
Confirm the ports are listening:
sudo ss -altnp | grep 900
LISTEN 0 4096 127.0.0.1:9000 0.0.0.0:* users:(("minio",pid=4754,fd=7))
LISTEN 0 4096 [::1]:9000 [::]:* users:(("minio",pid=4754,fd=9))
LISTEN 0 4096 *:9000 *:* users:(("minio",pid=4754,fd=8))
LISTEN 0 4096 *:9001 *:* users:(("minio",pid=4754,fd=6))
Step 6: Configure Firewall
As per our configuration above, MinIO listend on TCP port 9000 for API requests and TCP port 9001 for web console access.
Hence, open these ports on Firewall to allow access to MinIO;
I am using UFW on Ubuntu.
sudo ufw allow 9000/tcp
sudo ufw allow 9001/tcp
If you are using Firewalld/Iptables, use the appropriate commands to open these ports.
Step 7: Access the MinIO Console
Open a browser and navigate to http://your-server-ip:9001.

Log in with the MINIO_ROOT_USER and MINIO_ROOT_PASSWORD set in Step 4.
Upon successful login, you’ll see the MinIO web console dashboard. By default, you land on where you can create buckets and manage objects.

To create a bucket:
- Click the Create a Bucket.
- If you already have existing buckets, just click the + button in the console to add more.
- Enter a bucket name (e.g., my-bucket) and click Create.

Step 8: Secure MinIO with Nginx and Let’s Encrypt (Optional)
For production, you can secure MinIO with HTTPS using Nginx as a reverse proxy and Let’s Encrypt SSL.
Install Nginx
To install Nginx on Ubuntu 24.04;
sudo apt install nginx
Install Certbot for Let’s Encrypt
sudo apt install certbot python3-certbot-nginx -y
Create an Nginx HTTP configuration for the MinIO console.
Replace the FQDN minio-console.yourdomain.com appropriately.
sudo tee /etc/nginx/sites-enabled/minio-console.conf << EOF
server {
listen 80;
server_name minio-console.yourdomain.com;
location / {
proxy_pass http://localhost:9001;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
Confirm the file for syntax errors:
sudo nginx -t
It should be okay;
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Start and enable Nginx service;
sudo systemctl enable --now nginx
Open HTTP port on Firewall;
sudo ufw allow 80/tcp
You should now be able to access MinIO web console via your server domain address without specifying the web console port on the address.
Generate Let's Encrypt TLS Certificates
Now, to use SSL/TLS certs with Let's encrypt, you can generate them for your domain. I assume that you domain is already public and mapped to a public DNS.
In this example guide, I will generate wildcard SSL/TLS certs via Let's encrypt. I will do it a manual way.
Replace yourdomain.com accordingly.
sudo certbot certonly \
--manual \
--preferred-challenges dns \
--server https://acme-v02.api.letsencrypt.org/directory \
-d "*.yourdomain.com" \
-d "yourdomain.com"
When the command runs, Certbot pauses and asks you to provide your email address, accept terms of service, if you need to receive info about Let's encrypt and then finally to manually add a DNS TXT record to your DNS provider.
After adding the record, wait 1-5 minutes for DNS propagation, then press Enter in the Certbot prompt to continue.
Note that you might be asked to create multiple distinct TXT records with the same name. This is
permitted by DNS standards.) Before continuing, verify the TXT record has been deployed. Depending on the DNS provider, this may take some time, from a few seconds to multiple minutes.
You can even verify the propagation using DIG before pressing ENTER.
dig TXT _acme-challenge.yourdomian.com +short
Or you can use online tools, such as the Google Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.yourdomain.com. Look for one or more bolded line(s) below the line ';ANSWER'. It should show the value(s) you've just added.
Press ENTER to complete the generation.
...
Press Enter to Continue
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/yourdomain.com/privkey.pem
This certificate expires on 2025-07-29.
These files will be updated when the certificate renews.
NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
Remember we just did the cert generation manually. Hence, you will have to repeat SSL/TLS cert generation every 90 days before expiry. No automation is configured. But you can choose to automate the whole process.
Configure MinIO Server with TLS
You can configure MinIO server itself with TLS.
So, create the MinIO certs directory under the MinIO configs directory we created above, /etc/minio.
sudo mkdir -p /etc/minio/certs
Next, copy the Let's Encrypt TLS certs:
- Copy the fullchain.pem certificate as public.crt
- Copy the privkey.pem private key as private.key
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem /etc/minio/certs/public.crt
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem /etc/minio/certs/private.key
Update the ownership of the certs directory;
sudo chown -R minio: /etc/minio/certs/
Next, update the configuration value of the MINIO_OPTS to include the TLS certs.
sudo sed -i '/^MINIO_OPTS=.*/ s/"$/ --certs-dir \/etc\/minio\/certs"/' /etc/default/minio
The line should now look like;
grep ^MINIO_OPTS /etc/default/minio
MINIO_OPTS="--address :9000 --console-address :9001 --certs-dir /etc/minio/certs"
Restart MinIO service;
sudo systemctl restart minio
Update MinIO Web Console and API Nginx Configs with TLS certs to enable HTTPS
Now that we have the TLS certs, update the configs;
sudo tee /etc/nginx/sites-enabled/minio-console.conf << EOF
# HTTP server block for redirecting to HTTPS
server {
listen 80;
server_name minio-console.yourdomain.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://\$host\$request_uri;
}
# HTTPS server block
server {
listen 443 ssl;
server_name minio-console.yourdomain.com;
# SSL certificate and key
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL settings for security
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
location / {
proxy_pass https://minio-console.yourdomain.com:9001;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
Generate same config for the API;
sudo tee /etc/nginx/sites-enabled/minio-api.conf << EOF
# HTTP server block for redirecting to HTTPS
server {
listen 80;
server_name minio-api.yourdomain.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://\$host\$request_uri;
}
# HTTPS server block
server {
listen 443 ssl;
server_name minio-api.yourdomain.com;
# SSL certificate and key
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL settings for security
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
location / {
proxy_pass https://minio-api.yourdomain.com:9000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
Check Nginx for any errors;
sudo nginx -t
Ensure there are no errors!
Restart Nginx.
sudo systemctl restart nginx
Now, access the MinIO console at https://minio.yourdomain.com and the S3 API at https://minio-api.yourdomain.com. HTTP requests to http://minio.yourdomain.com or http://minio-api.yourdomain.com will automatically redirect to HTTPS.
Ensure your domain’s DNS records for minio.yourdomain.com and minio-api.yourdomain.com point to your server’s IP address. If you encounter SSL errors, verify the certificate paths and permissions

Step 9: Install MinIO Client on Ubuntu 24.04 (Optional)
The MinIO client allows command-line interaction with your server. Debian based systems ships the mc package as mcli. You can optionally install the MinIO client on Ubuntu 24.04 as follows;
wget https://dl.min.io/client/mc/release/linux-amd64/mcli_20250416181326.0.0_amd64.deb -P /tmp
Install the client:
sudo apt install /tmp/mcli_20250416181326.0.0_amd64.deb
You should be now be having MinIO client, mcli command in place;
mcli --version
Step 10: Using MinIO Client to Interact with MinIO Server
You can begin the usage of MinIO client by creating MinIO server alias. An alias in MinIO is a shortcut name that stores:
- The server API endpoint (e.g.,
https://minio.yourdomain.com:9000
). - Access credentials (access/secret keys).
- SSL/TLS settings (if using HTTPS).
Instead of typing the full server URL and credentials every time, you use the alias (e.g., minioapi
) to interact with the MinIO server via CLI tools like mc
(MinIO Client).
Before you can proceed, enable MinIO client command auto-completion:
mcli --autocompletion
Please reload your shell;
source ~/.bashrc
To create an alias for my MinIO endpoint, use mcli alias set command:
mcli alias set ALIAS
For example:
mcli alias set minioapi http[s]://minio-api.yourdomain.com
This will prompt for your ACCESS_KEY and SECRET_KEY. These values usually corresponds to:
- Default Values (if not customized):
- MINIO_ROOT_USER
- MINIO_ROOT_PASSWORD
- Custom Values (set in /etc/default/minio)
You can provide the values in CLI;
mcli alias set minioapi URL ACCESS_KEY SECRET_KEY
List aliases;
mcli alias ls
You can basically use the client to interact with the MinIO server. For example, you can list any buckets
mcli ls minioapi
Get info;
mcli admin info minioapi
Want non root user? Create as follows:
mcli admin user add SERVER_ALIAS
You will be prompted for username and password:
Enter Access Key: kifarunix
Enter Secret Key:
Added user `kifarunix` successfully.
Assign the roles/policies! You can list available roles/policies;
mcli admin policy list TARGET
TARGET is equivalent to MinIO server alias.
E.g
mcli admin policy list minioapi
consoleAdmin
diagnostics
readonly
readwrite
writeonly
Assign a role to the user.
mcli admin policy attach [FLAGS] TARGET POLICY [POLICY...] [--user USER | --group GROUP]
e.g
mcli admin policy attach minioapi readwrite --user kifarunix
To confirm the policy has been successfully attached, use the mcli admin user info TARGET USER command:
mcli admin user info minioapi kifarunix
Step 11: Complete list of MinIO Client CLI Options
To see a complete list of MinIO client commands you can use to interact with the server:
NAME:
mcli - MinIO Client for object storage and filesystems.
USAGE:
mcli [FLAGS] COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...]
COMMANDS:
alias manage server credentials in configuration file
admin manage MinIO servers
anonymous manage anonymous access to buckets and objects
batch manage batch jobs
cp copy objects
cat display object contents
cors manage bucket CORS configuration
diff list differences in object name, size, and date between two buckets
du summarize disk usage recursively
encrypt manage bucket encryption config
event manage object notifications
find search for objects
get get s3 object to local
head display first 'n' lines of an object
ilm manage bucket lifecycle
idp manage MinIO IDentity Provider server configuration
license license related commands
legalhold manage legal hold for object(s)
ls list buckets and objects
mb make a bucket
mv move objects
mirror synchronize object(s) to a remote site
od measure single stream upload and download
ping perform liveness check
pipe stream STDIN to an object
put upload an object to a bucket
quota manage bucket quota
rm remove object(s)
retention set retention for object(s)
rb remove a bucket
replicate configure server side bucket replication
ready checks if the cluster is ready or not
sql run sql queries on objects
stat show object metadata
support support related commands
share generate URL for temporary access to an object
tree list buckets and objects in a tree format
tag manage tags for bucket and object(s)
undo undo PUT/DELETE operations
update update mc to latest release
version manage bucket versioning
watch listen for object notification events
GLOBAL FLAGS:
--autocompletion install auto-completion for your shell
--config-dir value, -C value path to configuration folder (default: "/home/kifarunix/.mcli") [$MC_CONFIG_DIR]
--quiet, -q disable progress bar display [$MC_QUIET]
--disable-pager, --dp disable mc internal pager and print to raw stdout [$MC_DISABLE_PAGER]
--no-color disable color theme [$MC_NO_COLOR]
--json enable JSON lines formatted output [$MC_JSON]
--debug enable debug output [$MC_DEBUG]
--resolve value resolves HOST[:PORT] to an IP address. Example: minio.local:9000=10.10.75.1 [$MC_RESOLVE]
--insecure disable SSL certificate verification [$MC_INSECURE]
--limit-upload value limits uploads to a maximum rate in KiB/s, MiB/s, GiB/s. (default: unlimited) [$MC_LIMIT_UPLOAD]
--limit-download value limits downloads to a maximum rate in KiB/s, MiB/s, GiB/s. (default: unlimited) [$MC_LIMIT_DOWNLOAD]
--custom-header value, -H value add custom HTTP header to the request. 'key:value' format.
--help, -h show help
--version, -v print the version
TIP:
Use 'mcli --autocompletion' to enable shell autocompletion
COPYRIGHT:
Copyright (c) 2015-2025 MinIO, Inc.
LICENSE:
GNU AGPLv3
Conclusion
You’ve successfully installed MinIO on Ubuntu 24.04, configured it as a systemd service, and secured it with Nginx and Let’s Encrypt SSL. MinIO is now ready to store your data as an Amazon S3-compatible object storage solution.
Explore further by creating buckets, uploading files, or integrating MinIO with your applications. For more details, check the official MinIO documentation.