Tutorial

Migrar MinIO a Garage o RustFS sin perder un objeto actual

Autoalojamiento13 min de lectura20 pasos

El repositorio de MinIO está archivado desde el 25 de abril de 2026: su almacenamiento S3 funciona ahora sin parches de seguridad en origen. Garage y RustFS son los dos destinos autoalojables que más se mencionan, pero copiar los objetos es solo la mitad del trabajo. Las políticas IAM, el historial de versiones y las URL prefirmadas no se trasladan. Esta guía inventaría el origen, copia con rclone, demuestra el resultado con recuentos y comprobaciones, y cambia la aplicación en tres tiempos, con un corte de escritura mínimo y la vuelta atrás preparada.

Contenido· Por qué no dejar MinIO donde está1/14
  1. 01Por qué no dejar MinIO donde está
  2. 02Lo que una copia de bucket no traslada por sí sola
  3. 03Requisitos y plan de capacidad
  4. 04Paso 1: inventariar el origen antes de copiar
  5. 05Garage y RustFS: las diferencias que conviene conocer antes de elegir
  6. 06Versionado: lo que pierde la copia y qué hacer
  7. 07Paso 2: preparar el destino, Garage o RustFS
  8. 08Paso 3: copiar con rclone y demostrar el resultado
  9. 09ETag multipart y mc mirror: leer las diferencias sin equivocarse
  10. 10URL prefirmadas: por qué fallan en el cambio
  11. 11Paso 4: cambiar en tres tiempos, sin corte brusco
  12. 12La vuelta atrás se reduce a una variable
  13. 13Solución de problemas: los síntomas que se repiten
  14. 14La documentación oficial

Por qué no dejar MinIO donde está

El repositorio minio/minio fue archivado por su propietario el 25 de abril de 2026: es de solo lectura, su README indica que el proyecto ya no se mantiene y que los binarios ya publicados no recibirán actualizaciones. En la práctica, nadie corregirá en origen el próximo fallo que se descubra en su servidor S3. El cliente mc, también bajo AGPLv3, fue archivado el 14 de julio de 2026.

Su MinIO sigue funcionando, y eso es lo que hace traicionero el asunto: el día del archivado no se rompe nada. Pero un almacenamiento de objetos está expuesto, contiene sus archivos multimedia, copias de seguridad o exportaciones, y ahora funciona sin parches de seguridad. Dos destinos autoalojables aparecen una y otra vez en las discusiones: Garage, publicado bajo AGPLv3, y RustFS, publicado bajo licencia Apache 2.0.

Este artículo no repite la instalación de ninguno de los dos, que tienen su propia guía: Garage en un VPS y RustFS en un VPS. Aquí partimos de un MinIO en producción y respondemos a una sola pregunta: cómo mover los datos, demostrar que no falta nada y cambiar la aplicación sin URL rotas.

Lo que una copia de bucket no traslada por sí sola

  • Los objetos actuales — es la parte fácil: rclone o mc mirror los copian, con una comprobación posterior.
  • Las versiones anteriores — la documentación de mc mirror precisa que solo sincroniza el objeto actual, sin información de versión.
  • Los usuarios y las políticas IAM — viven en MinIO, no en los buckets. Los secretos no se exportan: se generan claves nuevas en el destino.
  • Las URL prefirmadas ya distribuidas — la firma depende del host, de la región y de las claves. Cambiar el endpoint las invalida.
  • Las diferencias de compatibilidad S3 — ACL, políticas de bucket, acceso anónimo, versionado: cada destino tiene sus huecos, que se leen en su documentación en lugar de suponerlos.
  • La configuración de los clientes — endpoint, región, direccionamiento path-style: todo lo que su aplicación, sus copias restic o su CDN llevan fijado.

Requisitos y plan de capacidad

Necesita acceso de administrador a MinIO, un equipo o un VPS con mc y rclone, y un destino ya instalado y accesible por HTTPS (consulte las dos guías anteriores para el proxy inverso y el certificado). La regla de capacidad es simple: mientras no haya validado la migración, conserva el origen intacto, así que paga el disco dos veces.

Nuestra recomendación editorial: prever en el destino el tamaño total de los datos del origen, más un margen de alrededor del 30 % para los metadatos y las diferencias de reparto. En el mismo VPS, eso significa disponer como mínimo del doble del volumen actual más el margen; en dos VPS, cada uno asume su parte. Un único nodo Garage con replication_factor = 1 guarda una sola copia de cada objeto: no es una copia de seguridad, y el origen aún en pie es su única red de seguridad durante la migración.

Paso 1: inventariar el origen antes de copiar

  1. Declarar MinIO como alias

    Cree un alias src con credenciales que lean todos los buckets:
    mc alias set src https://s3.your-domain.com ACCESS_KEY SECRET_KEY

  2. Contar los objetos y el tamaño

    Para cada bucket, anote el número de objetos y el volumen:
    mc du --recursive src/medias
    mc ls --recursive src/medias | wc -l
    Lleve estas cifras a una tabla «antes / después»: es su prueba de que la migración está completa.

  3. Contar las versiones

    Si el versionado está activo, la lista de versiones es más larga que la de objetos:
    mc ls --recursive --versions src/medias | wc -l
    La documentación de mc ls precisa que --versions exige un servicio que admita el versionado. Una gran diferencia entre ambos recuentos indica cuánto historial está en juego.

  4. Exportar la lista de políticas y de usuarios

    Conserve un registro de lo que tendrá que recrear:
    mc admin policy list src
    mc admin user list src
    Los secretos no aparecen en esta salida y no pueden aparecer: los regenerará.

  5. Anotar la configuración de los clientes

    En cada aplicación que habla con MinIO, anote el endpoint, la región, el estilo de direccionamiento y el nombre de la variable de entorno que los contiene. El cambio final solo modificará estos valores.

Garage y RustFS: las diferencias que conviene conocer antes de elegir

Desplace la tabla

TemaGarageRustFS
LicenciaAGPLv3 (README del repositorio)Apache 2.0 (README del repositorio)
VersionadoNo admitido: `PutBucketVersioning` y `ListObjectVersions` figuran como ausentesIndicado como disponible en el README
Políticas de bucket y ACLNinguna de las dos: un sistema propio, por clave y por bucketIAM y políticas de bucket; las ACL no se admiten de forma deliberada
Acceso anónimoRechazado, con una respuesta 403Evaluado según la política del bucket
Región del cliente`s3_region` de `garage.toml`, que hay que copiar en el cliente`RUSTFS_REGION`, `us-east-1` por defecto, que hay que copiar en el cliente
DireccionamientoPath-style y vhost-style admitidosPath-style por defecto, sin configuración DNS
URL prefirmadasAdmitidasAdmitidas; host, esquema, puerto, región y ruta deben coincidir con la firma
API de administración de MinIONo aplica: se administra con el comando `garage`Superficie separada: el S3 funciona sin que `mc admin` esté garantizado

Versionado: lo que pierde la copia y qué hacer

Este punto decide la elección del destino. Garage no admite el versionado: su página de compatibilidad S3 lo dice sin rodeos. Si sus buckets conservan un historial que la aplicación consulta o que debe guardar por razones de negocio, Garage no es el destino. RustFS indica el versionado como disponible, pero la copia con rclone sync o mc mirror no recreará allí su historial.

Tres vías, a elegir bucket por bucket. Asumir la pérdida: solo pasa la versión actual, lo cual basta cuando el versionado era solo una red de seguridad contra el error humano. Copiar versión por versión: se listan los identificadores con mc ls --versions y se reproducen las versiones de la más antigua a la más reciente hacia un destino que admita el versionado, tras activarlo en el bucket; las fechas de las versiones serán las de la copia, no las originales. O archivar el historial aparte, en un bucket de archivo, y migrar solo lo actual. En todos los casos, pruebe con un objeto de varias versiones antes de lanzar la copia general.

Paso 2: preparar el destino, Garage o RustFS

  1. Garage: asignar y luego aplicar el layout

    Ningún bucket es utilizable hasta que se aplica el layout. Obtenga el identificador del nodo y asígnele una zona y una capacidad:
    garage status
    garage layout assign -z dc1 -c 1G <node_id>
    garage layout apply --version 1
    Ajuste -c al espacio en disco realmente asignado.

  2. Garage: crear la clave, el bucket y los permisos

    Los permisos se conceden por clave y por bucket:
    garage key create app-key
    garage bucket create medias
    garage bucket allow --read --write --owner medias --key app-key
    El secreto se muestra al crear la clave: cópielo enseguida en su gestor de secretos.

  3. Garage: copiar la región en el cliente

    La sección [s3_api] de garage.toml define s3_region. Ponga exactamente ese valor en la configuración de sus clientes y mantenga el direccionamiento path-style. Una región distinta provoca firmas rechazadas.

  4. RustFS: alias y bucket

    Con mc configurado sobre el destino:
    mc alias set dst http://127.0.0.1:9000 ACCESS_KEY SECRET_KEY
    mc mb dst/medias
    La documentación de RustFS recomienda usuarios IAM o cuentas de servicio en lugar de las claves raíz para las aplicaciones.

  5. RustFS: recrear usuarios y políticas

    Tome la lista exportada en el paso 1 y recree cada usuario y cada política en RustFS, con una clave nueva por aplicación. Después alinee la región: RUSTFS_REGION vale us-east-1 por defecto, y el cliente debe usar la misma.

Paso 3: copiar con rclone y demostrar el resultado

  1. Declarar los dos remotes

    Use el proveedor Minio para el origen y Other para el destino:
    rclone config create src s3 provider=Minio access_key_id=ACCESS_KEY secret_access_key=SECRET_KEY endpoint=https://s3.your-domain.com
    rclone config create dst s3 provider=Other access_key_id=ACCESS_KEY secret_access_key=SECRET_KEY endpoint=http://127.0.0.1:3900 region=garage
    region=garage supone s3_region = "garage", el valor del ejemplo de Garage: ponga el suyo si difiere. Para RustFS, sustituya el endpoint por el del destino y la región por el valor de RUSTFS_REGION.

  2. Hacer un ensayo en seco

    rclone sync modifica el destino para que refleje el origen, incluidas las eliminaciones. No lo invierta nunca, y ejecute primero el ensayo:
    rclone sync src:medias dst:medias --checksum --metadata --transfers 16 --dry-run

  3. Lanzar la copia en caliente

    MinIO sigue en servicio durante esta primera pasada:
    rclone sync src:medias dst:medias --checksum --metadata --transfers 16 --progress
    --metadata pide a rclone que conserve los metadatos: compruebe en un objeto de prueba que el tipo de contenido ha llegado intacto.

  4. Verificar la copia

    Compruebe que todo lo que está en el origen existe en el destino:
    rclone check src:medias dst:medias --one-way --combined /tmp/check-medias.txt
    El archivo lista cada ruta con un símbolo: = idéntico, + ausente del destino, * distinto, ! error. El objetivo es cero líneas +, * o !.

  5. Volver a contar tras la copia

    Repita mc du --recursive y el recuento de objetos en el destino, con el alias dst, y rellene la columna «después» de su tabla. Las dos cifras deben ser idénticas, salvo diferencias explicadas por las versiones.

ETag multipart y mc mirror: leer las diferencias sin equivocarse

El ETag de un objeto pequeño enviado en una sola petición es su MD5, y rclone lo usa como suma de control. En un objeto multipart, la documentación de rclone recuerda que el ETag deja de ser el MD5 de los datos: es el MD5 de la sucesión de los MD5 de cada parte, seguido del número de partes. Depende, por tanto, del tamaño de las partes, que eligió el cliente al subir.

Su MinIO recibió el objeto con un troceado, rclone lo envía al destino con otro: el contenido es idéntico byte a byte, el ETag no. Un rclone check que señale esos objetos como distintos no tiene por qué tener razón. Repítalo sobre ellos con --download, que descarga ambos lados y compara los propios datos: más lento, pero sin ambigüedad. La misma cautela vale para mc mirror: su documentación precisa que las sumas compuestas pueden diferir simplemente porque cambió el reparto en partes.

Si prefiere quedarse en el ecosistema mc, la copia se escribe mc mirror --preserve src/medias dst/medias. --preserve conserva los atributos del origen y sus reglas de política de bucket; esto último solo tiene sentido si el destino sabe leerlas, lo que excluye a Garage. Sin --overwrite, un objeto ya presente en el destino no se vuelve a copiar: el error se registra y la copia continúa. Con --remove, se eliminan los objetos del destino ausentes del origen. Y mc mirror solo sincroniza el objeto actual, sin versiones. Su comparación se basa en el nombre, el tamaño, la fecha y la suma de control, sin leer el contenido. El repositorio de mc también está archivado: la herramienta funciona, pero no evolucionará.

URL prefirmadas: por qué fallan en el cambio

Una URL prefirmada contiene una firma calculada con la clave secreta, el host, la región y la ruta. La documentación de RustFS lo dice: el host, el esquema, el puerto, la región y la ruta de la petición deben coincidir con los usados para firmar. Cambiar de endpoint o de clave invalida, por tanto, todos los enlaces ya emitidos, sin excepción, y nada los redirige.

La consecuencia es una cuestión de secuencia. Los enlaces que su aplicación genera al vuelo se regeneran solos en cuanto se reconecta al nuevo destino. Los que envió por correo o guardó en base de datos morirán en el cambio. Acorte, pues, la vida útil de los enlaces unos días antes, para que circulen pocos enlaces largos, y avise a los equipos que los reparten a mano.

Paso 4: cambiar en tres tiempos, sin corte brusco

  1. Sincronización inicial en caliente

    Es la copia del paso 3, ejecutada mientras MinIO sigue sirviendo tráfico. Dura lo que tenga que durar y no molesta a nadie. Anote la hora de finalización.

  2. Congelar las escrituras

    Ponga la aplicación en solo lectura o en un mantenimiento breve, o active una doble escritura si su código lo permite. Las lecturas pueden seguir en MinIO mientras se ejecuta la sincronización final.

  3. Sincronización final con --update

    Transfiera solo lo que ha cambiado desde entonces:
    rclone sync src:medias dst:medias --update --metadata --transfers 16 --progress
    rclone check src:medias dst:medias --one-way
    Vuelva a contar los objetos y el tamaño, y compare con la tabla del paso 1.

  4. Cambiar el endpoint mediante una variable de entorno

    Su aplicación debe leer el endpoint, la región y las claves de su entorno, nunca del código. Modifique esas variables, reinicie el servicio y pruebe una subida, una lectura y un borrado sobre un objeto de prueba. Regenere los enlaces prefirmados que importen.

  5. Vigilar y solo después desmontar

    Deje MinIO en su sitio, detenido o en solo lectura, el tiempo necesario para ver pasar un ciclo completo de sus copias de seguridad y de sus tareas programadas. Vuelva a apuntar sus copias restic al destino; vea la guía sobre las copias de seguridad con restic.

La vuelta atrás se reduce a una variable

Mientras MinIO no se haya eliminado y la última sincronización se haya hecho en solo lectura, volver atrás consiste en poner el endpoint antiguo en el entorno y reiniciar. Si ha habido escrituras en el destino desde el cambio, tráigalas antes al origen con un rclone copy en sentido contrario (nunca un sync, que eliminaría) y después vuelva. Borre MinIO solo tras un periodo de observación fijado de antemano.

Solución de problemas: los síntomas que se repiten

Una llamada sin firma a Garage responde 403 con el mensaje Garage does not support anonymous access yet. Es el comportamiento esperado de Garage, y la petición de acceso anónimo sigue en el seguimiento del proyecto como una función que nunca se priorizó. Si su aplicación servía archivos públicos sin firma, tendrá que usar URL prefirmadas o un proxy delante del bucket.

Si las escrituras se rechazan con errores de firma justo después del cambio, compare la región del cliente con la del destino (s3_region en Garage, RUSTFS_REGION en RustFS) y compruebe que el cliente usa direccionamiento path-style. Si rclone check señala objetos multipart como distintos aunque sus tamaños sean iguales, repítalo con --download. Si una nueva ejecución de mc mirror no copia un objeto modificado, la causa es la falta de --overwrite. Por último, si un bucket está vacío en el destino aunque la sincronización haya terminado bien, compruebe que la clave recibió --read --write sobre ese bucket en Garage, o la política adecuada en RustFS.

La documentación oficial

Relea estas fuentes antes de actuar, porque estos proyectos evolucionan: el repositorio github.com/minio/minio para el estado y la licencia de MinIO; github.com/rustfs/rustfs y docs.rustfs.com para RustFS; garagehq.deuxfleurs.fr para la compatibilidad S3 de Garage; rclone.org para sync y check; la documentación de MinIO sobre mc mirror. Para respaldar este almacenamiento, consulte el artículo 3-2-1 con restic y S3.

Un segundo VPS para probar el destino antes de apagar MinIO

Un segundo VPS con acceso root y disco NVMe aloja el destino durante la migración: prueba junto a producción y solo apaga MinIO cuando los recuentos de objetos estén validados. El cambio se hace sin tocar la máquina de origen.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva