Aller au contenu

Comment faire fonctionner `temporaryUrl()` de MinIO avec Laravel

temporaryUrl() de MinIO ne fonctionne pas par défaut avec Docker. Voici la config minimale qui résout le problème.

· 4 min read ·
Laravel MinIO S3 Docker

TL;DR : temporaryUrl() de MinIO echoue dans Docker car l’URL generee utilise le hostname interne du conteneur. Corrigez en definissant AWS_URL vers votre endpoint MinIO externe et en configurant la cle url dans votre config disque S3.

Comment faire fonctionner temporaryUrl() de MinIO avec Laravel

Storage::disk('s3')->temporaryUrl() de Laravel génère des URLs signées pour vos fichiers privés dans MinIO. Sauf que dans Docker, les URLs générées pointent vers le hostname interne du conteneur et ne marchent pas dans le navigateur.

Voici la config minimale qui règle le problème.


Étape 1 : Définir un nom de conteneur stable

Dans votre fichier docker-compose.yml, configurez le service MinIO avec un nom de conteneur fixe :

minio:
  image: "minio/minio:latest"
  ports:
    - "9000:9000"
    - "8900:8900"
  container_name: dev.minio.example.com
  environment:
    MINIO_ROOT_USER: "example"
    MINIO_ROOT_PASSWORD: "password"
  volumes:
    - "example-minio:/data/minio"
  networks:
    - example-network
  command: minio server /data/minio --console-address ":8900"

Pourquoi ça marche

Le nom du conteneur sert de hostname. Laravel l’utilise pour joindre MinIO dans Docker, et vous allez le mapper vers 127.0.0.1 sur votre machine (étape suivante) pour que votre navigateur y accède aussi. Pas de VIRTUAL_HOST, pas d’alias réseau.


Étape 2 : Modifier /etc/hosts pour un accès local

Sur votre machine locale, ajoutez cette ligne à votre fichier /etc/hosts (Linux/macOS) ou C:\Windows\System32\drivers\etc\hosts (Windows) :

127.0.0.1 dev.minio.example.com

Maintenant http://dev.minio.example.com pointe vers votre machine locale. Les URLs signées marcheront dans votre navigateur.


Étape 3 : Générer des identifiants MinIO

N’utilisez pas les identifiants root dans votre app. Créez une clé dédiée depuis la console MinIO :

  1. Ouvrir la console MinIO : http://localhost:8900

  2. Se connecter avec :

    • Utilisateur : example
    • Mot de passe : password
  3. Aller dans Identity > Users

  4. Cliquer sur “Create User” et générer :

    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
  5. Assigner les droits de lecture et d’écriture à cet utilisateur.


Étape 4 : Configurer Laravel

Mettez à jour votre .env avec les identifiants que vous venez de créer :

AWS_ACCESS_KEY_ID=your_generated_access_key
AWS_SECRET_ACCESS_KEY=your_generated_secret_key
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=test-storage
AWS_URL=http://dev.marketplace-api.example.com:9000/test-storage
AWS_ENDPOINT=http://dev.minio.example.com:9000
AWS_USE_PATH_STYLE_ENDPOINT=true

Ce que chaque champ fait :

ChampDescription
AWS_URLL’URL de votre app Laravel suivie du port MinIO + nom du bucket
AWS_ENDPOINTAdresse interne vers le conteneur MinIO
Clés AWSGénérées depuis la console MinIO

Pensez à vider le cache de Laravel après mise à jour :

php artisan config:clear
php artisan cache:clear

Étape 5 : Générer une URL temporaire avec Laravel

C’est tout. Générez une URL signée :

use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;

$filePath = 'documents/sample.pdf';
$expiration = Carbon::now()->addMinutes(60); // URL valide pendant 1h

$url = Storage::disk('s3')->temporaryUrl($filePath, $expiration);

return response()->json(['temporary_url' => $url]);

L’astuce en résumé

Le vrai problème est la résolution du hostname. Les conteneurs Docker utilisent des hostnames internes, mais votre navigateur a besoin d’atteindre le même hostname depuis l’extérieur. Nommer le conteneur comme un domaine et le mapper dans /etc/hosts résout les deux côtés d’un coup.

Cinq minutes de config. Pas de proxy nginx, pas d’alias réseau, pas de middleware custom.

Questions frequentes

Pourquoi temporaryUrl() de MinIO echoue dans Docker ?

L’URL presignee generee utilise le hostname Docker interne (comme minio:9000) qui n’est pas accessible depuis le navigateur. Vous devez configurer une URL accessible exterieurement via AWS_URL dans votre .env.

Quelle est la difference entre AWS_ENDPOINT et AWS_URL dans Laravel ?

AWS_ENDPOINT est utilise par le client S3 pour se connecter a MinIO en interne. AWS_URL est utilise pour generer les URLs publiques. Dans Docker, l’endpoint peut etre http://minio:9000 tandis que l’URL doit etre http://localhost:9000.

Cette solution fonctionne-t-elle en production ?

Oui. En production, definissez AWS_URL vers votre domaine MinIO public (ex: https://storage.example.com). Les parametres de l’URL presignee fonctionnent independamment de l’URL de base.