1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

laravel ローカル開発環境でS3互換のMiniOのバケットにputFileするとfalseが返る

Last updated at Posted at 2023-10-26

概要

  • app/public/test_images/image.pngに存在するファイルをMiniOのpublicバケットにputFileしようとしてもfalseが返るので自分の場合の原因を突き止めてみた。

前提

  • ローカル開発環境はDocker

  • S3のファイルをいじるときに使うライブラリ(league/flysystem-aws-s3-v3)はインストール済み。composer.jsonにも下記のように記載されていることを確認済み。

    composer.json
    "league/flysystem-aws-s3-v3": "^3.16"
    

問題解決までの道のり

  • laravelのコードが有るコンテナに入りtinkerを起動する。

  • 下記を実行してアプリケーション → MiniOバケットに疎通確認をしてみる。

    $localImagePath = storage_path('app/public/test_images/image.png');
    $file = new \Illuminate\Http\File($localImagePath);
    
    $pathInStorage = Storage::disk('s3')->putFile('test_folder', $file);
    
  • やはりputFileでfalseが返る。上記のコードの出力内容をそれぞれ合わせてみてみる。

    • $localImagePath = storage_path('app/public/test_images/image.png');の結果(問題なさそう)

      = "/app/storage/app/public/test_images/image.png"
      
    • $file = new \Illuminate\Http\File($localImagePath);の結果(問題なさそう)

      = Illuminate\Http\File {#3869
          path: "/app/storage/app/public/test_images",
          filename: "image.png",
          basename: "image.png",
          pathname: "/app/storage/app/public/test_images/image.png",
          extension: "png",
          realPath: "/app/storage/app/public/test_images/image.png",
          aTime: 2023-10-26 23:31:20,
          mTime: 2023-08-01 17:59:33,
          cTime: 2023-10-26 14:54:41,
          inode: 7545195,
          size: 104934,
          perms: 0100644,
          owner: 0,
          group: 0,
          type: "file",
          writable: true,
          readable: true,
          executable: true,
          file: true,
          dir: false,
          link: false,
      linkTarget: "/app/storage/app/public/test_images/image.png",    }
      
    • $pathInStorage = Storage::disk('s3')->putFile('test_folder', $file);の結果(問題有りそう)

      = false
      
  • $file = new \Illuminate\Http\File($localImagePath);の結果が問題なさそうと判断した理由は、$localImagePathを架空のものにしてから実行したらエラーになったため。

    $localImagePath = '/app/storage/app/public/test_images/foobar.png'
    = "/app/storage/app/public/test_images/foobar.png"
    
    $file = new \Illuminate\Http\File($localImagePath);
    
    Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException  The file "storagepublic/test_images/foobar.png" does not exist.
    
  • こうなるとMiniOに疎通できていない可能性が非常に高い

  • MiniOへの接続情報が間違えているかもしれない。取り急ぎlaravelの.envを確認してみる。

    .env
    AWS_USE_PATH_STYLE_ENDPOINT=true
    
    AWS_URL=http://locaohost:9000
    AWS_ENDPOINT=http://localhost:9000
    
  • ぱっとみ問題なさそうに見えるが、PHPのコンテナとMiniOのコンテナは別コンテナである。そうなるとPHP→MiniOの通信はコンテナ間通信ということになる。

  • Dockerのコンテナ間通信はdocker-composer.yamlのservicesで定義した名前を指定することでDocker側が勝手に内部DNSで解決してくれる。

  • 筆者の環境はMiniOのServicesはminioという名前で定義しているので下記の様になる。(AWS_URLの方はオブジェクトへのパス生成で使うのでlocalhostのままにしておく、多分S3を使う環境の場合 AWS_USE_PATH_STYLE_ENDPOINT=falseAWS_URL=で良いはず。AWS_USE_PATH_STYLE_ENDPOINT=trueとすると「AWS_URLを使ってストレージファサードでオブジェクトのURLを作成するよ」という設定になるはず。AWS_URL=http://localhost:9000/バケット名にバケット名を含めないとMiniOの場合完全なURLが生成できず、XMLのエラーが出ることがある。)

    .env
    AWS_USE_PATH_STYLE_ENDPOINT=true
    
    AWS_URL=http://localhost:9000/バケット名
    AWS_ENDPOINT=http://minio:9000
    
  • これで今一度tinkerからputFileしてみる。

    $localImagePath = storage_path('app/public/test_images/image.png');
    = "/app/storage/app/public/test_images/image.png"
    
    $file = new \Illuminate\Http\File($localImagePath);
    = Illuminate\Http\File {#3875
        path: "/app/storage/app/public/test_images",
        filename: "image.png",
        basename: "image.png",
        pathname: "/app/storage/app/public/test_images/image.png",
        extension: "png",
        realPath: "/app/storage/app/public/test_images/image.png",
        aTime: 2023-10-26 23:31:20,
        mTime: 2023-08-01 17:59:33,
        cTime: 2023-10-26 14:54:41,
        inode: 7545195,
        size: 104934,
        perms: 0100644,
        owner: 0,
        group: 0,
        type: "file",
        writable: true,
        readable: true,
        executable: true,
        file: true,
        dir: false,
        link: false,
      }
    
    $pathInStorage = Storage::disk('s3')->putFile('test_folder', $file);
    = "test_folder/kP3DDCldR5VPxpvlzj5TAqmOQZVWy7xWz7fSXWI4.png"
    
  • アップロードできたっぽい。

  • ブラウザで見ても設置できてた。良かった。解決した。

    MinIO_Console.png

おまけ MiniO接続チェック項目

  • ライブラリ(league/flysystem-aws-s3-v3)はインストール済み?!
  • .envの下記の内容はそれぞれ記載されてる?
    • AWS_ACCESS_KEY_ID=docke-compose.ymlのenvironmentでMINIO_ROOT_USERに設定している値
    • AWS_SECRET_ACCESS_KEY=docke-compose.ymlのenvironmentでMINIO_ROOT_PASSWORDに設定している値
    • AWS_DEFAULT_REGION=us-east-1 → 固定
    • AWS_BUCKET=バケット名 → 手動か、docker-compose.ymlで自動作成したバケット名
    • AWS_USE_PATH_STYLE_ENDPOINT=true
    • AWS_URL=http://localhost:9000 → ポート名は設定によって異なる可能性があるよ
    • AWS_ENDPOINT=http://minio:9000 → docker-compose.ymlのMiniOコンテナのservicesの値だよ、localhostじゃないよ
  • そもそもMiniOコンテナは起動している?
  • そもそもバケットは存在している?
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?