# Médias de production en local sans les télécharger : le proxy d’uploads

> Servir les images manquantes en local directement depuis la production via une règle nginx, pour un environnement de développement léger et à jour.

- Auteur : Clément Hadrot
- Publié le : 2021-03-17
- Mis à jour le : 2021-03-17
- Catégorie : Outils &amp; workflow
- URL : https://wpmoderne.dev.wordpress-developpement.fr/outils/medias-production-local-proxy-uploads/

## L’essentiel

- Une règle nginx qui bascule vers la production si l'image est absente
- Un dossier uploads local qui reste vide ou presque
- Alternative en PHP pour les configurations sans nginx

Un client e-commerce avec dix ans d'historique de catalogue possédait un dossier `wp-content/uploads` de 14 Go. Chaque nouveau développeur qui clonait le projet en local perdait une demi-journée à synchroniser ces fichiers, pour un résultat qui n'avait aucun intérêt : en développement, on regarde rarement une vraie photo produit, on vérifie surtout que la mise en page s'affiche correctement.

Le proxy d'uploads règle ce problème une fois pour toutes : quand une image demandée n'existe pas localement, le serveur la sert directement depuis la production, sans jamais la télécharger ni l'enregistrer sur la machine de développement. Cette recette ne traite pas la mise en place d'un CDN, qui répond à un besoin différent — accélérer la production, pas alléger le local.

## Le principe : réécriture conditionnelle côté serveur

> L'essentiel à retenir : Une règle nginx qui bascule vers la production si l'image est absente ; Un dossier uploads local qui reste vide ou presque ; Alternative en PHP pour les configurations sans nginx

Avec nginx comme serveur local (via Docker, DDEV ou une configuration native), une règle de réécriture teste l'existence du fichier avant de le servir. S'il est absent, la requête est transmise à la production :

```
location ~* ^/wp-content/uploads/.*\.(jpg|jpeg|png|gif|webp|svg)$ {
    try_files $uri @production_media;
}

location @production_media {
    proxy_pass https://mon-site.fr;
    proxy_set_header Host mon-site.fr;
    proxy_ssl_server_name on;
}
```

Le navigateur ne voit aucune différence : l'image s'affiche avec l'URL locale, mais son contenu réel provient de la production. Aucun octet n'est écrit sur le disque local, ce qui garde l'environnement de développement léger indéfiniment, même après des années d'ajout de contenu en production.

## Version DDEV : configuration additionnelle

Avec DDEV, qui utilise nginx en interne, la configuration s'ajoute via un fichier de configuration additionnel placé dans `.ddev/nginx_full/uploads-proxy.conf` :

```
server {
    location ~* ^/wp-content/uploads/.*\.(jpg|jpeg|png|gif|webp|svg)$ {
        try_files $uri @production_media;
    }

    location @production_media {
        resolver 8.8.8.8;
        proxy_pass https://mon-site.fr$request_uri;
        proxy_intercept_errors off;
    }
}
```

Un `ddev restart` suffit à activer la règle. Le résolveur DNS explicite (`resolver 8.8.8.8`) est nécessaire car nginx, dans certaines configurations conteneurisées, ne réutilise pas automatiquement le résolveur système pour un `proxy_pass` vers un nom de domaine externe.

## Alternative en PHP pour un hébergement mutualisé local

Sur des configurations qui ne donnent pas la main sur la conf nginx (certains environnements Local, MAMP), une extension légère peut intercepter les requêtes 404 sur `wp-content/uploads` :

```
add_action( 'template_redirect', function () {
	if ( ! is_404() ) {
		return;
	}

	$path = $_SERVER['REQUEST_URI'];
	if ( strpos( $path, '/wp-content/uploads/' ) === 0 ) {
		wp_redirect( 'https://mon-site.fr' . $path, 302 );
		exit;
	}
} );
```

Cette version redirige le navigateur plutôt que de proxifier réellement la requête : plus simple à mettre en place, mais visible dans l'onglet réseau des outils de développement, et légèrement moins fluide qu'une vraie réécriture serveur.

## Attention aux formats générés à la volée

WordPress génère de nombreuses tailles d'image dérivées (`mon-image-300x200.jpg`) au moment de l'upload. Si la taille demandée en local n'existe pas exactement en production sous ce nom — ce qui arrive après un changement de thème modifiant les tailles enregistrées — le proxy échoue silencieusement. Deux options pour limiter ce cas :

- Générer la version manquante côté production via `wp media regenerate --yes` avant de commencer un nouveau projet local
- Ajouter une règle de repli vers l'image taille originale si la variante précise n'est pas trouvée en production

## Sécurité et bonnes pratiques

> Ce mécanisme ne doit exister que sur les environnements de développement, jamais activé sur un environnement accessible publiquement — un proxy ouvert vers la production pourrait être détourné pour masquer l'origine de requêtes non désirées.

Quelques précautions à respecter :

1. Limiter la règle de proxy aux seules extensions d'image, jamais à l'ensemble du dossier `uploads`
2. Vérifier que le domaine de production n'expose pas de fichier sensible accessible via ce chemin
3. Désactiver ou retirer la configuration avant tout déploiement vers un environnement de recette publique

## Pour aller plus loin

Le proxy d'uploads change concrètement le quotidien d'une équipe qui travaille sur un site avec un historique de médias volumineux : plus de synchronisation manuelle, plus de disque local saturé, et des images toujours à jour puisqu'elles proviennent en direct de la production. La seule contrepartie est une dépendance réseau permanente en développement — un léger prix à payer, largement compensé par le temps gagné à ne plus gérer de copies locales obsolètes.
