MinIO es un servidor de almacenamiento de objetos compatible con la API de Amazon S3: cualquier aplicación, SDK o herramienta de copias de seguridad que hable S3 puede usarlo sin cambios. En este tutorial instalarás MinIO en un único servidor Ubuntu 24.04 como servicio systemd, lo publicarás con HTTPS detrás de Nginx y usarás el cliente mc para crear un bucket, un usuario con permisos limitados y una regla de caducidad de objetos.
Notadesde 2025 la edición comunitaria de MinIO (licencia AGPLv3) está en modo mantenimiento y su consola web solo incluye el explorador de objetos. La administración de usuarios y políticas se hace con
mc, como en esta guía. Revisa el estado del proyecto en su repositorio antes de usarlo en producción.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS de 64 bits (x86_64), por ejemplo un VPS de CubePath, con al menos 2 GB de RAM.
- Un usuario no root con privilegios
sudoy UFW activo permitiendo SSH. - Un disco o volumen para los datos. En esta guía se usa
/srv/minio/data; si tienes un volumen adicional, móntalo en esa ruta antes de empezar. - Dos nombres DNS con registro A apuntando a la IP del servidor:
minio.your_domainpara la API S3 yconsole.your_domainpara la consola web. Sustituye your_domain por tu dominio en todos los comandos.
Esta guía despliega un nodo con una sola unidad. Es adecuado para desarrollo, copias de seguridad y cargas pequeñas, pero no ofrece redundancia de disco ni versionado de objetos, que en MinIO requieren un despliegue con varias unidades (erasure coding).
Paso 1: Descargar el binario de MinIO
MinIO se distribuye como un único binario estático. Descárgalo en /usr/local/bin:
cd /tmp
curl -fLO https://dl.min.io/server/minio/release/linux-amd64/minio
sudo install -m 0755 minio /usr/local/bin/minio
Comprueba que se ejecuta:
minio --version
minio version RELEASE.2025-... (commit-id=...)
Runtime: go1.24 linux/amd64
Paso 2: Crear el usuario del servicio y el directorio de datos
MinIO no debe ejecutarse como root. Crea un usuario de sistema sin shell ni directorio personal y dale la propiedad del directorio de datos:
sudo groupadd --system minio-user
sudo useradd --system --no-create-home --shell /usr/sbin/nologin -g minio-user minio-user
sudo mkdir -p /srv/minio/data
sudo chown -R minio-user:minio-user /srv/minio
Paso 3: Configurar las variables de entorno
El servicio lee su configuración de /etc/default/minio. Crea el archivo:
sudo nano /etc/default/minio
Añade este contenido, sustituyendo el usuario y la contraseña de administrador por valores propios. La contraseña debe tener al menos 8 caracteres; usa una larga y aleatoria (por ejemplo, generada con openssl rand -base64 24):
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=your_strong_password
MINIO_VOLUMES="/srv/minio/data"
MINIO_OPTS="--address :9000 --console-address :9001"
MINIO_SERVER_URL="https://minio.your_domain"
MINIO_BROWSER_REDIRECT_URL="https://console.your_domain"
MINIO_OPTSfija el puerto de la API S3 (9000) y el de la consola (9001). No los abrirás en el firewall: Nginx será el único punto de entrada.MINIO_SERVER_URLyMINIO_BROWSER_REDIRECT_URLindican a MinIO las URL públicas que usarán los clientes.
Protege el archivo, ya que contiene la contraseña de administrador:
sudo chown root:minio-user /etc/default/minio
sudo chmod 640 /etc/default/minio
Paso 4: Crear el servicio systemd
Crea la unidad de systemd:
sudo nano /etc/systemd/system/minio.service
[Unit]
Description=MinIO object storage
Documentation=https://github.com/minio/minio
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
Type=notify
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
TasksMax=infinity
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
Las variables se escriben sin llaves ($MINIO_OPTS) para que systemd las separe en argumentos. Recarga systemd y arranca el servicio:
sudo systemctl daemon-reload
sudo systemctl enable --now minio
Comprueba el estado:
sudo systemctl status minio --no-pager
● minio.service - MinIO object storage
Loaded: loaded (/etc/systemd/system/minio.service; enabled; preset: enabled)
Active: active (running) since ...
Verifica que la API responde en local con el endpoint de salud:
curl -I http://127.0.0.1:9000/minio/health/live
HTTP/1.1 200 OK
Si el servicio no arranca, revisa el registro con sudo journalctl -u minio -n 50.
Paso 5: Publicar MinIO con Nginx y Let's Encrypt
Instala Nginx y Certbot:
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx
Crea un sitio con dos bloques server, uno para la API y otro para la consola:
sudo nano /etc/nginx/sites-available/minio
server {
listen 80;
server_name minio.your_domain;
# Sin límite de tamaño ni buffering: los objetos pueden ser grandes
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
ignore_invalid_headers 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_connect_timeout 300;
proxy_pass http://127.0.0.1:9000;
}
}
server {
listen 80;
server_name console.your_domain;
client_max_body_size 0;
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;
# La consola usa WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:9001;
}
}
Activa el sitio, comprueba la sintaxis y recarga Nginx:
sudo ln -s /etc/nginx/sites-available/minio /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Abre HTTP y HTTPS en el firewall y solicita los certificados. Certbot modifica el sitio para servir HTTPS y redirigir HTTP:
sudo ufw allow 'Nginx Full'
sudo certbot --nginx -d minio.your_domain -d console.your_domain
Comprueba la API desde tu equipo o desde el propio servidor:
curl -I https://minio.your_domain/minio/health/live
HTTP/2 200
Abre https://console.your_domain en el navegador e inicia sesión con MINIO_ROOT_USER y MINIO_ROOT_PASSWORD.
Paso 6: Instalar y configurar el cliente mc
mc es el cliente de línea de comandos de MinIO. Instálalo con el nombre mcli para no chocar con Midnight Commander, que en Ubuntu también usa el comando mc:
cd /tmp
curl -fLO https://dl.min.io/client/mc/release/linux-amd64/mc
sudo install -m 0755 mc /usr/local/bin/mcli
Registra un alias con las credenciales de administrador:
mcli alias set myminio https://minio.your_domain minioadmin your_strong_password
Added `myminio` successfully.
Comprueba la conexión y el estado del servidor:
mcli admin info myminio
● minio.your_domain
Uptime: 10 minutes
Version: ...
Network: 1/1 OK
Drives: 1/1 OK
Paso 7: Crear un bucket y subir objetos
Crea un bucket llamado backups y sube un archivo de prueba:
mcli mb myminio/backups
echo "hola minio" > /tmp/prueba.txt
mcli cp /tmp/prueba.txt myminio/backups/
mcli ls myminio/backups
Bucket created successfully `myminio/backups`.
...
[2026-09-25 10:12:03 UTC] 11B STANDARD prueba.txt
Para sincronizar un directorio completo usa mcli mirror, que solo copia los archivos nuevos o modificados:
mcli mirror /var/www myminio/backups/www
Paso 8: Crear un usuario con acceso limitado
Las aplicaciones no deben usar las credenciales de administrador. Crea una política que solo permita trabajar dentro del bucket backups:
nano ~/backups-rw.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::backups"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": ["arn:aws:s3:::backups/*"]
}
]
}
Registra la política, crea el usuario appbackup y asóciale la política. Sustituye app_secret_key por una clave secreta larga y aleatoria:
mcli admin policy create myminio backups-rw ~/backups-rw.json
mcli admin user add myminio appbackup app_secret_key
mcli admin policy attach myminio backups-rw --user appbackup
Verifica los permisos con un alias que use el nuevo usuario. Debe poder listar backups y recibir un error de acceso al intentar crear otro bucket:
mcli alias set appminio https://minio.your_domain appbackup app_secret_key
mcli ls appminio/backups
mcli mb appminio/otro-bucket
[2026-09-25 10:12:03 UTC] 11B STANDARD prueba.txt
mcli: <ERROR> Unable to make bucket `appminio/otro-bucket`. Access Denied.
Con estas credenciales (endpoint https://minio.your_domain, clave de acceso appbackup y su clave secreta) ya puedes configurar cualquier cliente S3, como rclone, restic o el SDK de AWS.
Paso 9: Borrar objetos antiguos automáticamente
Las reglas de ciclo de vida (ILM) eliminan objetos pasado un tiempo. Esta regla borra los objetos del prefijo tmp/ a los 7 días:
mcli ilm rule add --prefix "tmp/" --expire-days 7 myminio/backups
mcli ilm rule ls myminio/backups
La salida muestra la regla con el prefijo tmp/, estado Enabled y 7 días hasta la caducidad.
Solución de problemas
systemctl statusmuestrafailedy el registro dice que la contraseña es demasiado corta:MINIO_ROOT_PASSWORDnecesita al menos 8 caracteres. Corrígela en/etc/default/minioy ejecutasudo systemctl restart minio.- Error
file access deniedal arrancar: el directorio de datos no pertenece aminio-user. Repitesudo chown -R minio-user:minio-user /srv/minio. - Las subidas grandes fallan con
413 Request Entity Too Large: faltaclient_max_body_size 0;en el bloqueserverde la API en Nginx. - Errores de firma (
SignatureDoesNotMatch) a través del proxy: Nginx debe enviar la cabeceraHost $http_hostsin modificar, como en la configuración del paso 5.
Conclusión
Tienes MinIO funcionando como servicio systemd, accesible por HTTPS a través de Nginx, con un bucket, un usuario de aplicación limitado a ese bucket y una regla de caducidad. Como siguientes pasos puedes configurar restic o rclone para enviar copias de seguridad a este bucket, montar un despliegue con varias unidades para disponer de redundancia y versionado, o replicar el bucket a otro servidor con mcli mirror --watch.
