​Laravel 使用 MinIO 作为文件存储​

news/2024/7/5 2:48:32

起因

我们的图片资源和其他静态资源都采用 S3 来进行存储,于是我们为了降低代码复杂度,我们在开发和测试阶段用的存储页时线上 S3 环境,一直以来一切都正常运行着。但是突然有一天,在国内的测试服上传文件到 S3 出现了超时的问题,且这个问题一直无法得到解决。

起初我们考虑在测试服的时候,将文件上传到项目目录的 Storage 下,但是在配置和生成 URL 的时候非常麻烦,不利于 DevOps。

我们的项目中,大量使用自定义的配置或者 ENV 来拼接静态资源的 URL,导致代码的可维护性极差。而且如果要保证访问的一致性,还需要为上传的文件做单独的 Web 服务。

于是乎我就想起了之前在 Github 上看到的一个开源项目 MinIO,没错它就是今天的主角。

MinIO 简介

MinIO 是采用 Go 开发的一套类似于 S3 的存储服务,为什么说用它替代 S3 呢,因为它能兼容 S3 的 API。这样一来,在项目中集成的时候,降低了复杂度。主要在资源 URL 的生成中。

部署 MinIO

我这里采用 Docker Compose 来进行部署,配置文件如下:

services:
  minio:
  image: minio/minio:latest
  restart: always
  hostname: minio
  container_name: minio
  ports:
    - 9000:9000
    - 9001:9001
  volumes:
    - /usr/www/data/minio:/data
  environment:
    - MINIO_ROOT_USER=${MINIO_ROOT_USER}
    - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
  command: server /data --console-address ":9001"

YAML

Copy

设置 Nginx 代理:

server {
    listen 80;
    listen [::]:80;
    server_name minio.example.dev bucket.example.dev minio-console.example.dev;

    location / {
        return 301 https://$host$request_uri;
    }
}

# 文件上传时用到的域名
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name minio.example.dev;

    # SSL
    ssl_certificate certs/fullchain.cer;
    ssl_certificate_key certs/example.dev.key;

    ssl_stapling on;
    ssl_stapling_verify on;

    proxy_buffering off;
    client_max_body_size 0;

    ssl_trusted_certificate /etc/nginx/certs/ca-bundle.trust.crt;

    include components/security.conf;

    # gzip
    gzip                    on;
    gzip_vary               on;
    gzip_proxied            any;
    gzip_comp_level         6;
    gzip_types              text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

    location / {
        proxy_pass http://minio:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# MinIO Bucket 的域名,这样访问上传文件的 URL 中不用加 Bucket 名称
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name bucket.example.dev;

    # SSL
    ssl_certificate certs/fullchain.cer;
    ssl_certificate_key certs/example.dev.key;

    ssl_stapling on;
    ssl_stapling_verify on;

    proxy_buffering off;
    client_max_body_size 0;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    ssl_trusted_certificate /etc/nginx/certs/ca-bundle.trust.crt;

    include components/security.conf;

    # gzip
    gzip                    on;
    gzip_vary               on;
    gzip_proxied            any;
    gzip_comp_level         6;
    gzip_types              text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

    location / {
        # 这里需要将 MinIO 里创建的 Bucket 作为代理的 Endpoint
        proxy_pass http://minio:9000/bucket/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# MinIO 管理后台的代理配置
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name minio-console.example.dev;

    # SSL
    ssl_certificate certs/fullchain.cer;
    ssl_certificate_key certs/example.dev.key;

    ssl_stapling on;
    ssl_stapling_verify on;

    proxy_buffering off;
    client_max_body_size 0;

    ssl_trusted_certificate /etc/nginx/certs/ca-bundle.trust.crt;

    include components/security.conf;

    location / {
        proxy_pass http://minio:9001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /ws {
        proxy_pass http://minio:9001;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        chunked_transfer_encoding off;
    }
}

需要注意的点

  1. 一定要加上 proxy_set_header 的相关配置,否则无法正常访问 MinIO;
  2. 为 Bucket 单独分配一个域名,这样可以完美模拟 S3 的访问 URL;

Laravel 中集成 MinIO

安装依赖

composer require league/flysystem-aws-s3-v3:~1.0

Shell

Copy

修改配置文件

修改 config/filesystems.php 文件中的配置如下:

's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION', 'ap-northeast-1'),
    'bucket' => env('AWS_BUCKET', 'neox'),
    'url' => env('AWS_URL'),
    'endpoint' => env('AWS_ENDPOINT'),
    'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false)
]

PHP

Copy

修改环境配置

修改 .env 文件中的配置如下:

FILESYSTEM_DRIVER=s3
AWS_BUCKET=static # 这里是你 Bucket 的名称
AWS_URL=https://bucket.example.dev # 用于生成 URL 的前缀
AWS_ENDPOINT=https://minio.example.dev # 用于上传文件时访问的 URL
AWS_DEFAULT_REGION=ch-shanghai # 这个是 MinIO 后台配置的 Region
AWS_ACCESS_KEY_ID=MINIO_ACCESS_KEY_ID # 这里是你在 MinIO 后台创建的 User Access Key ID
AWS_SECRET_ACCESS_KEY=MINIO_ACCESS_KEY_SECRET # 这里是你在 MinIO 后台创建的 User Access Key SECRET
AWS_USE_PATH_STYLE_ENDPOINT=true # 这里一定要用 true,才能完美兼容 S3

上传文件

$uri = Storage::put($path, $request->file('file'), ['visibility' => 'public']);
if ($uri) {
    return response()->json([
        'uri' => $uri,
        'url' => Storage::url($uri),
        'filename' => Str::afterLast($uri, '/')
    ]);
}

PHP

Copy

响应如下:

{
    "uri": "trend/reports/8q472L1asBz06mM7VK7i4gd1Kyen4eWRaAcxlmX5.jpg",
    "url": "https://bucket.example.dev/trend/reports/8q472L1asBz06mM7VK7i4gd1Kyen4eWRaAcxlmX5.jpg",
    "filename": "8q472L1asBz06mM7VK7i4gd1Kyen4eWRaAcxlmX5.jpg"
}

JSON

Copy

到这里就完成了 MinIO 的集成和使用了,在生成环境中我们只需要将 .env 的配置项修改为生产环境的配置项就可以了。

预告

因为我们的测试服数据是克隆自生产环境的,所以很多图片资源是存储在 S3 伤的,那么如何将 S3 上的文件同步到测试服的 MinIO 服务上呢?

后面我会分享如何使用 MinIO CLI 进行同步的经验,以及使用事件和消息队列的方式进行资源同步。

I hope this is helpful, Happy hacking…

Laravel 使用 MinIO 作为文件存储

2022-01-14 [Updated: 2023-01-31] :: George

#S3  #Laravel  #MinIO 

起因

我们的图片资源和其他静态资源都采用 S3 来进行存储,于是我们为了降低代码复杂度,我们在开发和测试阶段用的存储页时线上 S3 环境,一直以来一切都正常运行着。但是突然有一天,在国内的测试服上传文件到 S3 出现了超时的问题,且这个问题一直无法得到解决。

起初我们考虑在测试服的时候,将文件上传到项目目录的 Storage 下,但是在配置和生成 URL 的时候非常麻烦,不利于 DevOps。

我们的项目中,大量使用自定义的配置或者 ENV 来拼接静态资源的 URL,导致代码的可维护性极差。而且如果要保证访问的一致性,还需要为上传的文件做单独的 Web 服务。

于是乎我就想起了之前在 Github 上看到的一个开源项目 MinIO,没错它就是今天的主角。

MinIO 简介

MinIO 是采用 Go 开发的一套类似于 S3 的存储服务,为什么说用它替代 S3 呢,因为它能兼容 S3 的 API。这样一来,在项目中集成的时候,降低了复杂度。主要在资源 URL 的生成中。

部署 MinIO

我这里采用 Docker Compose 来进行部署,配置文件如下:

services:
  minio:
  image: minio/minio:latest
  restart: always
  hostname: minio
  container_name: minio
  ports:
    - 9000:9000
    - 9001:9001
  volumes:
    - /usr/www/data/minio:/data
  environment:
    - MINIO_ROOT_USER=${MINIO_ROOT_USER}
    - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
  command: server /data --console-address ":9001"

YAML

Copy

设置 Nginx 代理:

server {
    listen 80;
    listen [::]:80;
    server_name minio.example.dev bucket.example.dev minio-console.example.dev;

    location / {
        return 301 https://$host$request_uri;
    }
}

# 文件上传时用到的域名
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name minio.example.dev;

    # SSL
    ssl_certificate certs/fullchain.cer;
    ssl_certificate_key certs/example.dev.key;

    ssl_stapling on;
    ssl_stapling_verify on;

    proxy_buffering off;
    client_max_body_size 0;

    ssl_trusted_certificate /etc/nginx/certs/ca-bundle.trust.crt;

    include components/security.conf;

    # gzip
    gzip                    on;
    gzip_vary               on;
    gzip_proxied            any;
    gzip_comp_level         6;
    gzip_types              text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

    location / {
        proxy_pass http://minio:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# MinIO Bucket 的域名,这样访问上传文件的 URL 中不用加 Bucket 名称
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name bucket.example.dev;

    # SSL
    ssl_certificate certs/fullchain.cer;
    ssl_certificate_key certs/example.dev.key;

    ssl_stapling on;
    ssl_stapling_verify on;

    proxy_buffering off;
    client_max_body_size 0;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    ssl_trusted_certificate /etc/nginx/certs/ca-bundle.trust.crt;

    include components/security.conf;

    # gzip
    gzip                    on;
    gzip_vary               on;
    gzip_proxied            any;
    gzip_comp_level         6;
    gzip_types              text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

    location / {
        # 这里需要将 MinIO 里创建的 Bucket 作为代理的 Endpoint
        proxy_pass http://minio:9000/bucket/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# MinIO 管理后台的代理配置
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name minio-console.example.dev;

    # SSL
    ssl_certificate certs/fullchain.cer;
    ssl_certificate_key certs/example.dev.key;

    ssl_stapling on;
    ssl_stapling_verify on;

    proxy_buffering off;
    client_max_body_size 0;

    ssl_trusted_certificate /etc/nginx/certs/ca-bundle.trust.crt;

    include components/security.conf;

    location / {
        proxy_pass http://minio:9001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /ws {
        proxy_pass http://minio:9001;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        chunked_transfer_encoding off;
    }
}

需要注意的点

  1. 一定要加上 proxy_set_header 的相关配置,否则无法正常访问 MinIO;
  2. 为 Bucket 单独分配一个域名,这样可以完美模拟 S3 的访问 URL;

Laravel 中集成 MinIO

安装依赖

composer require league/flysystem-aws-s3-v3:~1.0

Shell

Copy

修改配置文件

修改 config/filesystems.php 文件中的配置如下:

's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION', 'ap-northeast-1'),
    'bucket' => env('AWS_BUCKET', 'neox'),
    'url' => env('AWS_URL'),
    'endpoint' => env('AWS_ENDPOINT'),
    'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false)
]

PHP

Copy

修改环境配置

修改 .env 文件中的配置如下:

FILESYSTEM_DRIVER=s3
AWS_BUCKET=static # 这里是你 Bucket 的名称
AWS_URL=https://bucket.example.dev # 用于生成 URL 的前缀
AWS_ENDPOINT=https://minio.example.dev # 用于上传文件时访问的 URL
AWS_DEFAULT_REGION=ch-shanghai # 这个是 MinIO 后台配置的 Region
AWS_ACCESS_KEY_ID=MINIO_ACCESS_KEY_ID # 这里是你在 MinIO 后台创建的 User Access Key ID
AWS_SECRET_ACCESS_KEY=MINIO_ACCESS_KEY_SECRET # 这里是你在 MinIO 后台创建的 User Access Key SECRET
AWS_USE_PATH_STYLE_ENDPOINT=true # 这里一定要用 true,才能完美兼容 S3

上传文件

$uri = Storage::put($path, $request->file('file'), ['visibility' => 'public']);
if ($uri) {
    return response()->json([
        'uri' => $uri,
        'url' => Storage::url($uri),
        'filename' => Str::afterLast($uri, '/')
    ]);
}

PHP

Copy

响应如下:

{
    "uri": "trend/reports/8q472L1asBz06mM7VK7i4gd1Kyen4eWRaAcxlmX5.jpg",
    "url": "https://bucket.example.dev/trend/reports/8q472L1asBz06mM7VK7i4gd1Kyen4eWRaAcxlmX5.jpg",
    "filename": "8q472L1asBz06mM7VK7i4gd1Kyen4eWRaAcxlmX5.jpg"
}

JSON

Copy

到这里就完成了 MinIO 的集成和使用了,在生成环境中我们只需要将 .env 的配置项修改为生产环境的配置项就可以了。

预告

因为我们的测试服数据是克隆自生产环境的,所以很多图片资源是存储在 S3 伤的,那么如何将 S3 上的文件同步到测试服的 MinIO 服务上呢?

后面我会分享如何使用 MinIO CLI 进行同步的经验,以及使用事件和消息队列的方式进行资源同步。

I hope this is helpful, Happy hacking…


http://lihuaxi.xjx100.cn/news/1063832.html

相关文章

Vue3技术6之toRef和toRefs、shallowReactive与shallowRef、readonly与shallowReadonly

Vue3技术6 toRef和toRefstoRefApp.vueDemo.vue toRefsApp.vueDemoTwo.vue 总结 shallowReactive与shallowRefshallowReactiveApp.vueDemo.vue shallowRefDemo.vue 总结 readonly与shallowReadonlyApp.vueDemo.vueDemoTwo.vue总结 toRef和toRefs toRef App.vue <template&…

MySQL按照,库的操作,表的约束 --- MySQL总结(一)

MySQL 文章目录 MySQLMySQL的安装MySQL组成架构连接池软件层引擎层储存层 库的操作创建库修改数据库删除数据库备份数据库还原数据库查看链接情况 表操作创建表查看表结构修改表结构添加字段修改字段类型长度更改表名修改属性删除表 数据类型表的约束空属性&#xff08;not nul…

哪款无线洗地机最好用?好用的无线洗地机分享

洗地机是近几年来比较火的家庭清洁工具&#xff0c;我从推出以来就一直在使用&#xff0c;这些年下来也使用过不少品牌的洗地机&#xff0c;其中有好用的&#xff0c;也有体验一般的。今天为大家分享几款个人使用下来感觉还不错的洗地机。希望对于同样在选购洗地机的你有所帮助…

Python每日一练(20230424)

目录 1. 滑动窗口最大值 &#x1f31f;&#x1f31f;&#x1f31f; 2. 用栈实现队列 &#x1f31f; 3. 直线上最多的点数 &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一…

《面试1v1》java泛型

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a;小伙子,说实话,泛型这个机制一开始我也是一头雾水,搞不太明白它到底要解决什么问题。你能不能不那么书呆子,给我普普通通地讲一讲泛型? 候选人…

掌握这些移动测试技巧,棘手的问题也能游刃有余解决了

目录&#xff1a;导读 引言 一、测试的程序 二、功能测试点 三、移动端安卓环境变量 性能测试 四、实操通过USB连接到手机设备 五、adb操作命令 写在最后 引言 你是否曾经遇到过打开一个移动应用后出现各种问题&#xff0c;比如卡顿、闪退等&#xff1f; 这些问题可能会…

android framework-ActivityManagerService(AMS)下

一、ActivityThread \frameworks\base\core\java\android\app\ActivityThread.java 1.1、main public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");// Install selective syscall interceptionAnd…

如何使用Tensorflow神经网络模型来完成兰州房价预测分析?

兰州房价预测是一个非常热门的话题,许多人都对如何预测兰州房价感兴趣。在本文中,我将介绍如何使用TensorFlow来预测兰州房价,并提供Python源代码。 首先,我们需要收集兰州的房价数据。我们可以从房地产网站或政府统计数据中获取。在本文中,我们将使用Kaggle上提供的兰州…