0
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?

next-s3-uploadとMinIOでローカルのファイル投稿環境を構築する

Last updated at Posted at 2024-09-25

はじめに

最近Next.jsのウェブアプリでファイルの投稿機能を追加するときはnext-s3-uploadを使っているのですが、ファイルストレージサービスを実環境のS3を使っていたので、ローカル用のS3環境を立ててみたいと思って色々と調べてやってみました。

MinIOを使う

MinIOを使うことでS3互換性のあるサービスをDockerで構築することができます。

以下はdocker-compose.ymlの例です。

docker-compose.yml
services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: s3-minio
    environment:
      MINIO_ROOT_USER: admin123
      MINIO_ROOT_PASSWORD: admin123
    command: server --console-address ":9090" /data
    volumes:
      - ./docker/minio/data:/data
    ports:
      - 9000:9000
      - 9090:9090

ここではユーザー名とパスワードをadmin123で設定しています。まずは以下のコマンドでDockerを起動します。

docker compose up -d

次にhttp://localhost:9090にアクセスをしてコンソール画面にアクセスして、先ほど設定したユーザー名とパスワードでログインします。

スクリーンショット 2024-09-25 10.30.37.png

左メニューからBucketsを選択してCreate Bucketでストレージを新規作成します。

スクリーンショット 2024-09-25 10.28.36.png

左メニューからAccess Keysを選択してCreate Access Keyでアクセスキーを新規作成します。

スクリーンショット 2024-09-25 10.32.11.png

これでローカルのS3の準備ができたので、作成した以下の情報を記録しておきます。

  • バケット名
  • アクセスキー
  • シークレットキー

next-s3-uploadでMinIOと繋ぎこみ

前提としてNext.jsnext-s3-uploadは既にインストールされているものとします。今回はNext.jsのpage routerで実装するとして、src/pages/s3-upload.tsで以下を実装します。

src/pages/s3-upload.ts
import { APIRoute } from 'next-s3-upload'

export default APIRoute.configure({
  accessKeyId: process.env.S3_UPLOAD_KEY,
  secretAccessKey: process.env.S3_UPLOAD_SECRET,
  bucket: process.env.S3_UPLOAD_BUCKET,
  region: process.env.S3_UPLOAD_REGION,
  endpoint: process.env.S3_UPLOAD_ENDPOINT,
  forcePathStyle: true,
})

forcePathStyle: trueという設定は、AWS S3以外を用いる場合は重要になるので必ずtrueで設定しておきます。.envは以下のように設定します。

.env
S3_UPLOAD_KEY=アクセスキー
S3_UPLOAD_SECRET=シークレットキー
S3_UPLOAD_BUCKET=バケット名
S3_UPLOAD_REGION=ap-northeast-1
S3_UPLOAD_ENDPOINT=http://localhost:9000

S3_UPLOAD_REGIONS3_UPLOAD_ENDPOINTについては内容そのままコピペで大丈夫です。AWS以外の環境で実装する場合の詳細は公式ドキュメントのOther providersの項でまとめてあります。
あとはファイル投稿画面を実装するだけですが、アップロード機能のhooksはusePresignedUploadを使います。以下はコード例です。

import { FC, useState } from 'react';
import { usePresignedUpload } from 'next-s3-upload'

export const Component: FC = ({ contents, handleSave }) => {
  const { uploadToS3, FileInput, openFileDialog } = usePresignedUpload()
  const [imageUrl, setImageUrl] = useState<string>('')
  const handleFileChange = async (file: File) => {
    const { url } = await uploadToS3(file)
    setImageUrl(url)
  }
  return (
    <>
      {imageUrl ? (
        <img src={imageUrl} />
      ) : (
        <div>サムネイルをアップロードしてください</div>
      )}
        <FileInput
          type="file"
          onChange={handleFileChange}
        />
        <button type="button" onClick={openFileDialog}>
          ファイル選択
        </button>
    </>
  )
}

さいごに

MinIOとnext-s3-uploadの連携方法について、書いている記事が見つからなかったので今回はそれについてまとめてみました。最初の導入は若干面倒ではありますが、一度構築してしまえば料金の心配なしに開発ができるので、結構便利だと思います。

0
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
0
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?