KB
Object Storage & S3

MinIO Setup on Ubuntu 24.04 (Headless Deployment)

5 min read1073 words37 code blocks

At a glance#

  • Purpose: Install and secure MinIO object storage on a headless Ubuntu server with LVM storage and optional TLS.
  • Applies to: MinIO on Ubuntu Server 24.04.
  • Risk: Medium - new service deployment; storage layout decisions are hard to change later.
  • Time: 1-2 hours.

Overview#

This guide explains how to install, configure, and secure MinIO on Ubuntu Server 24.04.

It uses SystemD, LVM storage, CLI management, and optionally Nginx for HTTPS termination.

It also includes AWS CLI integration for full S3 API compatibility.


System Details#

ItemValue
OSUbuntu Server 24.04
Storage/dev/sdb/mnt/minio-data (LVM)
NetworkLAN only
API Port9000
Console Port9001
HTTPS Reverse ProxyNginx (s3.example.com)
Management Toolsmc (MinIO Client), awscli (S3-compatible)

Installation Steps#

1. Update System#

bash
sudo apt update && sudo apt upgrade -y

2. Create MinIO User#

bash
sudo useradd -r -s /sbin/nologin minio-user

3. Install MinIO Server#

bash
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/

4. Prepare MinIO Data Directory (with LVM setup)#

We’ll create an LVM volume on /dev/sdb, format it, and mount it to /mnt/minio-data.

⚠️ Warning: These steps will erase all data on /dev/sdb. Double-check your disk with lsblk or sudo fdisk -l before proceeding.

1 Create a Partition for LVM#

bash
sudo fdisk /dev/sdb

Inside fdisk, run:

text
g            # create a new GPT partition table
n            # create new partition
<enter>      # default partition number (1)
<enter>      # default first sector
<enter>      # default last sector (use full disk)
t            # change partition type
8e           # set type to "Linux LVM"
w            # write changes and exit

Check the new partition:

bash
lsblk

You should now see /dev/sdb1.


2 Create the LVM Structure#

bash
# Create a physical volume
sudo pvcreate /dev/sdb1

# Create a volume group (VG)
sudo vgcreate vg_minio /dev/sdb1

# Create a logical volume (LV)
sudo lvcreate -n lv_minio -l 100%FREE vg_minio

Verify:

bash
sudo lvdisplay

3 Format the Logical Volume#

bash
sudo mkfs.ext4 /dev/vg_minio/lv_minio

4 Create Mount Point and Mount Volume#

bash
sudo mkdir -p /mnt/minio-data
sudo mount /dev/vg_minio/lv_minio /mnt/minio-data

5 Enable Persistent Mounting#

Add the mount entry to /etc/fstab:

bash
sudo blkid /dev/vg_minio/lv_minio

Copy the UUID from output, then:

bash
sudo nano /etc/fstab

Add this line (replace the UUID with yours):

text
UUID=<your-uuid> /mnt/minio-data ext4 defaults 0 2

Apply:

bash
sudo mount -a

6 Set Permissions for MinIO#

bash
sudo chown -R minio-user:minio-user /mnt/minio-data

Result:

Your LVM volume is now mounted at /mnt/minio-data and ready for MinIO to use.


5. Create SystemD Service#

bash
sudo nano /etc/systemd/system/minio.service

Paste:

text
[Unit]
Description=MinIO Object Storage
Documentation=https://min.io/docs/
Wants=network-online.target
After=network-online.target

[Service]
User=minio-user
Group=minio-user
EnvironmentFile=-/etc/default/minio
ExecStart=/usr/local/bin/minio server /mnt/minio-data --console-address ":9001"
Restart=always
LimitNOFILE=65536
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

6. Configure Credentials#

bash
sudo nano /etc/default/minio

Paste:

text
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=Password123 (Put strong password here)

Secure permissions:

bash
sudo chown root:minio-user /etc/default/minio
sudo chmod 640 /etc/default/minio

7. Start and Enable Service#

bash
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
systemctl status minio

View logs:

bash
sudo journalctl -u minio -f

8. (Optional) Firewall Rules#

bash
sudo ufw allow 9000/tcp
sudo ufw allow 9001/tcp

Optional: HTTPS via Nginx Reverse Proxy#

Configure secure HTTPS access for MinIO API and Console.

1. Install and Configure Nginx#

bash
sudo apt install nginx nginx-extras -y
sudo mkdir -p /etc/nginx/ssl
sudo cp s3.fullchain.crt /etc/nginx/ssl/
sudo cp s3.key /etc/nginx/ssl/

2. Add Nginx Config#

Create:

bash
sudo nano /etc/nginx/sites-available/minio.conf

Paste:

text
server {
    listen 80;
    listen [::]:80;
    server_name s3.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name s3.example.com;

    ssl_certificate     /etc/nginx/ssl/s3.fullchain.crt;
    ssl_certificate_key /etc/nginx/ssl/s3.key;
    ssl_trusted_certificate /etc/nginx/ssl/s3.fullchain.crt;

    server_tokens off;
    more_clear_headers Server;

    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

    ignore_invalid_headers off;
    client_max_body_size 0;
    proxy_buffering off;
    proxy_request_buffering off;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $http_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;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;
        proxy_hide_header Server;
        proxy_hide_header x-minio-version;
        more_clear_headers Server;
        more_clear_headers x-minio-version;
    }

    location /minio/ui/ {
        rewrite ^/minio/ui/(.*) /$1 break;
        proxy_pass http://127.0.0.1:9001;
        proxy_set_header Host $http_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;
        proxy_set_header X-NginX-Proxy true;
        real_ip_header X-Real-IP;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        chunked_transfer_encoding off;
        proxy_hide_header Server;
        proxy_hide_header x-minio-version;
        more_clear_headers Server;
        more_clear_headers x-minio-version;
    }
}

Enable and restart:

bash
sudo ln -s /etc/nginx/sites-available/minio.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx

Now access:

  • API: https://s3.example.com
  • Console: https://s3.example.com/minio/ui/

Managing MinIO with mc (MinIO Client)#

Install and Configure#

bash
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/
mc alias set minio https://s3.example.com minioadmin Password123 --api s3v4

Common Commands#

ActionCommand
List Bucketsmc ls minio
Create Bucketmc mb minio/mybucket
Upload Filemc cp file.txt minio/mybucket/
Download Filemc cp minio/mybucket/file.txt ./
Public Accessmc anonymous set download minio/mybucket

Using AWS CLI with MinIO (S3 API)#

1. Install AWS CLI#

Ubuntu/Debian:

bash
sudo apt update
sudo apt install unzip -y
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

Windows (PowerShell):

powershell
# Download and install:
# https://awscli.amazonaws.com/AWSCLIV2.msi
aws --version

2. Configure AWS CLI for MinIO#

bash
aws configure --profile minio-admin

Fill in:

text
AWS Access Key ID: YOUR_MINIO_ACCESS_KEY
AWS Secret Access Key: YOUR_MINIO_SECRET_KEY
Default region name: us-east-1
Default output format: json

Then edit:

bash
nano ~/.aws/config

Add:

text
[profile minio-admin]
region = us-east-1
output = json
s3 =
    endpoint_url = https://s3.example.com
    addressing_style = path

Set as default for this session:

bash
export AWS_PROFILE=minio-admin

3. Common AWS CLI (S3-Compatible) Commands#

ActionCommand
Create Bucketaws s3 mb s3://mybucket
List Bucketsaws s3 ls
Upload Fileaws s3 cp /path/to/file.txt s3://mybucket/
Upload Folderaws s3 cp /path/to/folder s3://mybucket/ --recursive
List Objectsaws s3 ls s3://mybucket --recursive --human-readable --summarize
Download Fileaws s3 cp s3://mybucket/file.txt /local/path/
Delete Fileaws s3 rm s3://mybucket/file.txt
Delete All Files in Bucketaws s3 rm s3://mybucket --recursive
Delete Bucketaws s3api delete-bucket --bucket mybucket

Maintenance & Updates#

Check versions:

bash
minio --version
mc --version
aws --version

To update MinIO:

bash
sudo systemctl stop minio
sudo wget -O /usr/local/bin/minio https://dl.min.io/server/minio/release/linux-amd64/minio
sudo chmod +x /usr/local/bin/minio
sudo systemctl start minio