Sulu 图像格式变化始终存储在本地,即使主图像存储在 S3 上也是如此

Sulu image format variations always stored locally even when master image stored on S3

我们已将 Sulu 配置为将上传的媒体文件存储在 S3 中,但是当生成各种图像尺寸和格式时(根据 /config/image-formats.xml 中指定的图像格式)生成的文件是存储在 /public/uploads/media

的本地服务器上

我们应该如何配置它以将生成的变体也存储在 S3 上?

这是config/packages/sulu-media.yaml:

services:
    # Overwrite adapter creation due to error: "mime_content_type(): stream does not support seeking"
    # https://github.com/sulu/sulu/issues/5468
    sulu_media.storage.s3.adapter:
        class: League\Flysystem\AwsS3v3\AwsS3Adapter
        arguments:
            - '@sulu_media.storage.s3.client'
            - '%sulu_media.media.storage.s3.bucket_name%'
            - '%sulu_media.media.storage.s3.path_prefix%'
            - []
            - false

sulu_media:
    storage: local
    storages:
        s3:
            key: '%env(AWS_S3_KEY)%'
            secret: '%env(AWS_S3_SECRET)%'
            bucket_name: '%env(AWS_S3_BUCKET)%'
            path_prefix: 'sulu-media/%kernel.environment%'
            region: '%env(AWS_REGION)%'
            arguments:
                use_path_style_endpoint: true
                bucket_endpoint: false

这是config/packages/prod/sulu_media.yaml

sulu_media:
    storage: s3

简答

图像格式不保存在 S3 中,因为它们是根据请求生成的,并且 S3 和其他媒体存储不能用作反向代理。所以你需要配置一个自己的反向代理来缓存生成的图像并禁用图像格式的本地保存。

长答案

图像格式和媒体存储在 Sulu 中是不同的东西。在下载 PDF 文件或原始大图像文件时不需要快速响应的地方。嵌入网站的图片需要快速响应。

关于 Sulu 中图像格式的最重要说明是它们是在请求时生成的。因此,如果您上传图像,则不会生成任何图像格式。图像格式只有在真正使用时才会生成。这意味着还需要调用 Sulu 运行 的本地 url 来生成图像格式。

所以如果我们在我们的树枝中嵌入以下内容:

<img src="{{ media.thumbnails['50x50'] }}" alt="{{ media.title }}">

如示例中所示,在您的网络服务器上调用了 /uploads/media/50x50/1-image.jpg url。然后您的网络服务器将在 public/uploads/media/50x50/1-image.jpg 中查找该文件,如果它不存在 public/index.php 将在 sulu 运行 中调用。这请求了 sulu 媒体流控制器并将生成请求图像格式。此过程还将生成然后图像格式为 public/uploads/media/50x50/1-image.jpg。所以下次调用图像格式 url 时,网络服务器将直接从文件系统中 return 图像。这是某种真正低级的反向代理机制。

这里是图片表示:

所以我们现在到了重要的关键字“反向代理”。由于 S3 不能用作反向代理或反向代理缓存,因此 S3 配置对图像格式没有任何影响。因此,如果您只有一个多服务器设置,这基本上没有问题,因为图像格式将在每台服务器上快速生成和提供。但是如果你在云设置中,你会丢失这个本地生成的文件,你需要找到另一种方式来缓存这些图像,否则重新启动服务器可能会在再次生成每种图像格式时杀死服务器。

一些云提供商在这里非常容易配置。例如,在 google 云中,您只需为 /uploads/media CDN 设置所需的内容,然后图像将缓存在 google CDN 缓存中,因此可以通过以下方式禁用 sulu 本地缓存:

sulu_media:
    format_cache:
         save: false

!!重要的是,如果您不确定是否配置了其他反向代理,请不要禁用此缓存,如上所述,始终触发图像生成可能会杀死您的服务器。

正如您提到的 Amazon S3,我认为您可以使用 cloudflare 或亚马逊提供的 CDN 服务为 uploads/media 配置一些反向缓存。还有其他第三方服务,如 enter link description here 是为这种缓存机制构建的。

您可能知道问自己如何在没有外部服务的情况下自行缓存图像。大多数情况下,这里最简单的方法就是使用配置了的 nginx 反向代理机制和缓存。

proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=my_cache:16m max_size=16g inactive=180d use_temp_path=off;

server {
    root /usr/share/nginx/html;

    location / {
        index index.html;
    }

    location /uploads/media {
        proxy_cache my_cache;
        proxy_pass {{ backend.uri }};
        proxy_ignore_headers "Set-Cookie";
        proxy_ignore_headers Cache-Control;
        proxy_cache_valid 200 365d;

        add_header X-Cache-Status $upstream_cache_status;

        add_header Cache-Control "public, max-age=31536000, immutable";
   }
}