winter / wn-vapor-plugin
一个简单的插件,使在Laravel Vapor上运行Winter CMS变得更加容易
Requires
- laravel/vapor-core: ^2.21
- predis/predis: ^1.1
- winter/wn-driveraws-plugin: dev-main
This package is auto-updated.
Last update: 2024-09-07 16:32:42 UTC
README
简化在Laravel Vapor上运行Winter CMS项目的过程
此插件可通过Composer进行安装。
composer require winter/wn-vapor-plugin
安装
要开始在Vapor上运行Winter CMS,您需要按照以下步骤操作:
- 注册一个AWS账户
- 注册一个Laravel Vapor账户
- 安装Vapor CLI:
composer global require laravel/vapor-cli
- 认证Vapor CLI:
vapor login
- 在您的Winter CMS项目中安装此插件:
composer require winter/wn-vapor-plugin
- 创建
vapor.yml
文件:vapor init
(当被问及是否要安装laravel/vapor-core包时,请回答“NO”) - 修改
vapor.yml
- 将
npm run build
替换为php artisan mix:compile --production --stop-on-error
- 在资产编译后,在
build
后添加以下代码:- 'php artisan vapor:mirror "public" --copy --verbose --ignore "/modules\/.*\/.*\.less$/" --ignore "/\/src\//" --ignore "/(.*).php$/" --ignore "/(.*).md$/" --ignore "/.htaccess/" --ignore "/.DS_Store/" --ignore "/\/storage\//'
- 在
storage: my-bucket-name
中添加一个桶名称,以便Vapor为您设置桶(建议您配置桶为私有设置,并使用CloudFront分发从桶中提供公共资产。有关更多信息,请参阅配置S3 & CloudFront)
- 将
- 将
plugins/winter/vapor/stubs/httpHandler.php
和plugins/winter/vapor/stubs/runtime.php
文件复制到您的项目根目录。
配置S3 & CloudFront
Vapor将自动为您创建一个S3桶,但它将是公开可访问的。建议您配置该桶为私有,并设置一个CloudFront分发以从该桶提供公共资产。
为此,请在Vapor为您创建桶后执行以下步骤:
配置CloudFront
为了配置CloudFront,您需要创建一个源访问标识符(OAI)和一个CloudFront分发。
- 转到CloudFront控制台,创建一个新的分发
- 将S3桶作为源域名选择
- 留空源路径
- 保留名称为默认值
- 设置源访问为传统访问标识符
- 创建一个新的OAI
- 保留名称为默认值或更改它
- 将“启用源盾”设置为否(https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html?icmpid=docs_cf_help_panel)
- 路径模式:默认
- 自动压缩对象 - 是
- 查看器协议策略 - 将HTTP重定向到HTTPS
- 允许的HTTP方法 - GET, HEAD
- 限制查看器访问 - 否
- 缓存策略和源请求策略
- 缓存策略 - 缓存优化
- 源请求策略 - 留空
- 响应头策略 - 简单CORS
- 响应头策略 - 留空
- 平滑流媒体 - 否
- 字段级加密 - 保持空白,上传将通过流上传功能处理,并且将使用稍后创建的特定存储桶 IAM 用户和政策签名的 URL
- 启用实时日志 - 否
- Web 应用程序防火墙 - 否,会增加额外成本,并且我们只允许读操作
- 价格类别 - 任何相关的类别,但对于全球受众,请保留使用所有边缘位置
- 备用域名(CNAME)- 现在保持空白或设置为您的域名(例如 cdn.example.com),但您需要确保您在 Vapor 中添加该域名并请求证书
- 自定义 SSL 证书 - 保持空白
- 支持的 HTTP 版本 - 启用 HTTP/2 和 HTTP/3
- 默认根对象 - 保持空白
- 标准日志 - 关闭
- IPv6 - 开启
- 描述 - 设置您想要的任何内容(我建议备用域名,例如 cdn.example.com)
配置 S3 存储桶
为了使用 Winter CMS 时 S3 的最大安全性和可靠性,存储桶应按以下方式配置
锁定存储桶
- 现在跳过启用版本控制,调整大小的图片可能难以处理
- 转到存储桶的权限选项卡
- 将“阻止所有公共访问”设置为“开启”
- 将策略设置为以下内容(使用您自己的 bucketName 和您之前创建的 CloudFront OAI 中的 oai)
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity {oai}" }, "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::{bucketName}/media/*", "arn:aws:s3:::{bucketName}/uploads/public/*", "arn:aws:s3:::{bucketName}/public/*", "arn:aws:s3:::{bucketName}/resized/*" ] } ] }
- Set the CORS configuration to the following:
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "HEAD", "GET", "PUT", "POST" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [ "ETag" ] } ]
为应用程序创建一个 IAM 用户以访问该特定存储桶
- 创建一个名为 s3-$bucketName-iam-policy 的新 IAM 策略,内容如下(替换
bucketName
的值为您自己的值)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::{bucketName}" ] }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:GetObjectAcl", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::{bucketName}/*" ] } ] }
- 创建一个名为 s3-$bucketName-iam-user 的新 IAM 用户
- 将 s3-$bucketName-iam-policy 绑定到用户
- 为用户创建一个新的访问密钥并记下它(用户详情页面 -> 安全凭证选项卡 -> 访问密钥部分)
- 运行在 AWS 计算服务上的应用程序
- 为其提供描述(s3-$bucket-iam-access-key)
- 将访问密钥 ID 复制到 .env 作为 AWS_S3_ACCESS_KEY_ID
- 将秘密访问密钥复制到 .env 作为 AWS_S3_SECRET_ACESS_KEY
- 将区域、存储桶名称和 CF URL 分别复制到 .env 作为 AWS_S3_REGION、AWS_S3_BUCKET 和 AWS_S3_URL
- 确保 filesystems.php -> s3 已设置为使用新环境变量
- 确保 cms.php 已设置为
'path' => env('FILESYSTEM_DISK', 'local') === 'local' ? '/storage/app/uploads' : env('AWS_S3_URL') . '/uploads',
- 将环境变量复制到 Vapor 仪表板
常见错误
Winter.Redirect 规则不一致
启用“高级”中的“缓存重定向”设置以在 Redis 中存储重定向
ERROR: "在 PhpRedisConnector.php 行 161: 连接被拒绝”
您当前正在尝试使用 Redis(用于数据库、缓存、会话等),但您没有在您构建的机器上运行它
ERROR: "在 PhpRedisConnector.php 行 81: 类 "Redis" 未找到" - 您的配置将 phpredis 作为 Redis 的驱动程序,但您的构建机器上没有安装 phpredis 扩展
您的构建机器需要安装 PHPRedis 扩展或通过 composer 在项目中安装 predis
pecl install redis
或composer require predis/predis
ERROR: "命令
npm ci && php artisan mix:compile --production --stop-on-error && rm -rf node_modules
失败。退出代码:127(命令未找到)” - 您的构建机器上没有安装 node / npm
您的构建机器需要安装 node / npm
brew install node
(在 MacOS 上)
ERROR: "在 DynamoDbStore.php 行 451: DynamoDb 不支持清除整个表。请创建一个新的表。”
DynamoDB 不适合作为 Winter CMS 的缓存存储;请使用 Redis。在 https://vapor.laravel.net.cn/app/caches 或通过运行 vapor cache nameofcache
创建缓存
错误:"您的应用程序超过了 AWS Lambda 允许的最大大小。"
AWS Lambda 限制了上传的大小,上传大小限制为 50MB(压缩)和 250MB(未压缩)。
在 composer.json
文件中的一些 dev-dependencies 可能会导致上传超出限制(例如:faker、phpunit、phpstan 等)。在 vapor.yml
文件中的 composer install
步骤上设置 --no-dev
标志(或者将它们包含在发送到 artisan vapor:mirror public
的忽略模式中来防止这些被包含在上传中)。
如果这还不够,尝试切换到使用部署的 Docker 运行时(将限制增加到 10GB,并允许完全控制可用的 PHP 扩展)。
使用说明
配置
Winter CMS 默认在配置文件中包含了大多数所需的环境变量,但如果您已经自定义了它们,或者正在将 Vapor 支持添加到现有项目中,您需要确保以下配置项设置为使用环境变量
由 Winter.Vapor Plugin.php 自动添加
app.tempPath
:应设置为env('APP_TEMP_PATH', null)
,对于使用服务器上临时存储的任何内容都是必需的(例如文件上传)。app.trustedProxies
:建议设置为**
,这样您的应用程序就可以正确识别发出请求的客户端的真实 IP 地址,尽管客户端可能位于多层代理之后。cms.databaseTemplates
:应设置为true
,以确保数据库用于存储 CMS 模板,因为 Vapor 上文件系统是只读的。filesystems.disks.s3.visibility
:如果使用带有锁定 S3 存储桶的 CloudFront,应设置为private
,以确保正确的 ACL。filesystems.disks.s3.stream_uploads
:应设置为true
或至少env('AWS_S3_STREAM_UPLOADS', false)
,以确保文件上传被流式传输到 S3,而不是首先尝试将其上传到 Vapor PHP 服务器,因为 Vapor PHP 服务器的请求大小硬限制很低,这会导致性能下降和较大的上传失败。
需要手动验证
app.asset_url
:应设置为env('ASSET_URL', null)
,这是从 Vapor 为您配置的 CDN 加载资源时必需的,因为资源文件不是直接在 Vapor 服务器上提供的。app.trustedHosts
:建议在此处添加每个有效主机的条目。filesystems.disks.s3.url
:应设置为env('AWS_URL')
,以确保使用正确的 URL 访问 S3 上的文件,尤其是在您在 S3 前使用 CloudFront CDN 的情况下。
所需的 Vapor 重写
Laravel Vapor 默认加载自己的引导文件,然后直接加载 Laravel 的引导程序。这阻止了 Winter 的引导程序首先运行,因此导致 Winter 提供的重写不再生效。要修复此问题,将 /stubs
文件夹中的 httpHandler.php
和 runtime.php
文件复制到项目根目录。
缓存
使用 Redis,因为 DynamoDB 目前不支持在 Laravel 中刷新,这是通过 Winter 后端进行缓存清理所必需的。
webmanifest 和 .json 文件
如果这些文件不是从您的 CDN 服务器上提供,您需要为 .webmanifest
和 .json
文件创建手动路由。有关更多详细信息,请参阅 https://github.com/laravel/vapor-cli/commit/30f55eff6ebc22e30796e9e033536894a28b0824#commitcomment-46973546。Winter.Favicon 的未来版本可能具有潜在性。
许可
本软件包受 MIT 许可证 的许可。
鸣谢
本插件基于Jack Wilkinson为在Laravel Vapor上运行SpatialMedia.io所做的工作开发。经过打磨,现已作为Winter CMS的第一个插件在Winter命名空间下发布,并由Winter CMS团队维护。自此之后,该插件得到了进一步改进,并被用于在Laravel Vapor上运行WinterCMS.com。
如果您想为此插件的开发贡献力量,请随意提交问题或拉取请求到该插件的仓库:https://github.com/wintercms/wn-vapor-plugin
如果您想支持Winter CMS,请访问WinterCMS.com