Deploy Single Node MinIO Server with Nginx Reverse Proxy (Ubuntu 24.04 LTS)
3 min read511 words15 code blocks
At a glance#
- Purpose: Deploy a single-node MinIO server behind an nginx reverse proxy with TLS termination.
- Applies to: MinIO on Ubuntu 24.04 LTS.
- Risk: Medium - new service deployment.
- Time: About 1 hour.
1. OS Installation#
- Install Ubuntu Server 24.04 LTS minimal
- Single
/partition (65 GB+) or whatever the storage is - Set hostname:
sudo hostnamectl set-hostname minio2. System Update & Tools#
sudo apt update && sudo apt upgrade -y
sudo apt install ufw curl wget openssl nginx -y3. Firewall Setup#
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable4. MinIO User & Data Directory#
sudo useradd -r -m -U -d /srv/minio -s /usr/sbin/nologin minio-user
sudo mkdir -p /srv/minio-data
sudo chown minio-user:minio-user /srv/minio-data5. Install MinIO Server Binary#
wget https://dl.min.io/server/minio/release/linux-amd64/minio
sudo mv minio /usr/local/bin/
sudo chmod +x /usr/local/bin/minio6. Environment File#
Generate strong creds:
ACCESS_KEY="$(openssl rand -hex 6)" # >=3 chars
SECRET_KEY="$(openssl rand -base64 24 | tr -d '/+=\n')" # >=8 charsCreate /etc/default/minio:
sudo tee /etc/default/minio >/dev/null <<EOF
MINIO_ROOT_USER=${ACCESS_KEY}
MINIO_ROOT_PASSWORD=${SECRET_KEY}
MINIO_VOLUMES="/srv/minio-data"
MINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"
MINIO_SERVER_URL=https://s3.example.com
MINIO_BROWSER_REDIRECT_URL=https://s3.example.com/minio/ui/
EOF
sudo chmod 600 /etc/default/minio
sudo chown root:root /etc/default/minio7. Systemd Service#
/etc/systemd/system/minio.service:
[Unit]
Description=MinIO
Documentation=https://min.io/docs/minio/linux/index.html
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 $MINIO_VOLUMES $MINIO_OPTS
Restart=always
LimitNOFILE=65536
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now minio8. Nginx Reverse Proxy with TLS#
- Place cert & key in
/etc/nginx/ssl/:
sudo mkdir -p /etc/nginx/ssl
sudo cp s3_leaf.crt /etc/nginx/ssl/
sudo cp ca_bundle.crt /etc/nginx/ssl/
sudo cp s3.key /etc/nginx/ssl/
sudo bash -c 'cat /etc/nginx/ssl/s3_leaf.crt /etc/nginx/ssl/ca_bundle.crt > /etc/nginx/ssl/s3.fullchain.crt'
sudo chmod 600 /etc/nginx/ssl/s3.key- Create
/etc/nginx/sites-available/minio.conf:
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;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
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_pass http://127.0.0.1:9000;
}
location /minio/ui/ {
rewrite ^/minio/ui/(.*) /$1 break;
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_pass http://127.0.0.1:9001;
}
}Enable & reload:
sudo ln -s /etc/nginx/sites-available/minio.conf /etc/nginx/sites-enabled/minio.conf
sudo nginx -t && sudo systemctl reload nginx9. MinIO Client (mc)#
wget https://dl.min.io/client/mc/release/linux-amd64/mc
sudo mv mc /usr/local/bin/
sudo chmod +x /usr/local/bin/mc
mc alias set prod https://s3.example.com $ACCESS_KEY $SECRET_KEY
mc admin info prod10. Create Bucket & App User#
mc mb prod/mybucket
cat > /tmp/mybucket-rw.json <<'JSON'
{
"Version":"2012-10-17",
"Statement":[
{"Effect":"Allow","Action":["s3:ListBucket"],"Resource":["arn:aws:s3:::mybucket"]},
{"Effect":"Allow","Action":["s3:GetObject","s3:PutObject","s3:DeleteObject"],"Resource":["arn:aws:s3:::mybucket/*"]}
]
}
JSON
mc admin policy create prod mybucket-rw /tmp/mybucket-rw.json
APP_USER="app_user"
APP_PASS="$(openssl rand -base64 30 | tr -d '/+=\n')"
mc admin user add prod "$APP_USER" "$APP_PASS"
mc admin policy attach prod mybucket-rw --user "$APP_USER"11. Health Checks#
curl -Ik https://s3.example.com/minio/health/ready
curl -s http://127.0.0.1:9000/minio/health/ready && echo