diff --git a/CHANGELOG.md b/CHANGELOG.md index 798636f8..be88c45f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - (pro) Add the [hashsum](https://docs.imgproxy.net/latest/usage/processing#hashsum) processing and info options. - (pro) Add the [calc_hashsums](https://docs.imgproxy.net/latest/usage/getting_info#calc-hashsums) info option. - (pro) Add the [IMGPROXY_VIDEO_THUMBNAIL_TILE_AUTO_KEYFRAMES](https://docs.imgproxy.net/latest/configuration/options#IMGPROXY_VIDEO_THUMBNAIL_TILE_AUTO_KEYFRAMES) config. +- (docker) Add lambda adapter to the Docker image. ### Change - Allow relative values for `gravity` and `watermark` offsets. @@ -12,6 +13,7 @@ - Allow `IMGPROXY_TTL` to be zero. - Don't set `Expires` HTTP header as it is ignored if the `Cache-Control` header is set. - Don't log health-check requests and responses. +- Enforce `IMGPROXY_WORKERS=1` when running in AWS Lambda. - (pro) If the `step` argument of the `video_thumbnail_tile` is negative, calculate `step` automatically. ### Fix diff --git a/config/config.go b/config/config.go index 08e6ca9f..8f5da9ed 100644 --- a/config/config.go +++ b/config/config.go @@ -402,8 +402,15 @@ func Configure() error { configurators.Int(&KeepAliveTimeout, "IMGPROXY_KEEP_ALIVE_TIMEOUT") configurators.Int(&ClientKeepAliveTimeout, "IMGPROXY_CLIENT_KEEP_ALIVE_TIMEOUT") configurators.Int(&DownloadTimeout, "IMGPROXY_DOWNLOAD_TIMEOUT") - configurators.Int(&Workers, "IMGPROXY_CONCURRENCY") - configurators.Int(&Workers, "IMGPROXY_WORKERS") + + if lambdaFn := os.Getenv("AWS_LAMBDA_FUNCTION_NAME"); len(lambdaFn) > 0 { + Workers = 1 + log.Info("AWS Lambda environment detected, setting workers to 1") + } else { + configurators.Int(&Workers, "IMGPROXY_CONCURRENCY") + configurators.Int(&Workers, "IMGPROXY_WORKERS") + } + configurators.Int(&RequestsQueueSize, "IMGPROXY_REQUESTS_QUEUE_SIZE") configurators.Int(&MaxClients, "IMGPROXY_MAX_CLIENTS") diff --git a/docker/Dockerfile b/docker/Dockerfile index 8b861a69..115b6200 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -35,6 +35,9 @@ COPY --from=0 /usr/local/lib /usr/local/lib COPY docker/entrypoint.sh /usr/local/bin/ +# AWS Lambda adapter +COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.7.2 /lambda-adapter /opt/extensions/lambda-adapter + COPY NOTICE /usr/local/share/doc/imgproxy/ ENV VIPS_WARNING=0 diff --git a/vips/vips.go b/vips/vips.go index 23ba6e3c..642792b7 100644 --- a/vips/vips.go +++ b/vips/vips.go @@ -24,6 +24,7 @@ import ( "github.com/imgproxy/imgproxy/v3/ierrors" "github.com/imgproxy/imgproxy/v3/imagedata" "github.com/imgproxy/imgproxy/v3/imagetype" + "github.com/imgproxy/imgproxy/v3/imath" "github.com/imgproxy/imgproxy/v3/metrics/cloudwatch" "github.com/imgproxy/imgproxy/v3/metrics/datadog" "github.com/imgproxy/imgproxy/v3/metrics/newrelic" @@ -71,7 +72,14 @@ func Init() error { C.vips_cache_set_max_mem(0) C.vips_cache_set_max(0) - C.vips_concurrency_set(1) + if lambdaFn := os.Getenv("AWS_LAMBDA_FUNCTION_NAME"); len(lambdaFn) > 0 { + // Set vips concurrency level to GOMAXPROCS if we are running in AWS Lambda + // since each function processes only one request at a time + // so we can use all available CPU cores + C.vips_concurrency_set(C.int(imath.Max(1, runtime.GOMAXPROCS(0)))) + } else { + C.vips_concurrency_set(1) + } if len(os.Getenv("IMGPROXY_VIPS_LEAK_CHECK")) > 0 { C.vips_leak_set(C.gboolean(1))