asilgag/aws-s3-incremental-deployer

AWS S3 的增量和高性能原子部署

v2.0.1 2024-03-08 09:30 UTC

This package is auto-updated.

Last update: 2024-09-08 13:22:49 UTC


README

AWS S3 的增量和高性能原子部署。

  • 增量:使用快速差异算法,此包仅根据文件内容上传更改的文件。
  • 原子:尽管 AWS S3 不支持原子性,但此包以最优化方式执行上传,几乎达到相同的结果。
  • 高性能:更新包含 10 万个文件的网站通常在 ~10 秒内完成部署

为什么不使用 aws s3 sync --delete

aws s3 sync --delete 使用两个指标来决定是否从源同步到目标

  • 文件大小
  • 时间戳

这在大多数情况下都很好用,但当你正在部署由像 Gatsby 这样的静态站点生成器生成的网站时则不行。Gatsby 在每次构建时都会重新生成所有文件,因此 aws s3 sync --delete 会上传所有文件,因为它们都是“新的”。

与此相反,此包使用更智能(且更快)的策略:它比较文件内容以决定是否同步。因此,如果你的网站包含数千个文件,但只有 4 个文件已更改,则此包只会更新这 4 个文件。

安装

composer require asilgag/aws-s3-incremental-deployer

依赖项

此包对 Unix shell 的使用非常密集。以下 Unix 命令必须存在,以便此包按预期工作

  • aws (AWS CLI)
  • find
  • sort
  • xargs
  • sha1sum

因此,此包在非 Unix 操作系统(Windows 等)上无法工作。

ACL 权限

执行部署的用户必须授予以下 ACL 权限

  • 读取
  • 写入
  • 读取_ACP

增量部署

此包不使用 "aws s3 sync" 命令来同步本地文件夹到存储桶,而是使用不同的策略。

它使用 Unix 命令 sha1sum 获取本地文件夹中所有文件的校验和,然后将其与存储在存储桶中的上次部署版本进行比较。然后,它检测哪些文件是新的、已编辑或已删除,并以最“原子”的方式处理上传

  • 首先,新资产和页面
  • 其次,更新的资产和页面
  • 第三,主页

你应该使用具有适当缓存策略的 CDN(CloudFront、Akamai 等),以确保在上传期间不会有人访问网站的损坏版本。

用法

use Asilgag\Aws\S3\AwsS3IncrementalDeployer;
use Asilgag\Aws\S3\Logger\MultiLogger;

// Use any PSR-3 compatible logger
$multiLogger = new MultiLogger('/path/to/log/file', TRUE);

// Create a AwsS3IncrementalDeployer object and configure its behaviour.
$deployer = new AwsS3IncrementalDeployer($multiLogger);

// Optional. Define an array of relative paths that shouldn't be uploaded.
$deployer->setExcludedPaths(['relative/path/to/exclude/in/all/cases/*']);

// Optional. Add options to the "aws" part of the command (--region, --profile, etc)
$deployer->getAwsCli()->getAwsOptions()->add('--region eu-east-1');

// Optional. Set environment for the command.
$deployer->getAwsCli()->setEnvironment('AWS_ACCESS_KEY_ID', '***');
$deployer->getAwsCli()->setEnvironment('AWS_SECRET_ACCESS_KEY', '***');

// Execute deploy operation.
try {
   $deployer->deploy('/path/to/local/site', 'bucket-name');
}
catch (RuntimeException $e) {
   // Do some logging
}