Quand on étudie Kubernetes, on arrive tôt ou tard sur la question de la gestion des sauvegardes. Et avec elles le sujet du stockage de ces dernières. La référence en matière de sauvegarde - dont je parlerais sûrement dans un prochain article - est Velero. Cet outil supporte plusieurs fournisseurs de stockage pour ses opérations de sauvegarde comme Amazon Web Services, Google Cloud, Microsoft Azure ou VMware Sphere. Principalement des fournisseurs liés à une entreprise. Que faire dans la situation où nous souhaitons auto-héberger une solution de stockage chez soi ?

C’est ce dont je voudrais parler aujourd’hui : une solution spécifique que j’ai - presque - choisie. Surtout pourquoi cette solution ? Je décrirais son installation sous Docker Compose derrière un proxy nommé Traefik, dont je vous ai déjà parlé. Et j’ajouterais quelques mots sur les ports réseau à ouvrir, l’initialisation des premiers « buckets » (nous y reviendrons) et l’usage de noms de domaines.

Logo du projet RustFS, simple écriture du mot RustFS en bleu

Pourquoi cette solution ?

Si vous n’êtes pas fan de l’histoire de « pourquoi choisir cette solution », vous pouvez passer au chapitre suivant, je ne vous en voudrais pas 😉.

En étudiant la documentation de Velero on découvre parmi les fournisseurs de solutions de stockage le célèbre Amazon Web Services. Et avec lui le service Amazon S3. Ce service est une solution de stockage objet qui a développé un protocole ouvert du même nom : S3. Grâce à cela, de nombreux outils compatibles avec ce protocole ont vu le jour ; que ce soit des clients comme des serveurs. Top, c’est ce que je recherche !

Ayant beaucoup entendu parler de MinIO, je m’enquiers de l’installer fin novembre 2025. En Docker Compose, derrière Traefik comme je l’explique dans un précédent article sur le sujet. Mais quelques problèmes se posent successivement :

  • en août 2025 les dépôts de Bitnami, qui fournissaient jusqu’alors d’excellentes images, chartes Helm et outils en tous genres sont chamboulés par une décision drastique prise par Bitnami. L’impact est énorme sur la communauté,
  • faute de cette image pratique, je me tourne vers l’image officielle qui demande des ajustements pour avoir des « buckets » à l’initialisation,
  • finalement le 13 février 2026, l’entreprise qui gérait MinIO décide d’abandonner la maintenance de la version communautaire.

Coup dur. Je recherche des alternatives. Je tombe sur le message de loverustfs qui compare les solutions alternatives à RustFS, dont MinIO, Garage, Ceph, Seaweeedfs, etc..

Edit (24 fév. 2026) : Un fork de MinIO est apparu il y a quelques jours. Si le cœur vous en dit 🤷.

RustFS n’est probablement pas la solution la plus performante (Seaweedfs semble plus performant), mais il se défend bien. Et il semble proche de MinIO en terme d’interface et d’utilisation. Allons donc, ne le faisons pas attendre, installons-le !

RustFS sous Docker Compose

L’idée est d’installer/utiliser RustFS avec Docker Compose. Derrière Træfik. Avec des domaines.

Installation minimale

On commence par une installation de base. On a besoin de :

  • une image Docker. Ça tombe bien, il y a des images officielles de RustFS sur le Hub Docker,
  • ouvrir 2 ports :
    • 9000,
    • 9001,
  • un volume local pour stocker les données et pouvoir les réutiliser entre 2 redémarrages de conteneurs,
  • un identifiant et un mot de passe initial.

ATTENTION : le projet RustFS est encore jeune, il est en développement actif et les versions ne sont pas toutes utilisables telles quelles. Par exemple dans ma situation, la version 1.0.0-alpha.83 était inutilisable. Ceci dû à un bug sur l’architecture de ma machine comme le montre ce ticket Github.

Une première ébauche d’un fichier docker-compose.yaml pourrait s’écrire de la manière suivante :

services:
  rustfs:
    image: rustfs/rustfs:1.0.0-alpha.82
    restart: always
    ports:
      - 9000
      - 9001
    volumes:
      - ./storage_data:/data
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      - RUSTFS_VOLUMES=/data
      - RUSTFS_ADDRESS=0.0.0.0:9000
      - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
      - RUSTFS_CONSOLE_ENABLE=true
      - RUSTFS_ACCESS_KEY=olivier
      - RUSTFS_SECRET_KEY=mot2passe
      - RUSTFS_OBS_LOGGER_LEVEL=info
    healthcheck:
      test:
        [
          "CMD",
          "sh", "-c",
          "curl -f http://127.0.0.1:9000/health && curl -f http://127.0.0.1:9001/rustfs/console/health"
        ]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Veillez à changer les éléments suivants - au minimum :

  • ./storage_data dans la section volumes. Renseigner par un dossier dans lequel vous voulez stocker les données,
  • RUSTFS_ACCESS_KEY dans la section environment. Changez olivier par un identifiant que vous souhaitez utiliser,
  • RUSTFS_SECRET_KEY dans la section environment. Changez la valeur mot2passe par quelque chose de bien plus long et bien plus compliqué que cela (une clé secrète en somme).

De cette façon, le service va se lancer avec des ports choisis par Docker Compose. Vous pouvez les connaître en tapant les commandes suivantes :

docker compose port rustfs 9000
docker compose port rustfs 9001

On constate sur l’interface (port initial 9001), après s’être authentifié avec l’identifiant et la clé secrète, qu’il n’y aucun bucket.

Initialisation des buckets

Qu’est un bucket ?

C’est un espace qui regroupe plusieurs objets qu’on aurait déposé à cet endroit. Cela permet de se repérer plus facilement dans un espace de stockage objet.

Afin de créer un bucket, soit on utilise l’interface (méthode manuelle), soit on créé un conteneur d’initialisation qui fera le job à notre place (automatique).

J’opte pour le conteneur d’initialisation pour créer 3 buckets. Dans notre fichier docker-compose.yaml on ajoute les lignes suivantes :

  init_buckets:
    image: minio/mc:RELEASE.2025-08-13T08-35-41Z
    depends_on:
      - rustfs
    restart: on-failure
    entrypoint: >
      /bin/sh -c "
      sleep 5;
      /usr/bin/mc alias set s3server http://rustfs:9000 \"olivier\" \"mot2passe\";
      /usr/bin/mc mb s3server/default;
      /usr/bin/mc mb s3server/bucket1;
      /usr/bin/mc mb s3server/bucket2;
      exit 0;
      "      

Pensez à changer olivier et mot2passe par les mêmes identifiants/mot de passe que renseignés dans le service rustfs du docker-compose.yaml précédent.

L’astuce est donc d’utiliser le client mc de MinIO pour ajouter les buckets qu’on souhaiterait. Dans l’exemple présenté ci-avant, le conteneur d’initialisation permet de créer 3 buckets :

  • default,
  • bucket1,
  • bucket2.

Libre à vous d’adapter ce conteneur pour répondre à vos besoins en matière de création initiale de bucket.

Il ne reste alors plus que la mise à disposition sur Internet via l’usage de sous-domaines et de Træfik.

Configurer les labels pour Træfik

Træfik est un proxy souvent utilisé avec Docker Compose pour se charger des routes. L’idée de Træfik est d’utiliser le champ labels pour récupérer des instructions utiles à la création des routes en lien avec les domaines.

Pour RustFS sous Docker Compose, et avec Træfik en frontal, je suggère les labels suivants :

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api-rustfs.rule=Host(`api.mondomaine.tld`)"
      - "traefik.http.routers.api-rustfs.entrypoints=websecure"
      - "traefik.http.routers.api-rustfs.service=api-rustfs"
      - "traefik.http.services.api-rustfs.loadbalancer.server.port=9000"
      - "traefik.http.routers.rustfs.rule=Host(`mondomaine.tld`)"
      - "traefik.http.routers.rustfs.entrypoints=websecure"
      - "traefik.http.routers.rustfs.service=rustfs"
      - "traefik.http.services.rustfs.loadbalancer.server.port=9001"

Prenez soin de changer les éléments suivants :

  • websecure par le nom de votre routeur permettant d’avoir du HTTPS,
  • api.mondomaine.tld par le domaine de votre choix pour accéder à l’API de RustFS,
  • mondomaine.tld par le domaine utilisé pour accéder à l’interface Web de RustFS.

Évidemment tout un tas d’autres options sont possibles, il suffit de lire la documentation de Træfik pour cela.

Résultat final complet

Ce qui nous donne :

services:
  rustfs:
    image: rustfs/rustfs:1.0.0-alpha.82
    restart: always
    ports:
      - 9000
      - 9001
    volumes:
      - ./storage_data:/data
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      - RUSTFS_VOLUMES=/data
      - RUSTFS_ADDRESS=0.0.0.0:9000
      - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
      - RUSTFS_CONSOLE_ENABLE=true
      - RUSTFS_ACCESS_KEY=olivier
      - RUSTFS_SECRET_KEY=mot2passe
      - RUSTFS_OBS_LOGGER_LEVEL=info
    healthcheck:
      test:
        [
          "CMD",
          "sh", "-c",
          "curl -f http://127.0.0.1:9000/health && curl -f http://127.0.0.1:9001/rustfs/console/health"
        ]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api-rustfs.rule=Host(`api.mondomaine.tld`)"
      - "traefik.http.routers.api-rustfs.entrypoints=websecure"
      - "traefik.http.routers.api-rustfs.service=api-rustfs"
      - "traefik.http.services.api-rustfs.loadbalancer.server.port=9000"
      - "traefik.http.routers.rustfs.rule=Host(`mondomaine.tld`)"
      - "traefik.http.routers.rustfs.entrypoints=websecure"
      - "traefik.http.routers.rustfs.service=rustfs"
      - "traefik.http.services.rustfs.loadbalancer.server.port=9001"

  init_buckets:
    image: minio/mc:RELEASE.2025-08-13T08-35-41Z
    depends_on:
      - rustfs
    restart: on-failure
    entrypoint: >
      /bin/sh -c "
      sleep 5;
      /usr/bin/mc alias set s3server http://rustfs:9000 \"olivier\" \"mot2passe\";
      /usr/bin/mc mb s3server/default;
      /usr/bin/mc mb s3server/bucket1;
      /usr/bin/mc mb s3server/bucket2;
      exit 0;
      "      

Avec ce contenu vous devriez pouvoir démarrer une instance RustFS sans problème 😉.

Quelle aventure !

Au bout du compte, avoir cherché à lancer un service de stockage objet a été une sacrée odyssée pour moi. Beaucoup d’aléas liés au changement de politique de Bitnami (pour les images MinIO), à l’arrêt de maintenance du code du serveur MinIO par AIStor et aux effets de bord de RustFS en plein développement.

Mes besoins spécifiques en terme d’infrastructure (Docker Compose et Træfik) m’ont amené à devoir retravailler plusieurs fois le fichier docker-compose.yaml. Et j’ai essuyé quelques plâtres avant d’avoir une instance fonctionnelle.

Je suis ainsi content de partager ce fichier docker-compose.yaml. Bien qu’il y a matière à faire évoluer ce fichier. On peut imaginer améliorer ce fichier en utilisant des variables pour le dossier où seront stockées les données, le nom du service, le domaine et bien évidemment l’identifiant et le mot de passe du service RustFS. Et déposer les valeurs dans un fichier .env.

On pourrait également trouver un autre client que mc pour initialiser les buckets au départ. Voire trouver un autre outil permettant de créer les buckets plus facilement. Imaginons une nouvelle image Docker ayant un script d’initialisation avec des variables d’environnement le permettant.

Je laisse votre imagination faire le reste 😊.

Sources utilisées pour la mise en place de RustFS

Liens utiles