diff --git a/docs/deploy/docker.mdx b/docs/deploy/docker.mdx
index 8d2035a30..fab9a5328 100644
--- a/docs/deploy/docker.mdx
+++ b/docs/deploy/docker.mdx
@@ -29,11 +29,14 @@ You should consider deploying using Docker when:
Bref helps you deploy using Docker images by offering base images that work on AWS Lambda. Here is an example of a Dockerfile you can use:
```dockerfile filename="Dockerfile"
-FROM bref/php-84-fpm:2
+FROM bref/php-84:3
# Copy the source code in the image
COPY . /var/task
+# In this example we're serving an HTTP application with php-fpm
+ENV BREF_RUNTIME=fpm
+
# Configure the handler file (the entrypoint that receives all HTTP requests)
CMD ["public/index.php"]
```
@@ -43,14 +46,14 @@ The `CMD` instruction let us specify the entrypoint that will handle all request
Always specify the major version of the Bref image you want to use. That avoids breaking changes when a new major version is released.
- For example `bref/php-84-fpm:3` points to Bref v3.
+ For example `bref/php-84:3` points to Bref v3.
-Bref offers the following base images:
+The `ENV BREF_RUNTIME=fpm` let's us specify which [runtime](../runtimes.mdx) to use. As a reminder, Bref offers the following runtimes:
-- `bref/php-xx-fpm:3`: PHP-FPM to run HTTP applications
-- `bref/php-xx-console:3`: to run PHP CLI commands
-- `bref/php-xx:3`: to run [PHP functions](../runtimes/function.mdx)
+- `fpm`: [uses PHP-FPM to serve web applications](../runtimes/fpm-runtime.mdx)
+- `function`: [to run PHP code](../runtimes/function.mdx)
+- `console`: [to run CLI commands](../runtimes/console.mdx)
The `CMD` instruction in `Dockerfile` must contain a valid JSON array. This is why you must escape any `\` character. This is important for PHP class names, for example when using Laravel Octane:
@@ -65,10 +68,10 @@ Bref offers the following base images:
You can enable additional PHP extensions by pulling them from [Bref Extra Extensions](https://github.com/brefphp/extra-php-extensions):
```dockerfile filename="Dockerfile" {3-4}
-FROM bref/php-84-fpm:2
+FROM bref/php-84:3
-COPY --from=bref/extra-redis-php-84:1 /opt /opt
-COPY --from=bref/extra-gmp-php-84:1 /opt /opt
+COPY --from=bref/extra-redis-php-84:3 /opt /opt
+COPY --from=bref/extra-gmp-php-84:3 /opt /opt
COPY . /var/task
@@ -76,9 +79,9 @@ CMD ["public/index.php"]
```
- Like the Bref images, always specify the major version of the Bref Extra Extensions images: `bref/extra-*:1` points to Bref Extra Extensions v1.
+ Like the Bref images, always specify the major version of the Bref Extra Extensions images: `bref/extra-*:3` points to Bref Extra Extensions v3.
- Note that Bref v2 is compatible with Bref Extra Extensions v1 (yes that's confusing, sorry about that, we will fix that in Bref v3 to have matching versions).
+ Note that Bref v3 is compatible with Bref Extra Extensions v3.
## Deployment
@@ -126,6 +129,6 @@ The `/tmp` folder will always be empty on cold starts. Avoid writing content to
## Docker Registry
-AWS Lambda only support AWS ECR as the source location for Docker images.
+AWS Lambda only supports AWS ECR as the source location for Docker images.
AWS Lambda will use the image digest as the unique identifier. This means that even if you overwrite the exact same tag on ECR, your lambda will still run the previous image code until you actually redeploy using the new image.
diff --git a/docs/local-development.mdx b/docs/local-development.mdx
index b5af0d95c..aee7bc96a 100644
--- a/docs/local-development.mdx
+++ b/docs/local-development.mdx
@@ -42,7 +42,7 @@ version: "3.5"
services:
app:
- image: bref/php-84-fpm-dev:3
+ image: bref/php-84-dev:3
ports: [ '8000:8000' ]
volumes:
- .:/var/task
@@ -62,7 +62,7 @@ The application will be available at [http://localhost:8000/](http://localhost:8
The `HANDLER` environment variable lets you define which PHP file will be handling all HTTP requests. This should be the same handler that you have defined in `serverless.yml` for your HTTP function.
-> Currently, the Docker image support only one PHP handler. If you have multiple HTTP functions in `serverless.yml`, you can duplicate the service in `docker-compose.yml` to have one container per lambda function.
+> Currently, the Docker image supports only one PHP handler. If you have multiple HTTP functions in `serverless.yml`, you can duplicate the service in `docker-compose.yml` to have one container per lambda function.
### Read-only filesystem
diff --git a/docs/local-development/event-driven-functions.mdx b/docs/local-development/event-driven-functions.mdx
index f7debd20a..58e4249b1 100644
--- a/docs/local-development/event-driven-functions.mdx
+++ b/docs/local-development/event-driven-functions.mdx
@@ -88,8 +88,8 @@ If you want to run your function in Docker:
```bash
$ docker run --rm -it --entrypoint= -v $(PWD):/var/task:ro bref/php-84:3 vendor/bin/bref-local my-function.php
-# You can also use the `dev` images for a simpler command (and Xdebug and Blackfire in the image):
-$ docker run --rm -it -v $(PWD):/var/task:ro bref/php-84-fpm-dev:3 vendor/bin/bref-local my-function.php
+# You can also use the `dev` images for a simpler command (and Xdebug in the image):
+$ docker run --rm -it -v $(PWD):/var/task:ro bref/php-84-dev:3 vendor/bin/bref-local my-function.php
```
You can also use Docker Compose, like described in [Local development for HTTP applications](../local-development.mdx):
@@ -98,7 +98,7 @@ You can also use Docker Compose, like described in [Local development for HTTP a
version: "3.5"
services:
app:
- image: bref/php-84-fpm-dev:3
+ image: bref/php-84-dev:3
volumes:
- .:/var/task
```
diff --git a/docs/upgrading/v3.mdx b/docs/upgrading/v3.mdx
index 4c7a2dd14..cbbf83344 100644
--- a/docs/upgrading/v3.mdx
+++ b/docs/upgrading/v3.mdx
@@ -23,20 +23,194 @@ Then run `composer update bref/bref --with-all-dependencies`.
If you use the [Bref Extra extensions](https://github.com/brefphp/extra-php-extensions), you also need to update the `bref/extra-php-extensions` package to version `^3.0`.
+## Container image changes
+
+If you deploy using [container images](../deploy/docker.mdx), you must update your `Dockerfile`.
+
+First, change the major version of the Bref base image:
+
+```diff filename="Dockerfile"
+- FROM bref/php-84-fpm:2
++ FROM bref/php-84-fpm:3
+
+# ...
+```
+
+Since Bref container images have been merged into a single `bref/php-xx` image, the following images don't exist anymore: `bref/php-xx-fpm` and `bref/php-xx-console`.
+
+You must replace the base image to `bref/php-xx` when needed and define the `BREF_RUNTIME` environment variable:
+
+```diff filename="Dockerfile"
+FROM bref/php-84:3
+
++ ENV BREF_RUNTIME=function
+
+# ...
+```
+
+or
+
+```diff filename="Dockerfile"
+- FROM bref/php-84-fpm:3
++ FROM bref/php-84:3
+
++ ENV BREF_RUNTIME=fpm
+
+# ...
+```
+
+or
+
+```diff filename="Dockerfile"
+- FROM bref/php-84-console:3
++ FROM bref/php-84:3
+
++ ENV BREF_RUNTIME=console
+
+# ...
+```
+
+Separately, if you use the `bref/php-84-fpm-dev` image for local development, you need to update its name and version:
+
+```diff filename="Dockerfile"
+- FROM bref/php-84-fpm-dev:2
++ FROM bref/php-84-dev:3
+
+# ...
+```
+
+The rest works as usual.
+
## Smaller breaking changes that might impact you
The changes below should not impact the majority of users. However, if you are using any of these features, you might need to update your code.
### Changed the AWS account ID for AWS Lambda layers
-The AWS account ID where Bref layers are published is different for v3. That lets us keep releasing Bref v2 layers without mixing up layer numbers.
-
-For Bref v3 layers, you need to use `873528684822` as the AWS account number (instead of `534081306603`).
+The AWS account ID where Bref layers are published is different for v3. That lets us keep releasing Bref v2 layers without mixing up layer numbers. If you reference the layers via their full ARN, you must update the Bref AWS account number to `873528684822` (instead of `534081306603`).
```bash
# Bref v2 layer
-arn:aws:lambda:eu-west-2:534081306603:layer:php-84:xxx
+arn:aws:lambda:us-east-1:534081306603:layer:php-84:xxx
# Bref v3 layer
-arn:aws:lambda:eu-west-2:873528684822:layer:php-84:xxx
+arn:aws:lambda:us-east-1:873528684822:layer:php-84:xxx
```
+
+**If you don't know what that means**, you're likely not concerned by this change.
+
+If you're not sure, search for `534081306603` in your codebase and replace it with the new account ID.
+
+### AWS Lambda layers have been merged into a single layer
+
+If you configure the `runtime` in your functions using the following syntax:
+
+```yml filename="serverless.yml"
+functions:
+ web:
+ # ...
+ runtime: php-84-fpm # or `php-xx` or `php-xx-console`
+```
+
+✅ **you have nothing to do**, your configuration is valid for Bref v3.
+
+However, if you specify AWS Lambda layers explicitly in `serverless.yml` (or through any other deployment method), for example:
+
+```yml filename="serverless.yml"
+functions:
+ web:
+ # ...
+ runtime: provided.al2
+ layers:
+ - ${bref:layer.php-84}
+ # or:
+ - ${bref:layer.php-84-fpm}
+ # or:
+ layers:
+ - 'arn:aws:lambda:us-east-1:534081306603:layer:php-84:21'
+```
+
+Then you must update your configuration.
+
+Under the hood, **all layers have been merged into one**, i.e. `php-xx-fpm` and `php-xx-console` have been merged into `php-xx` to make Bref layers simpler. The runtime is now defined via an environment variable that is automatically injected by Bref when using the `runtime:` syntax.
+
+- **Option 1**: switch to using the simpler `runtime:` syntax.
+
+ Before:
+
+ ```yml filename="serverless.yml"
+ functions:
+ web:
+ # ...
+ runtime: provided.al2
+ layers:
+ - ${bref:layer.php-84}
+ # or:
+ - ${bref:layer.php-84-fpm}
+ # or:
+ - ${bref:layer.php-84-console}
+ ```
+
+ After:
+
+ ```yml filename="serverless.yml"
+ functions:
+ web:
+ # ...
+ runtime: php-84
+ # or:
+ runtime: php-84-fpm
+ # or:
+ runtime: php-84-console
+ ```
+
+ The examples above assume you are using PHP 8.4 (`php-84`) but you can replace `84` with another PHP version.
+
+ If you include additional layers, you can keep them without issues, for example:
+
+ ```yml filename="serverless.yml"
+ functions:
+ web:
+ # ...
+ runtime: php-84-fpm
+ layers:
+ - ${bref-extra:imagick-php-84}
+ ```
+
+- **Option 2**: change the layer names and define the `BREF_RUNTIME` environment variable.
+
+ Before:
+
+ ```yml filename="serverless.yml"
+ functions:
+ web:
+ # ...
+ runtime: provided.al2
+ layers:
+ - ${bref:layer.php-84}
+ # or:
+ - ${bref:layer.php-84-fpm}
+ # or:
+ - ${bref:layer.php-84-console}
+ ```
+
+ After:
+
+ ```yml filename="serverless.yml"
+ functions:
+ web:
+ # ...
+ runtime: provided.al2
+ layers:
+ - ${bref:layer.php-84}
+ environment:
+ # ...
+ BREF_RUNTIME: function # for ${bref:layer.php-xx}
+ # or
+ BREF_RUNTIME: fpm # for ${bref:layer.php-xx-fpm}
+ # or
+ BREF_RUNTIME: console # ${bref:layer.php-xx-console}
+ ```
+
+ The examples above assume you are using PHP 8.4 (`php-84`) but you can replace `84` with another PHP version.
+
diff --git a/index.js b/index.js
index 1518f3e6f..a86b4a158 100644
--- a/index.js
+++ b/index.js
@@ -173,21 +173,67 @@ class ServerlessPlugin {
* Process the `php-xx` runtimes to turn them into `provided.al2` runtimes + Bref layers.
*/
processPhpRuntimes() {
- const includeBrefLayers = (runtime, existingLayers, isArm) => {
- let layerName = runtime;
+ const includeBrefLayers = (existingLayers, phpVersion, isArm) => {
+ let layerName = 'php-' + phpVersion;
// Automatically use ARM layers if the function is deployed to an ARM architecture
if (isArm) {
layerName = 'arm-' + layerName;
}
- if (layerName.endsWith('-console')) {
- layerName = layerName.substring(0, layerName.length - '-console'.length);
- existingLayers.unshift(this.getLayerArn('console', this.provider.getRegion()));
- existingLayers.unshift(this.getLayerArn(layerName, this.provider.getRegion()));
- } else {
- existingLayers.unshift(this.getLayerArn(layerName, this.provider.getRegion()));
- }
+ existingLayers.unshift(this.getLayerArn(layerName, this.provider.getRegion()));
return existingLayers;
}
+ /**
+ * @param {string} runtime
+ * @return {string|undefined}
+ */
+ const runtimeStringToRuntimeClass = (runtime) => {
+ if (! runtime.startsWith('php-')) {
+ return undefined;
+ }
+ if (runtime.endsWith('-console')) {
+ return 'Bref\\ConsoleRuntime\\Main';
+ }
+ if (runtime.endsWith('-fpm')) {
+ return 'Bref\\FpmRuntime\\Main';
+ }
+ return 'Bref\\FunctionRuntime\\Main';
+ };
+ const configureFunctionRuntime = (f) => {
+ // `php-\d\d(-fpm|console)?`
+ const fullRuntimeString = f.runtime || config.provider.runtime;
+ if (! fullRuntimeString || ! fullRuntimeString.startsWith('php-')) {
+ return;
+ }
+ const phpVersion = fullRuntimeString.substring('php-'.length).split('-')[0];
+ const runtimeClass = runtimeStringToRuntimeClass(fullRuntimeString);
+ if (! runtimeClass) return;
+
+ // The logic here is a bit custom:
+ // If there are layers on the function, we preserve them
+ let existingLayers = f.layers || []; // make sure it's an array
+ // Else, we merge with the layers defined at the root.
+ // Indeed, SF overrides the layers defined at the root with the ones defined on the function.
+ if (existingLayers.length === 0) {
+ // for some reason it's not always an array
+ existingLayers = Array.from(config.provider.layers || []);
+ }
+
+ f.layers = includeBrefLayers(
+ existingLayers,
+ phpVersion,
+ f.architecture === 'arm64' || (isArmGlobally && !f.architecture),
+ );
+ f.runtime = 'provided.al2';
+ // Add the `BREF_RUNTIME` environment variable
+ // to let the function know which runtime it is using
+ // (this is used by the Bref runtime)
+ if (!f.environment) {
+ f.environment = {};
+ }
+ if (!f.environment.BREF_RUNTIME) {
+ f.environment.BREF_RUNTIME = runtimeClass;
+ }
+ }
const config = this.serverless.service;
const isArmGlobally = config.provider.architecture === 'arm64';
@@ -195,40 +241,15 @@ class ServerlessPlugin {
// Check functions config
for (const f of Object.values(config.functions || {})) {
- if (
- (f.runtime && this.runtimes.includes(f.runtime)) ||
- (!f.runtime && isBrefRuntimeGlobally)
- ) {
- // The logic here is a bit custom:
- // If there are layers on the function, we preserve them
- let existingLayers = f.layers || []; // make sure it's an array
- // Else, we merge with the layers defined at the root.
- // Indeed, SF overrides the layers defined at the root with the ones defined on the function.
- if (existingLayers.length === 0) {
- // for some reason it's not always an array
- existingLayers = Array.from(config.provider.layers || []);
- }
-
- f.layers = includeBrefLayers(
- f.runtime || config.provider.runtime,
- existingLayers,
- f.architecture === 'arm64' || (isArmGlobally && !f.architecture),
- );
- f.runtime = 'provided.al2';
- }
+ configureFunctionRuntime(f);
}
// Check Lift constructs config
for (const construct of Object.values(this.serverless.configurationInput.constructs || {})) {
if (construct.type !== 'queue' && construct.type !== 'webhook') continue;
const f = construct.type === 'queue' ? construct.worker : construct.authorizer;
- if (f && (f.runtime && this.runtimes.includes(f.runtime) || !f.runtime && isBrefRuntimeGlobally) ) {
- f.layers = includeBrefLayers(
- f.runtime || config.provider.runtime,
- f.layers || [], // make sure it's an array
- f.architecture === 'arm64' || (isArmGlobally && !f.architecture),
- );
- f.runtime = 'provided.al2';
+ if (f) {
+ configureFunctionRuntime(f);
}
}
}
diff --git a/src/FpmRuntime/FpmHandler.php b/src/FpmRuntime/FpmHandler.php
index caa1ef145..597f006b9 100644
--- a/src/FpmRuntime/FpmHandler.php
+++ b/src/FpmRuntime/FpmHandler.php
@@ -76,8 +76,19 @@ public function start(): void
/**
* --nodaemonize: we want to keep control of the process
* --force-stderr: force logs to be sent to stderr, which will allow us to send them to CloudWatch
+ * TODO set `max_execution_time` to the timeout of the Lambda function?
*/
- $resource = @proc_open(['php-fpm', '--nodaemonize', '--force-stderr', '--fpm-config', $this->configFile], [], $pipes);
+ $resource = @proc_open([
+ 'php-fpm',
+ '--nodaemonize',
+ '--force-stderr',
+ '--fpm-config',
+ $this->configFile,
+ // Override ini settings to force disabling display_errors
+ // Displaying errors in the HTTP response is a security risk
+ '-d',
+ 'display_errors=0',
+ ], [], $pipes);
if (! is_resource($resource)) {
throw new RuntimeException('PHP-FPM failed to start');
diff --git a/src/FpmRuntime/Main.php b/src/FpmRuntime/Main.php
index 2eb7c6a0c..adf570311 100755
--- a/src/FpmRuntime/Main.php
+++ b/src/FpmRuntime/Main.php
@@ -16,10 +16,6 @@ class Main
{
public static function run(): void
{
- // In the FPM runtime process (our process) we want to log all errors and warnings
- ini_set('display_errors', '1');
- error_reporting(E_ALL);
-
ColdStartTracker::init();
LazySecretsLoader::loadSecretEnvironmentVariables();
diff --git a/tests/PluginTest.php b/tests/PluginTest.php
index 4da695d1c..debcae0a5 100644
--- a/tests/PluginTest.php
+++ b/tests/PluginTest.php
@@ -2,6 +2,9 @@
namespace Bref\Test;
+use Bref\ConsoleRuntime\Main as ConsoleMain;
+use Bref\FpmRuntime\Main as FpmMain;
+use Bref\FunctionRuntime\Main as FunctionMain;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;
use Symfony\Component\Yaml\Yaml;
@@ -12,26 +15,24 @@ public function test the plugin adds the layers(): void
{
$output = $this->slsPrint('serverless.yml');
- self::assertFunction($output['functions']['function'], [
+ self::assertFunction($output['functions']['function'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
]);
- self::assertFunction($output['functions']['fpm'], [
- 'arn:aws:lambda:us-east-1:873528684822:layer:php-83-fpm:',
+ self::assertFunction($output['functions']['fpm'], FpmMain::class, [
+ 'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
]);
- self::assertFunction($output['functions']['console'], [
+ self::assertFunction($output['functions']['console'], ConsoleMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
- 'arn:aws:lambda:us-east-1:873528684822:layer:console:',
]);
- self::assertFunction($output['functions']['function-arm'], [
+ self::assertFunction($output['functions']['function-arm'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
]);
- self::assertFunction($output['functions']['fpm-arm'], [
- 'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83-fpm:',
+ self::assertFunction($output['functions']['fpm-arm'], FpmMain::class, [
+ 'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
]);
- self::assertFunction($output['functions']['console-arm'], [
+ self::assertFunction($output['functions']['console-arm'], ConsoleMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
- 'arn:aws:lambda:us-east-1:873528684822:layer:console:',
]);
}
@@ -39,10 +40,10 @@ public function test the plugin adds the layers when the runtime is se
{
$output = $this->slsPrint('serverless-runtime-root.yml');
- self::assertFunction($output['functions']['function'], [
+ self::assertFunction($output['functions']['function'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
]);
- self::assertFunction($output['functions']['function-arm'], [
+ self::assertFunction($output['functions']['function-arm'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
]);
}
@@ -51,21 +52,21 @@ public function test the plugin doesnt break layers added separately(): v
{
$output = $this->slsPrint('serverless-with-layers.yml');
- self::assertFunction($output['functions']['function'], [
+ self::assertFunction($output['functions']['function'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
'arn:aws:lambda:us-east-1:1234567890:layer:foo:1',
]);
- self::assertFunction($output['functions']['function-arm'], [
+ self::assertFunction($output['functions']['function-arm'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
'arn:aws:lambda:us-east-1:1234567890:layer:foo:1',
]);
- self::assertFunction($output['functions']['function-with-layers'], [
+ self::assertFunction($output['functions']['function-with-layers'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
// This function doesn't have the `foo` layer because that's how SF works:
// layers in the function completely override the layers in the root
'arn:aws:lambda:us-east-1:1234567890:layer:bar:1',
]);
- self::assertFunction($output['functions']['function-arm-with-layers'], [
+ self::assertFunction($output['functions']['function-arm-with-layers'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
// This function doesn't have the `foo` layer because that's how SF works:
// layers in the function completely override the layers in the root
@@ -77,21 +78,21 @@ public function test the plugin doesnt break layers added separately wit
{
$output = $this->slsPrint('serverless-runtime-root-with-layers.yml');
- self::assertFunction($output['functions']['function'], [
+ self::assertFunction($output['functions']['function'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
'arn:aws:lambda:us-east-1:1234567890:layer:foo:1',
]);
- self::assertFunction($output['functions']['function-arm'], [
+ self::assertFunction($output['functions']['function-arm'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
'arn:aws:lambda:us-east-1:1234567890:layer:foo:1',
]);
- self::assertFunction($output['functions']['function-with-layers'], [
+ self::assertFunction($output['functions']['function-with-layers'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:php-83:',
// This function doesn't have the `foo` layer because that's how SF works:
// layers in the function completely override the layers in the root
'arn:aws:lambda:us-east-1:1234567890:layer:bar:1',
]);
- self::assertFunction($output['functions']['function-arm-with-layers'], [
+ self::assertFunction($output['functions']['function-arm-with-layers'], FunctionMain::class, [
'arn:aws:lambda:us-east-1:873528684822:layer:arm-php-83:',
// This function doesn't have the `foo` layer because that's how SF works:
// layers in the function completely override the layers in the root
@@ -111,9 +112,10 @@ private function slsPrint(string $configFile): array
return Yaml::parse($process->getOutput());
}
- private static function assertFunction(array $config, array $layers): void
+ private static function assertFunction(array $config, string $brefRuntime, array $layers): void
{
self::assertEquals('provided.al2', $config['runtime']);
+ self::assertEquals($brefRuntime, $config['environment']['BREF_RUNTIME']);
self::assertCount(count($layers), $config['layers'], sprintf('Expected %d layers, got %d: %s', count($layers), count($config['layers']), json_encode($config['layers'], JSON_THROW_ON_ERROR)));
foreach ($layers as $index => $layer) {
self::assertStringStartsWith($layer, $config['layers'][$index]);
diff --git a/utils/layers.json/update.php b/utils/layers.json/update.php
index c7a71bbee..1f261efbd 100644
--- a/utils/layers.json/update.php
+++ b/utils/layers.json/update.php
@@ -14,18 +14,11 @@
const LAYER_NAMES = [
'php-84',
- 'php-84-fpm',
'php-83',
- 'php-83-fpm',
'php-82',
- 'php-82-fpm',
'arm-php-84',
- 'arm-php-84-fpm',
'arm-php-83',
- 'arm-php-83-fpm',
'arm-php-82',
- 'arm-php-82-fpm',
- 'console',
];
$regions = json_decode(file_get_contents(__DIR__ . '/regions.json'), true);