From e405f0a57fe411444a953a78ff06fa5204a99d60 Mon Sep 17 00:00:00 2001 From: Mike Little Date: Thu, 8 May 2025 17:39:15 +0100 Subject: [PATCH 1/2] Limit container memory Work in progress Implement a default memory limit for containers if one is not specified. For now it applies the same limit across all services. But as enhanced-search now specifies its own docker-compose config, that is not affected by this. The es contaainer has a memry limit but the kibana container does not. Similarly, the proxy container is independent and does not specify a limit. Implemements https://github.com/humanmade/altis-local-server/issues/818 --- .../class-docker-compose-generator.php | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/inc/composer/class-docker-compose-generator.php b/inc/composer/class-docker-compose-generator.php index f8b2477..f495e0d 100644 --- a/inc/composer/class-docker-compose-generator.php +++ b/inc/composer/class-docker-compose-generator.php @@ -225,20 +225,40 @@ protected function get_php_reusable() : array { return $services; } + /** + * Default memory limit for all services that don't specify one. + * + * @param $args + * + * @return array + */ + protected function apply_service_defaults( $args ) : array { + $mem_limit = getenv( 'LS_MEM_LIMIT' ) ?: '1g'; + foreach ( $args as $service => $service_args ) { + if ( isset( $service_args['mem_limit'] ) ) { + continue; + } + $args[ $service ]['mem_limit'] = $mem_limit; + } + + return $args; + } + + /** * Get the PHP container service. * * @return array */ protected function get_service_php() : array { - return [ + return $this->apply_service_defaults( [ 'php' => array_merge( [ 'container_name' => "{$this->project_name}-php", ], $this->get_php_reusable() ), - ]; + ] ); } /** @@ -253,7 +273,7 @@ protected function get_service_nodejs() : array { $package_json = json_decode( file_get_contents( "{$config['nodejs']['path']}/package.json" ), true ); $version = $package_json['engines']['node'] ?? '20'; - return [ + return $this->apply_service_defaults( [ 'nodejs' => [ 'image' => "node:{$version}-bookworm-slim", 'container_name' => "{$this->project_name}-nodejs", @@ -282,7 +302,7 @@ protected function get_service_nodejs() : array { 'ALTIS_ENVIRONMENT_TYPE' => 'local', ], ], - ]; + ] ); } /** @@ -291,7 +311,7 @@ protected function get_service_nodejs() : array { * @return array */ protected function get_service_webgrind() : array { - return [ + return $this->apply_service_defaults( [ 'webgrind' => [ 'container_name' => "{$this->project_name}-webgrind", 'image' => 'wodby/webgrind:1.9', @@ -318,7 +338,7 @@ protected function get_service_webgrind() : array { 'WEBGRIND_DEFAULT_TIMEZONE' => 'UTC', ], ], - ]; + ] ); } /** @@ -327,7 +347,7 @@ protected function get_service_webgrind() : array { * @return array */ protected function get_service_cavalcade() : array { - return [ + return $this->apply_service_defaults( [ 'cavalcade' => array_merge( [ 'container_name' => "{$this->project_name}-cavalcade", @@ -339,7 +359,7 @@ protected function get_service_cavalcade() : array { ], $this->get_php_reusable() ), - ]; + ] ); } /** @@ -352,7 +372,7 @@ protected function get_service_nginx() : array { $domains = $config['domains'] ?? []; $domains = $domains ? ',' . implode( ',', $domains ) : ''; - return [ + return $this->apply_service_defaults( [ 'nginx' => [ 'image' => 'humanmade/altis-local-server-nginx:3.6.0', 'container_name' => "{$this->project_name}-nginx", @@ -387,7 +407,7 @@ protected function get_service_nginx() : array { 'PHP_PUBLIC_POOL_ENABLE_RATE_LIMIT' => 'false', ], ], - ]; + ] ); } /** @@ -396,7 +416,7 @@ protected function get_service_nginx() : array { * @return array */ protected function get_service_redis() : array { - return [ + return $this->apply_service_defaults( [ 'redis' => [ 'image' => 'redis:7.0-alpine', 'container_name' => "{$this->project_name}-redis", @@ -404,7 +424,7 @@ protected function get_service_redis() : array { '6379', ], ], - ]; + ] ); } /** @@ -433,7 +453,7 @@ protected function get_service_db() : array { $image = $version_map[ $version ]; - return [ + return $this->apply_service_defaults( [ 'db' => [ 'image' => $image, // Suppress mysql_native_password deprecation warning @@ -468,7 +488,7 @@ protected function get_service_db() : array { 'retries' => 10, ], ], - ]; + ] ); } /** @@ -477,7 +497,7 @@ protected function get_service_db() : array { * @return array */ protected function get_service_s3() : array { - return [ + return $this->apply_service_defaults( [ 's3' => [ 'image' => 'minio/minio:RELEASE.2021-09-18T18-09-59Z', 'container_name' => "{$this->project_name}-s3", @@ -560,7 +580,7 @@ protected function get_service_s3() : array { ], 'entrypoint' => "/bin/sh -c \"mc mirror --watch --overwrite -a local/{$this->bucket_name} /content\"", ], - ]; + ] ); } /** @@ -569,7 +589,7 @@ protected function get_service_s3() : array { * @return array */ protected function get_service_tachyon() : array { - return [ + return $this->apply_service_defaults( [ 'tachyon' => [ 'image' => 'humanmade/tachyon:v3.0.7', 'container_name' => "{$this->project_name}-tachyon", @@ -596,7 +616,7 @@ protected function get_service_tachyon() : array { "proxy:s3-{$this->hostname}", ], ], - ]; + ] ); } /** @@ -605,7 +625,7 @@ protected function get_service_tachyon() : array { * @return array */ protected function get_service_mailhog() : array { - return [ + return $this->apply_service_defaults( [ 'mailhog' => [ 'image' => 'cd2team/mailhog:latest', 'container_name' => "{$this->project_name}-mailhog", @@ -627,7 +647,7 @@ protected function get_service_mailhog() : array { 'MH_UI_WEB_PATH' => 'mailhog', ], ], - ]; + ] ); } /** @@ -636,7 +656,7 @@ protected function get_service_mailhog() : array { * @return array */ protected function get_service_analytics() : array { - return [ + return $this->apply_service_defaults( [ 'cognito' => [ 'container_name' => "{$this->project_name}-cognito", 'ports' => [ @@ -678,7 +698,7 @@ protected function get_service_analytics() : array { 'INDEX_ROTATION' => 'OneDay', ], ], - ]; + ] ); } /** @@ -687,7 +707,7 @@ protected function get_service_analytics() : array { * @return array */ protected function get_service_xray() : array { - return [ + return $this->apply_service_defaults( [ 'xray' => [ 'image' => 'amazon/aws-xray-daemon:3.3.3', 'container_name' => "{$this->project_name}-xray", @@ -700,7 +720,7 @@ protected function get_service_xray() : array { 'AWS_REGION' => 'us-east-1', ], ], - ]; + ] ); } /** @@ -751,7 +771,6 @@ public function get_array() : array { // Default compose configuration. $config = [ - // 'version' => '2.5', 'services' => $services, 'networks' => [ 'default' => null, From 5578704d89f012739bc3a2beaf37d87c8d8409c9 Mon Sep 17 00:00:00 2001 From: Mike Little Date: Tue, 16 Sep 2025 12:34:32 +0100 Subject: [PATCH 2/2] Fix linting issue. Add memory limit for proxy container. --- docker/proxy.yml | 1 + inc/composer/class-docker-compose-generator.php | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/proxy.yml b/docker/proxy.yml index 2159f2c..4a8cfd9 100644 --- a/docker/proxy.yml +++ b/docker/proxy.yml @@ -4,6 +4,7 @@ services: - proxy image: traefik:1.7 container_name: altis-proxy + mem_limit: 128m volumes: - "$PWD/altis/local-server/docker/conf/traefik.toml:/etc/traefik/traefik.toml" - "$PWD/ssl-cert.pem:/etc/traefik/ssl-cert.pem" diff --git a/inc/composer/class-docker-compose-generator.php b/inc/composer/class-docker-compose-generator.php index 7a52733..59482e8 100644 --- a/inc/composer/class-docker-compose-generator.php +++ b/inc/composer/class-docker-compose-generator.php @@ -224,11 +224,11 @@ protected function get_php_reusable() : array { /** * Default memory limit for all services that don't specify one. * - * @param $args + * @param array $args The services array to apply defaults to. * - * @return array + * @return array The modified array. */ - protected function apply_service_defaults( $args ) : array { + protected function apply_service_defaults( array $args ) : array { $mem_limit = getenv( 'LS_MEM_LIMIT' ) ?: '1g'; foreach ( $args as $service => $service_args ) { if ( isset( $service_args['mem_limit'] ) ) { @@ -240,7 +240,6 @@ protected function apply_service_defaults( $args ) : array { return $args; } - /** * Get the PHP container service. *