Un déploiement remplace trois conteneurs et deux cents pièces jointes disparaissent. Le code les avait écrites dans un répertoire interne au runtime ; un bind mount présent sur le serveur précédent masquait ce défaut. L’équipe restaure une sauvegarde de base parfaitement cohérente, mais celle-ci contient seulement des chemins vers des objets qui n’existent plus. Le statut du dossier affirme alors l’inverse de la réalité documentaire.
Ce qui compte vraiment est le contrat du fichier, pas le type de disque. Un upload possède un propriétaire, une finalité, un état de validation, une visibilité, une durée de conservation et une procédure de restauration. Le volume ou le stockage objet n’est qu’un adaptateur. Tant que ces décisions restent implicites, conteneuriser l’application déplace la fragilité sans la résoudre.
Contrairement à ce que suggère un upload réussi, le travail commence après la réception. Il faut borner taille et format, neutraliser le nom fourni, stocker hors exposition directe, scanner ou convertir selon le risque, enregistrer les métadonnées puis publier seulement lorsque l’état est connu. Un fichier reçu n’est pas encore un document exploitable.
Dans un développement web sur mesure, cette chaîne doit rester observable du navigateur jusqu’à la restauration. Les sections suivantes distinguent temporaire et durable, comparent volume partagé et stockage objet, puis proposent un plan de migration sans perdre les liens métier ni prétendre qu’un simple antivirus garantit la sûreté.
Classer chaque fichier avant de choisir son stockage
Séparer temporaire, dérivé et original
Un fichier temporaire sert à une opération courte et peut être régénéré ou abandonné. Un dérivé — miniature, PDF optimisé, export — doit pouvoir être reconstruit depuis une source et une version de traitement. Un original utilisateur constitue parfois une preuve ou un élément irremplaçable. Ces classes n’ont ni la même sauvegarde ni la même rétention.
La fiche de stockage ajoute volume attendu, taille maximale, sensibilité, fréquence d’accès et lieu de vérité. Une archive fiscale, une photo de profil et un cache de rendu ne partagent pas un répertoire générique « uploads ». Les regrouper facilite le premier développement mais rend ensuite purge, droits et restauration dangereux.
Nommer le statut métier
Reçu, en analyse, accepté, refusé, publié, archivé et supprimé décrivent mieux le cycle qu’un booléen « uploaded ». L’interface et le support lisent ce statut. Une erreur de conversion n’annule pas nécessairement la réception ; elle peut ouvrir une reprise sans demander au client de renvoyer un original déjà conservé.
Sortir les données durables de la couche du conteneur
La couche modifiable d’un conteneur suit son instance. Elle ne doit pas porter un document durable. Les volumes Docker documentés officiellement persistent hors du cycle de vie d’un conteneur et peuvent être gérés par Docker. Cette persistance ne constitue toutefois ni une sauvegarde ni une réplication.
Les chemins d’écriture sont déclarés. Le runtime peut rester en lecture seule à l’exception d’un espace temporaire borné. Au démarrage, l’application vérifie accès et capacité sans créer silencieusement un répertoire de repli interne. Une erreur de montage doit empêcher l’acceptation de nouveaux documents plutôt que produire des données invisibles.
Éviter les permissions corrigées à la main
UID, GID et droits sont alignés dans l’image et le déploiement. Un init job peut préparer un volume, mais son action reste versionnée et idempotente. Un chmod récursif lancé en urgence masque le propriétaire réel, rallonge le démarrage et peut exposer des fichiers à un processus qui n’en a pas besoin.
Concevoir un pipeline d’upload explicite
Le serveur reçoit le flux avec une limite de taille au niveau du proxy et de l’application. Il crée un identifiant interne, calcule une empreinte utile, stocke l’original dans une zone non publiée puis écrit les métadonnées. Les validations lourdes se poursuivent éventuellement en asynchrone ; la réponse utilisateur annonce « reçu » et non « disponible ».
Une clé d’idempotence relie la tentative au dossier. Si le navigateur recommence après un timeout, l’application retrouve l’objet existant ou reprend un multipart incomplet au lieu de créer une deuxième pièce. Les limites du proxy, de PHP et du stockage sont cohérentes afin qu’un refus produise une explication stable.
Garder une sortie opposable
La fin du pipeline associe objet, version, empreinte, taille, type détecté, statut de sécurité et dossier métier. Le support peut expliquer pourquoi un document n’est pas visible. Une simple présence sur disque ne suffit pas : sans ligne de métadonnées et sans relation métier, l’objet reste orphelin.
La mise en œuvre attribue les responsabilités de réception, de scan et de publication. Elle journalise les entrées, les sorties et les dépendances de stockage, puis relie le monitoring à un seuil de quarantaine. Le runbook décrit le retry autorisé et le rollback d’une publication sans jamais remplacer l’original.
Décider entre volume partagé et stockage objet
Un volume local ou réseau convient lorsque l’application exige une interface filesystem, un faible nombre d’instances et une administration maîtrisée. Il simplifie certains outils historiques. Son partage multi-hôtes, ses verrous et sa sauvegarde doivent être prouvés. Un montage réseau lent peut bloquer les workers comme une dépendance externe.
Le stockage objet offre identifiants, API, métadonnées, politiques de cycle de vie et souvent réplication gérée. Il s’adapte bien aux originaux et aux téléchargements directs signés. Il ne fournit pas les mêmes opérations qu’un filesystem : renommer devient souvent copier puis supprimer, les arborescences sont des conventions de clé et la cohérence métier reste dans l’application.
Isoler l’adaptateur
Le domaine demande stocker, ouvrir, supprimer ou générer un accès temporaire. L’adaptateur implémente volume ou objet. Cette frontière évite de propager chemins absolus et API fournisseur dans les règles. Elle ne promet pas une migration gratuite : volumes, latence et sémantique de suppression doivent être testés.
Garder les métadonnées comme source de vérité
La base porte identifiant, propriétaire, nom d’affichage, clé de stockage, empreinte, taille, type détecté, statut, dates et version. Elle ne stocke pas forcément le binaire. La clé technique n’est jamais dérivée uniquement du nom utilisateur ; elle reste stable si le document est renommé dans l’interface.
L’écriture entre base et stockage ne forme pas une transaction distribuée simple. Le workflow accepte des états intermédiaires. Il peut réserver la ligne, écrire l’objet, confirmer, puis nettoyer les réservations expirées. Un échec après stockage laisse un objet orphelin détectable ; un échec avant stockage laisse une ligne en attente, pas un document prétendument disponible.
Réconcilier régulièrement
Un job compare métadonnées et objets par lots, sans lister naïvement des millions de clés à chaque passage. Il signale objet sans ligne, ligne sans objet, empreinte inattendue et version de traitement obsolète. La correction est bornée : quarantaine, reconstruction ou escalade, jamais suppression automatique non expliquée.
Valider sans faire confiance au nom du fichier
L’extension et le type déclarés par le navigateur sont des indices, pas une preuve. L’application génère son nom de stockage, limite les extensions autorisées selon le besoin, inspecte signature et contenu, borne taille et nombre, puis rejette les formats inutiles. Les recommandations OWASP sur les uploads détaillent cette défense en profondeur.
Le stockage reste hors webroot ou derrière un service qui réapplique l’autorisation. Un fichier actif comme SVG, HTML ou document macro reçoit une politique spécifique. La conversion peut réduire certains risques, mais elle crée aussi un parseur exposé. Chaque moteur est patché, limité en CPU et mémoire, puis isolé du réseau si son rôle ne l’exige pas.
Ne pas transformer le scan en verdict absolu
Un antivirus réduit un risque connu à un instant donné ; il ne certifie pas l’innocuité. L’équipe conserve version des signatures, résultat et stratégie quand le scanner est indisponible. Pour un portail sensible, l’échec peut maintenir la quarantaine. Pour un flux moins critique, le métier peut autoriser un mode dégradé clairement visible.
Servir les documents publics et privés sans confusion
Un asset public versionné peut être mis en cache longuement. Une pièce privée exige une décision d’accès à chaque création de lien, une durée courte et une clé non devinable. Une URL signée délègue le transfert, pas l’autorisation initiale. Le serveur vérifie dossier, rôle et statut avant de la produire.
Les en-têtes de téléchargement contrôlent nom d’affichage, type, disposition et cache. Un type actif peut être forcé en pièce jointe. Les réponses privées évitent les caches partagés non prévus. La révocation immédiate d’une URL déjà signée dépend du fournisseur et de la durée : ce compromis doit être choisi, pas découvert pendant un incident.
Protéger les variantes
Une miniature n’hérite pas automatiquement de la visibilité de l’original si elle est publiée ailleurs. Les dérivés portent le même périmètre et une version. La suppression d’un document invalide ou purge toutes ses variantes selon une procédure réconciliable.
Isoler antivirus, aperçu et conversion
Les traitements lourds quittent la requête web. Un message référence le document et la version attendue ; le worker recharge le statut, prend un verrou logique ou applique une clé d’idempotence, puis écrit un dérivé sous une nouvelle clé. Une redélivrance retrouve le résultat au lieu de produire plusieurs fichiers concurrents.
Le worker possède des limites différentes du web. Un PDF malformé ne doit pas monopoliser toute la capacité. Timeout, mémoire, taille de sortie et profondeur de décompression sont bornés. La file distingue erreur temporaire du stockage, format refusé et défaut du moteur. Le support reçoit une action adaptée.
Déployer sans invalider la file
Les messages en attente peuvent traverser une version. Le contrat contient une version de traitement et des références stables. Le nouveau worker comprend l’ancien message ou l’ancienne version reste disponible jusqu’à vidage. Changer silencieusement les règles de conversion rend les résultats impossibles à comparer.
Prouver sauvegarde et restauration de bout en bout
La base et les objets doivent représenter le même horizon métier. Sauvegarder l’une à midi et l’autre à minuit peut créer des liens morts ou des objets sans métadonnées. Le plan documente RPO, ordre de restauration et réconciliation. La version d’application compatible fait partie de l’exercice.
Une réplication protège d’une panne, pas d’une suppression logique qui se propage. Versioning objet, corbeille ou snapshots peuvent offrir une fenêtre, à condition que la politique et les coûts soient connus. Les clés de chiffrement et droits nécessaires à la restauration sont conservés séparément et testés.
Restaurer un échantillon métier
Le test ne s’arrête pas au listing des fichiers. Il ouvre un dossier, contrôle empreinte, autorisation, original et dérivé, puis rejoue un traitement. Un seuil local peut exiger cent documents tirés de plusieurs périodes et zéro lien inexpliqué ; il qualifie ce patrimoine et sera renforcé selon le risque.
Appliquer rétention, suppression et droits
La durée dépend de la finalité et des obligations. Un original peut être archivé, un temporaire purgé en vingt-quatre heures et un dérivé supprimé dès qu’il est régénérable. Ces valeurs sont des choix locaux validés avec le métier et le juridique, pas des durées universelles issues de Docker.
La suppression traverse base, objet, variantes, index, cache et sauvegardes selon leur politique. Elle garde une preuve sans conserver le contenu supprimé. Pour des données personnelles, la CNIL rappelle le principe de conservation limitée et la nécessité de déterminer une durée selon la finalité.
Mettre les exceptions sous responsabilité
Un litige ou une obligation peut suspendre une purge. L’exception possède motif, périmètre, propriétaire et échéance. Un dossier « à garder » sans terme devient une rétention illimitée et empêche l’équipe de prouver ce qui doit réellement survivre.
Cas concret : reprendre les pièces jointes d’un extranet
Cas concret hypothétique. Un extranet stocke cent vingt mille PDF sur un volume local et conserve leurs chemins dans la base. Deux instances web doivent être ajoutées. L’équipe découvre huit mille noms dupliqués, des fichiers sans ligne et des répertoires accessibles directement par Nginx. Les sauvegardes n’ont jamais été restaurées avec la base.
La cible crée des identifiants immuables, copie les originaux vers un stockage objet privé, calcule empreinte et taille puis rapproche chaque dossier. Les lectures passent d’abord par un adaptateur capable de chercher l’ancien et le nouveau. Les nouveaux uploads utilisent immédiatement le pipeline avec quarantaine et URL courte.
Le pilote migre cinq mille documents de trois années. Les seuils locaux demandent zéro document perdu, cent pour cent des objets reliés à un dossier, moins de dix minutes pour expliquer un refus et une restauration de cent objets sans accès manuel au serveur. Scénario supplémentaire : si la copie réussit mais que la base échoue, alors la réconciliation doit isoler l’objet sans le publier.
Tester localement sans copier la production
Le développement utilise un adaptateur compatible ou un service objet local, avec des fixtures synthétiques couvrant taille, format et refus. Il n’a pas besoin de documents clients réels. La CI crée un bucket ou volume éphémère et vérifie upload, téléchargement, redélivrance et nettoyage.
Les différences de fournisseur restent testées par contrat. Un émulateur ne reproduit pas quotas, latence, permissions ou URLs signées. Une préproduction avec données anonymisées et paramètres réalistes complète les tests. Le but est de vérifier la sémantique sans prétendre que chaque environnement partage la même infrastructure.
Empêcher le montage de masquer un oubli
La CI lance l’image sans bind mount du code et avec les seuls chemins déclarés. Un test remplace le conteneur entre réception et traitement. Si le fichier disparaît, le pipeline échoue avant la production. Cette panne simple attrape une classe entière de fausses persistances locales.
Savoir quand l’architecture documentaire devient prioritaire
Le sujet devient critique quand les fichiers ont une valeur métier, plusieurs instances écrivent, des rôles limitent l’accès, des transformations asynchrones existent ou une restauration doit être prouvée. Une équipe qui reçoit contrats, factures, justificatifs ou exports ne peut pas traiter le stockage comme un dossier technique.
Une petite galerie publique de contenus reconstruits depuis un CMS peut suivre une approche plus légère. Le niveau d’architecture dépend de l’irremplaçabilité, de la sensibilité et du volume. Il faut refuser une plateforme documentaire générale si trois assets versionnés suffisent.
Éviter les pertes et doublons les plus fréquents
Écrire dans le conteneur
Le déploiement paraît fonctionner jusqu’au remplacement de l’instance. Tout original durable sort de la couche runtime et un test détruit le conteneur avant d’autoriser le flux.
Faire du nom utilisateur une clé
Deux dossiers écrasent le même fichier ou un nom traverse les chemins. L’application génère la clé, nettoie le nom d’affichage et garde la relation dans les métadonnées.
Sauvegarder sans restaurer
Le volume est copié, mais droits, base ou clés manquent. La répétition ouvre des dossiers réels, vérifie empreintes et rejoue un dérivé avec l’équipe qui portera l’incident.
Choisir une stratégie par classe de fichier
La matrice compare irremplaçabilité, sensibilité, volume, fréquence, partage multi-instance, transformation et rétention. Les originaux sensibles privilégient stockage privé, sauvegarde et contrôle d’accès. Les dérivés privilégient version et reconstruction. Les temporaires reçoivent quota et purge.
- D’abord, conserver l’original hors conteneur avec identifiant et empreinte.
- Ensuite, isoler les traitements lourds et rendre leurs sorties idempotentes.
- Puis, différer la publication tant que sécurité et métadonnées restent incomplètes.
- Enfin, refuser toute ouverture sans sauvegarde restaurée, owner et politique de suppression.
Le verdict peut combiner stockage objet pour les originaux, volume temporaire pour les conversions et CDN pour les assets publics. L’important est que chaque passage possède un état et une reprise. Un seul répertoire partagé pour simplifier le code ne doit pas effacer ces responsabilités.
Plan d’action sur huit semaines
Semaines une et deux : inventorier
L’équipe recense classes de fichiers, chemins, volumes, propriétaires, droits, durées et sauvegardes. Elle rapproche base et stockage sur un échantillon puis choisit le flux dont une perte coûte le plus. Les écritures dans le runtime sont bloquées pour les nouveaux cas.
Semaines trois et quatre : fermer le pipeline
Identifiant, métadonnées, limites, quarantaine et statuts sont implémentés. L’adaptateur de stockage remplace les chemins directs. Les tests couvrent timeout, double soumission, scanner indisponible, objet orphelin et permission refusée. Logs et monitoring relient upload et dossier.
Semaines cinq et six : migrer un lot
Un batch relançable copie, vérifie l’empreinte et confirme la ligne. La lecture accepte ancien et nouveau pendant la transition. Les écarts rejoignent une file de décision ; aucun fichier n’est supprimé de la source avant contrôle et sauvegarde du résultat.
Semaines sept et huit : restaurer et ouvrir
L’équipe restaure base et objets dans un environnement isolé, rejoue conversions et permissions puis exécute le runbook avec le support. Le comité compare pertes, orphelins, délai de reprise et coût. Il élargit seulement si le statut métier correspond aux fichiers disponibles.
La sortie attribue stockage, sécurité, sauvegarde, rétention, monitoring et rollback. Elle documente entrées, sorties, dépendances et seuils. La migration conserve son identifiant de lot et son journal afin qu’un arrêt puisse reprendre sans recopier ni ignorer un document.
Après ouverture, une réconciliation quotidienne puis espacée suit les écarts. Le volume d’orphelins ne devient pas un KPI de vanité : chaque catégorie mène à corriger le pipeline, reconstruire un dérivé ou arbitrer un original. Le plan se termine quand la preuve ne dépend plus du serveur historique.
- D’abord, contrôler un original, ses métadonnées et son statut après remplacement du conteneur.
- Ensuite, provoquer une redélivrance et vérifier que le dérivé n’est pas dupliqué.
- Puis, restaurer base et objets dans un environnement isolé avec les droits réels.
- Enfin, décider l’extension seulement si le support reprend les écarts depuis le runbook.
Guides complémentaires pour fiabiliser les flux
Stabiliser les environnements
Partager les conteneurs de dev, CI et production aide à tester les chemins d’écriture sans bind mount trompeur.
Organiser les traitements asynchrones
Maîtriser Messenger dans le run approfondit idempotence, retries et file d’échec pour les conversions.
Tester les exceptions
Tester un workflow et ses exceptions relie statuts documentaires, refus et reprise support.
- Distinguer original, dérivé et temporaire avant tout choix de technologie.
- Réconcilier base et stockage avant puis après chaque lot de migration.
- Restaurer avec les vrais droits et la version applicative compatible.
Conclusion : rendre le document indépendant du conteneur
Un fichier durable ne doit jamais dépendre de la vie d’une instance. Il possède un identifiant, des métadonnées, un statut, un stockage externe et une politique de sauvegarde cohérente avec son usage métier.
Volume partagé et stockage objet sont deux adaptateurs possibles. La bonne architecture vient de la classe du document, de sa sensibilité, de ses transformations et de la reprise attendue, pas d’une préférence d’infrastructure.
Le test décisif détruit un conteneur, redélivre un traitement et restaure un dossier complet. Si l’utilisateur, le support et les journaux retrouvent la même vérité, le pipeline tient enfin au-delà du cas nominal.
Dawap peut cartographier les flux, fermer le pipeline et migrer un premier lot dans un accompagnement en développement web sur mesure qui protège les documents, les droits et la restauration sans figer le produit dans son stockage historique.