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

news/2024/5/9 13:23:55/文章来源:https://blog.csdn.net/vcit102/article/details/130338540

起因

我们的图片资源和其他静态资源都采用 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:latestrestart: alwayshostname: miniocontainer_name: minioports:- 9000:9000- 9001:9001volumes:- /usr/www/data/minio:/dataenvironment:- 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;# SSLssl_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;# gzipgzip                    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;# SSLssl_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;# gzipgzip                    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 作为代理的 Endpointproxy_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;# SSLssl_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:latestrestart: alwayshostname: miniocontainer_name: minioports:- 9000:9000- 9001:9001volumes:- /usr/www/data/minio:/dataenvironment:- 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;# SSLssl_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;# gzipgzip                    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;# SSLssl_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;# gzipgzip                    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 作为代理的 Endpointproxy_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;# SSLssl_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://www.luyixian.cn/news_show_669023.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jetson Nano一步到位打开USB摄像头(Rosmaster小车)

背景:我用的rosmaster r2小车配的摄像头是Astra pro,也就是下图这款: 1. 支持的摄像头 Jetson开发包有多个用于连接相机的接口,包括USB、以太网和MIPI CSI-2。流行的相机是现成的支持,而Jetson生态系统合作伙伴支持广…

HBase进阶——文件的合并、 MemStore Flush、StoreFile Compaction、 Region Split、高可用与预分区介绍

系列文章目录 centos7虚拟机下hbase的使用案例讲解 hbase进阶操作——读流程与写流程介绍 centos7虚拟机在集群zookeeper上面配置hbase的具体操作步骤 文章目录 系列文章目录 一、HBase的架构原理 1、StoreFile 2、MemStore 3、WAL 二、HBase的shell操作 2.1、创建表…

java防止重复提交的方法

为了防止重复提交,可以采用以下几种方法: 1. 令牌机制(Token) 在表单中添加一个隐藏字段,用于存放一个随机生成的令牌(Token)。当用户提交表单时,将令牌一起提交到服务器。服务器接收…

2023前端面试上岸手册——JavaScript 部分

目录 JavaScript 有哪些数据类型,它们的区别?数据类型检测的方式有哪些null 和undefined 区别如何获取安全的 undefined 值?Object.is() 与比较操作符 “两等” 、“三等” 的区别?什么是 JavaScript 中的包装类型?为什…

MySQL:创建数据库,数据表,主键和外键

目录 前言: 安装MySQL: 打开MySQL: 创建数据库: 查看已建数据库: 查看数据库引擎: 创建数据表: 主键约束: 单字段主键: 多字段联合主键: 外键约束&…

​如何恢复回收站清空的文件?

清空回收站后可以恢复删除的文件吗? 你是否遇到过清空回收站后才意识到某些文件不应删除的情况。发生这种情况时,许多人会感到恐慌,并且想知道是否有可能恢复回收站清空的文件。 事实上,你不必为此担心。当用户清空回收站时&a…

【Python】实战:生成无关联单选问卷 csv《跌倒风险评估量表》

目录 一、适用场景 二、业务需求 三、Python 文件 (1)创建文件 (2)代码示例 四、csv 文件 一、适用场景 实战场景: 问卷全部为单选题问卷问题全部为必填问题之间无关联关系每个问题的答案分数不同根据问卷全部问…

ES使用小结

ES使用总结 1.查询es全部索2.根据es索引查询文档3.查看指定索引mapping文件4.默认查询总数10000条5.删除指定索引文档6.删除所有数据包括索引7.設置窗口值8. logstash简单配置Logstash配置:logstash 控制台输出 9. filebenat配置 1.查询es全部索 localhost:9200/_c…

NFS网络文件共享服务

NFS网络文件共享服务 NFS(network file system)网络文件系统 可以把对方主机资源直接挂载到自己电脑上,比FTP更加方便 明文传输 没有认证机制 安全性很差 只在局域网使用 依赖RPC(远程过程调用) 需要安装nfs-utils(提供NFS服务)…

Nacos身份绕过漏洞复现(QVD-2023-6271)

Nacos身份绕过漏洞复现(QVD-2023-6271) 公司上级预警QVD-2023-6271,领导安排进行排查。 本着知己知彼的原则,我在本地将该漏洞复现出来。 漏洞原理:Nacos 在默认配置下未对 token.secret.key 进行修改,导…

开放式耳机有什么好处,分享几款高畅销的开放式耳机

开放式耳机是一种声音传导方式,主要通过颅骨、骨骼把声波传递到内耳,属于非入耳式的佩戴方式。相比传统入耳式耳机,开放式耳机不会堵塞耳道,使用时可以开放双耳,不影响与他人的正常交流。开放式耳机不会对耳朵产生任何…

短视频app开发:如何实现实时短视频录制功能

简介 在当今的移动互联网时代,短视频app已经成为了人们生活中不可或缺的一部分。短视频app的数量和用户量都在不断增加。如今,越来越多的人开始关注短视频app的开发,尤其是如何实现实时短视频录制功能。本文将分享如何开发短视频app并实现实…

DataStructure--Tree

文章摘录链接 1.树基本概念 计算机数据结构中的树就是对显示中的树的一种抽象(倒置现实中的树)。 1.1 树 有层次关系N(N≥0)个节点的有限集合空树: N0 非空树: 有且只有一个根节点1.2 节点 根节点 分…

java: Compilation failed: internal java compiler error

问题描述: 今天学习一个新的框架 Jbolt-v3.0,然后将它通过 IDEA 导入,运行报错,如下显示: 接着我尝试了百度上的解决方案,依然没有解决,遂即记录一下。 原因分析: 出现这种报错的原…

Linux下版本控制器(SVN) -服务器端环境搭建步骤

文章目录 进阶知识-Linux下版本控制器(SVN)4、服务器端环境搭建步骤4.1 安装服务器端程序4.2 验证是否安装成功4.3 创建并配置版本库4.4 配置 SVN对应的服务4.5 启动 SVN服务 本人其他相关文章链接 进阶知识-Linux下版本控制器(SVN) 4、服务器端环境搭建步骤 4.1 安装服务器端…

带你一步步实现代码开发平台——概述、实现模式、整体框架

概述 低代码开发平台是一种开发工具,它允许用户使用图形界面和少量编码来创建应用程序。这种平台的目的是加快应用程序开发速度,减少开发成本和技能门槛。目前,市场上有许多低代码开发平台可供选择,包括Microsoft Power Apps、Ou…

六、Golang的并发

Go语言的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为goroutine时,Go会将其视为一个独立的工作单元。这个单元会被调度到可用的逻辑处理器上执行。 Go语言运行时的调度器是一个复杂的软件,能管理被创建的所有goroutine并为其分配执…

Spring之Bean的配置与实例

Spring之Bean的配置与实例 一、Bean的基础配置1. Bean基础配置【重点】配置说明代码演示运行结果 2. Bean别名配置配置说明代码演示打印结果 3. Bean作用范围配置【重点】配置说明代码演示打印结果 二、Bean的实例化1. Bean是如何创建的2. 实例化Bean的三种方式2.1 构造方法方式…

NewBing 边栏快捷插件没有了!如何解决?如何脱离浏览器使用 New Bing?

作者:明明如月学长, CSDN 博客专家,蚂蚁集团高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《EffectiveJava》独家解析》专栏作者。 热门文章推荐…

[世界读书日] 最好的书,都在博雅之中

今天是世界读书日(4月23日),还是谈谈读书。 我很少看到有人说读书不好的,但很少看到有人爱读书,也很少看到有人读到了好书。 好书、好读书、读好书,都是很稀缺的。 一、好书的作用 基本上,我们遇…