From 08f59107541f59987dbf887cc7f41a5cf49f462e Mon Sep 17 00:00:00 2001 From: Jonas Date: Thu, 16 Apr 2026 13:58:21 +0200 Subject: [PATCH 1/5] feat/FPM-configuration-based-on-resources-calculation --- api/v1/store_env.go | 52 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/api/v1/store_env.go b/api/v1/store_env.go index b9a9000..c227005 100644 --- a/api/v1/store_env.go +++ b/api/v1/store_env.go @@ -2,6 +2,7 @@ package v1 import ( "fmt" + "math" "slices" "strconv" @@ -143,7 +144,30 @@ func (s *Store) getSessionCache() []corev1.EnvVar { } } -func (f *FPMSpec) getFPMConfiguration() []corev1.EnvVar { +func (f *FPMSpec) getFPMConfiguration(s *Store) []corev1.EnvVar { + const ( + startServersRatio = 0.25 + minSpareServersRatio = 0.2 + maxSpareServersRatio = 0.375 + memoryPerChildMiB = 80 //Every PHP-FPM process in an empty shop uses 70.6MiB + ) + + memoryLimitMiB := s.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024) + maxChildren := int(math.Round(float64(memoryLimitMiB / memoryPerChildMiB))) + startServers := int(math.Round(float64(maxChildren) * startServersRatio)) + minSpare := int(math.Round(float64(maxChildren) * minSpareServersRatio)) + maxSpare := int(math.Round(float64(maxChildren)*maxSpareServersRatio) + 1) + + fmt.Println("Calculated FPM configuration based on memory limit:") + fmt.Printf("Memory Limit (MiB): %d\n", memoryLimitMiB) + fmt.Printf("Max Children: %d\n", maxChildren) + fmt.Printf("Start Servers: %d\n", startServers) + fmt.Printf("Min Spare Servers: %d\n", minSpare) + fmt.Printf("Max Spare Servers: %d\n", maxSpare) + fmt.Printf("mode: %d\n", f.ProcessManagement) + + // The formulas are based on CPU cores and MiB, not Kubernetes base units. + if f.ProcessManagement != "dynamic" { return []corev1.EnvVar{ { @@ -165,19 +189,19 @@ func (f *FPMSpec) getFPMConfiguration() []corev1.EnvVar { }, { Name: "FPM_PM_MAX_CHILDREN", - Value: strconv.Itoa(f.MaxChildren), + Value: strconv.Itoa(maxChildren), }, { Name: "FPM_PM_START_SERVERS", - Value: strconv.Itoa(f.StartServers), + Value: strconv.Itoa(startServers), }, { Name: "FPM_PM_MIN_SPARE_SERVERS", - Value: strconv.Itoa(f.MinSpareServers), + Value: strconv.Itoa(minSpare), }, { Name: "FPM_PM_MAX_SPARE_SERVERS", - Value: strconv.Itoa(f.MaxSpareServers), + Value: strconv.Itoa(maxSpare), }, } } @@ -186,6 +210,22 @@ func (f *FPMSpec) getFPMConfiguration() []corev1.EnvVar { Name: "FPM_PM", Value: f.ProcessManagement, }, + { + Name: "FPM_PM_MAX_CHILDREN", + Value: strconv.Itoa(maxChildren), + }, + { + Name: "FPM_PM_START_SERVERS", + Value: strconv.Itoa(startServers), + }, + { + Name: "FPM_PM_MIN_SPARE_SERVERS", + Value: strconv.Itoa(minSpare), + }, + { + Name: "FPM_PM_MAX_SPARE_SERVERS", + Value: strconv.Itoa(maxSpare), + }, } } @@ -548,7 +588,7 @@ func (s *Store) GetEnv() []corev1.EnvVar { c = append(c, s.getWorker()...) c = append(c, s.getOpensearch()...) c = append(c, s.getFastly()...) - c = append(c, s.Spec.FPM.getFPMConfiguration()...) + c = append(c, s.Spec.FPM.getFPMConfiguration(s)...) for _, obj2 := range s.Spec.Container.ExtraEnvs { if i := slices.IndexFunc(c, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }); i > -1 { From 9b701d2bf197a7b0c1d435f835d7e62b11188c49 Mon Sep 17 00:00:00 2001 From: Jonas Date: Tue, 21 Apr 2026 13:27:29 +0200 Subject: [PATCH 2/5] feat: distinguish betwen env's --- api/v1/store_env.go | 31 ++++++++++++----------------- api/v1/store_test.go | 18 ++++++++--------- internal/controller/store_status.go | 2 +- internal/cronjob/scheduled_task.go | 2 +- internal/deployment/admin.go | 2 +- internal/deployment/storefront.go | 2 +- internal/deployment/worker.go | 2 +- internal/job/command.go | 2 +- internal/job/migration.go | 2 +- internal/job/setup.go | 2 +- internal/pod/debug.go | 2 +- 11 files changed, 31 insertions(+), 36 deletions(-) diff --git a/api/v1/store_env.go b/api/v1/store_env.go index c227005..081218f 100644 --- a/api/v1/store_env.go +++ b/api/v1/store_env.go @@ -144,30 +144,25 @@ func (s *Store) getSessionCache() []corev1.EnvVar { } } -func (f *FPMSpec) getFPMConfiguration(s *Store) []corev1.EnvVar { +func (f *FPMSpec) getFPMConfiguration(s *Store, env string) []corev1.EnvVar { const ( startServersRatio = 0.25 minSpareServersRatio = 0.2 maxSpareServersRatio = 0.375 memoryPerChildMiB = 80 //Every PHP-FPM process in an empty shop uses 70.6MiB ) + var memoryLimitMiB, maxSpare, minSpare, startServers, maxChildren int - memoryLimitMiB := s.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024) - maxChildren := int(math.Round(float64(memoryLimitMiB / memoryPerChildMiB))) - startServers := int(math.Round(float64(maxChildren) * startServersRatio)) - minSpare := int(math.Round(float64(maxChildren) * minSpareServersRatio)) - maxSpare := int(math.Round(float64(maxChildren)*maxSpareServersRatio) + 1) - - fmt.Println("Calculated FPM configuration based on memory limit:") - fmt.Printf("Memory Limit (MiB): %d\n", memoryLimitMiB) - fmt.Printf("Max Children: %d\n", maxChildren) - fmt.Printf("Start Servers: %d\n", startServers) - fmt.Printf("Min Spare Servers: %d\n", minSpare) - fmt.Printf("Max Spare Servers: %d\n", maxSpare) - fmt.Printf("mode: %d\n", f.ProcessManagement) - + if env == "admin" { + memoryLimitMiB = int(s.Spec.AdminDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024)) + } else { + memoryLimitMiB = int(s.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024)) + } + maxChildren = int(math.Round(float64(memoryLimitMiB / memoryPerChildMiB))) + startServers = int(math.Round(float64(maxChildren) * startServersRatio)) + minSpare = int(math.Round(float64(maxChildren) * minSpareServersRatio)) + maxSpare = int(math.Round(float64(maxChildren)*maxSpareServersRatio) + 1) // The formulas are based on CPU cores and MiB, not Kubernetes base units. - if f.ProcessManagement != "dynamic" { return []corev1.EnvVar{ { @@ -481,7 +476,7 @@ func (s *Store) getFastly() []corev1.EnvVar { return envVars } -func (s *Store) GetEnv() []corev1.EnvVar { +func (s *Store) GetEnv(env string) []corev1.EnvVar { var appUrl string if s.Spec.Network.AppURLHost == "" { appUrl = fmt.Sprintf("https://%s", s.Spec.Network.Host) @@ -588,7 +583,7 @@ func (s *Store) GetEnv() []corev1.EnvVar { c = append(c, s.getWorker()...) c = append(c, s.getOpensearch()...) c = append(c, s.getFastly()...) - c = append(c, s.Spec.FPM.getFPMConfiguration(s)...) + c = append(c, s.Spec.FPM.getFPMConfiguration(s, env)...) for _, obj2 := range s.Spec.Container.ExtraEnvs { if i := slices.IndexFunc(c, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }); i > -1 { diff --git a/api/v1/store_test.go b/api/v1/store_test.go index 10361fc..4406437 100644 --- a/api/v1/store_test.go +++ b/api/v1/store_test.go @@ -353,7 +353,7 @@ func TestEnvMerge(t *testing.T) { }, }, } - env := baseContainer.GetEnv() + env := baseContainer.GetEnv("store") for _, envVar := range env { if envVar.Name == "APP_URL" { require.Equal(t, "overwritten", envVar.Value) @@ -377,7 +377,7 @@ func TestAppCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundCacheType, foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_CACHE_TYPE" { @@ -411,7 +411,7 @@ func TestAppCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundHost, foundPort, foundIndex, foundURL bool for _, envVar := range env { if envVar.Name == "K8S_CACHE_HOST" { @@ -451,7 +451,7 @@ func TestSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundHandler, foundRedisDSN bool for _, envVar := range env { if envVar.Name == "PHP_SESSION_HANDLER" { @@ -481,7 +481,7 @@ func TestSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundHandler, foundSavePath bool for _, envVar := range env { if envVar.Name == "PHP_SESSION_HANDLER" { @@ -511,7 +511,7 @@ func TestNewSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_REDIS_SESSION_DSN" { @@ -536,7 +536,7 @@ func TestNewSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_REDIS_SESSION_DSN" { @@ -561,7 +561,7 @@ func TestWorkerRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundDSN, foundConsumerName bool for _, envVar := range env { if envVar.Name == "MESSENGER_TRANSPORT_DSN" { @@ -590,7 +590,7 @@ func TestWorkerRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv() + env := store.GetEnv("store") var foundDSN, foundConsumerName bool for _, envVar := range env { if envVar.Name == "MESSENGER_TRANSPORT_DSN" { diff --git a/internal/controller/store_status.go b/internal/controller/store_status.go index 3918838..f751f5e 100644 --- a/internal/controller/store_status.go +++ b/internal/controller/store_status.go @@ -127,7 +127,7 @@ func (r *StoreReconciler) reconcileCRStatus( func printWarningForEnvs(ctx context.Context, store *v1.Store) { l := logging.FromContext(ctx) - envs := store.GetEnv() + envs := store.GetEnv("store") // TODO: this check doesn't make sense, because the overwriten envs are in there for _, obj2 := range store.Spec.Container.ExtraEnvs { if slices.ContainsFunc(envs, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }) { diff --git a/internal/cronjob/scheduled_task.go b/internal/cronjob/scheduled_task.go index 53307a5..c9dc375 100644 --- a/internal/cronjob/scheduled_task.go +++ b/internal/cronjob/scheduled_task.go @@ -57,7 +57,7 @@ func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { Image: store.Spec.Container.Image, Command: []string{"sh", "-c"}, Args: []string{store.Spec.ScheduledTask.Command}, - Env: store.GetEnv(), + Env: store.GetEnv("store"), Resources: store.Spec.Container.Resources, // Add Resources here }) diff --git a/internal/deployment/admin.go b/internal/deployment/admin.go index 323e840..11a104c 100644 --- a/internal/deployment/admin.go +++ b/internal/deployment/admin.go @@ -76,7 +76,7 @@ func AdminDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.AdminDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from AdminDeploymentContainer - envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv("admin"), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ LivenessProbe: &corev1.Probe{ diff --git a/internal/deployment/storefront.go b/internal/deployment/storefront.go index ba99004..05fd892 100644 --- a/internal/deployment/storefront.go +++ b/internal/deployment/storefront.go @@ -80,7 +80,7 @@ func StorefrontDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.StorefrontDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from StorefrontDeploymentContainer - envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv("store"), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: DEPLOYMENT_STOREFRONT_CONTAINER_NAME, diff --git a/internal/deployment/worker.go b/internal/deployment/worker.go index 4bffca1..730e3de 100644 --- a/internal/deployment/worker.go +++ b/internal/deployment/worker.go @@ -76,7 +76,7 @@ func WorkerDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.WorkerDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from WorkerDeploymentContainer - envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv("store"), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: appName, diff --git a/internal/job/command.go b/internal/job/command.go index 0fb66ab..b403eef 100644 --- a/internal/job/command.go +++ b/internal/job/command.go @@ -114,7 +114,7 @@ func getJobSpec(store v1.Store, ex v1.StoreExec, labels map[string]string) batch containerSpec := store.Spec.Container.DeepCopy() sharedProcessNamespace := true - envs := util.MergeEnv(store.GetEnv(), ex.Spec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv("store"), ex.Spec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_COMMAND, diff --git a/internal/job/migration.go b/internal/job/migration.go index 3683e14..efd364a 100644 --- a/internal/job/migration.go +++ b/internal/job/migration.go @@ -51,7 +51,7 @@ func MigrationJob(store v1.Store) *batchv1.Job { annotations["shop.shopware.com/store.newImage"] = containerSpec.Image // Merge containerSpec.ExtraEnvs to override with merged values from MigrationJobContainer - envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv("store"), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_MIGRATION_JOB, diff --git a/internal/job/setup.go b/internal/job/setup.go index 53456c8..3307478 100644 --- a/internal/job/setup.go +++ b/internal/job/setup.go @@ -41,7 +41,7 @@ func SetupJob(store v1.Store) *batchv1.Job { // Use util function for annotations annotations := util.GetDefaultContainerAnnotations(CONTAINER_NAME_SETUP_JOB, store, store.Spec.SetupJobContainer.Annotations) - envs := append(store.GetEnv(), + envs := append(store.GetEnv("store"), corev1.EnvVar{ Name: "INSTALL_ADMIN_PASSWORD", ValueFrom: &corev1.EnvVarSource{ diff --git a/internal/pod/debug.go b/internal/pod/debug.go index c88b16e..925b400 100644 --- a/internal/pod/debug.go +++ b/internal/pod/debug.go @@ -60,7 +60,7 @@ func DebugPod(store v1.Store, storeDebugInstance v1.StoreDebugInstance) *corev1. // we don't need the liveness and readiness probe to make sure that the container always starts Image: containerImage, // Use custom image if provided ImagePullPolicy: store.Spec.Container.ImagePullPolicy, - Env: store.GetEnv(), + Env: store.GetEnv("store"), VolumeMounts: store.Spec.Container.VolumeMounts, Ports: ports, Resources: store.Spec.Container.Resources, From 52cb2022cada872c070c17013e83a2c7a0ae0620 Mon Sep 17 00:00:00 2001 From: Jonas Date: Tue, 21 Apr 2026 14:33:26 +0200 Subject: [PATCH 3/5] fix: type Component --- api/v1/store_env.go | 15 +++++++++++---- api/v1/store_test.go | 18 +++++++++--------- internal/controller/store_status.go | 2 +- internal/cronjob/scheduled_task.go | 2 +- internal/deployment/admin.go | 2 +- internal/deployment/storefront.go | 2 +- internal/deployment/worker.go | 2 +- internal/job/command.go | 2 +- internal/job/migration.go | 2 +- internal/job/setup.go | 2 +- internal/pod/debug.go | 2 +- 11 files changed, 29 insertions(+), 22 deletions(-) diff --git a/api/v1/store_env.go b/api/v1/store_env.go index 081218f..f83e039 100644 --- a/api/v1/store_env.go +++ b/api/v1/store_env.go @@ -9,6 +9,13 @@ import ( corev1 "k8s.io/api/core/v1" ) +type Component string + +const ( + AdminComponent Component = "admin" + StoreComponent Component = "store" +) + // TODO: If building more than one instance print a warning for the cache to use // redis func (s *Store) getAppCache() []corev1.EnvVar { @@ -144,7 +151,7 @@ func (s *Store) getSessionCache() []corev1.EnvVar { } } -func (f *FPMSpec) getFPMConfiguration(s *Store, env string) []corev1.EnvVar { +func (f *FPMSpec) getFPMConfiguration(s *Store, component Component) []corev1.EnvVar { const ( startServersRatio = 0.25 minSpareServersRatio = 0.2 @@ -153,7 +160,7 @@ func (f *FPMSpec) getFPMConfiguration(s *Store, env string) []corev1.EnvVar { ) var memoryLimitMiB, maxSpare, minSpare, startServers, maxChildren int - if env == "admin" { + if component == AdminComponent { memoryLimitMiB = int(s.Spec.AdminDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024)) } else { memoryLimitMiB = int(s.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024)) @@ -476,7 +483,7 @@ func (s *Store) getFastly() []corev1.EnvVar { return envVars } -func (s *Store) GetEnv(env string) []corev1.EnvVar { +func (s *Store) GetEnv(component Component) []corev1.EnvVar { var appUrl string if s.Spec.Network.AppURLHost == "" { appUrl = fmt.Sprintf("https://%s", s.Spec.Network.Host) @@ -583,7 +590,7 @@ func (s *Store) GetEnv(env string) []corev1.EnvVar { c = append(c, s.getWorker()...) c = append(c, s.getOpensearch()...) c = append(c, s.getFastly()...) - c = append(c, s.Spec.FPM.getFPMConfiguration(s, env)...) + c = append(c, s.Spec.FPM.getFPMConfiguration(s, component)...) for _, obj2 := range s.Spec.Container.ExtraEnvs { if i := slices.IndexFunc(c, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }); i > -1 { diff --git a/api/v1/store_test.go b/api/v1/store_test.go index 4406437..ab75122 100644 --- a/api/v1/store_test.go +++ b/api/v1/store_test.go @@ -353,7 +353,7 @@ func TestEnvMerge(t *testing.T) { }, }, } - env := baseContainer.GetEnv("store") + env := baseContainer.GetEnv(v1.StoreComponent) for _, envVar := range env { if envVar.Name == "APP_URL" { require.Equal(t, "overwritten", envVar.Value) @@ -377,7 +377,7 @@ func TestAppCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundCacheType, foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_CACHE_TYPE" { @@ -411,7 +411,7 @@ func TestAppCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundHost, foundPort, foundIndex, foundURL bool for _, envVar := range env { if envVar.Name == "K8S_CACHE_HOST" { @@ -451,7 +451,7 @@ func TestSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundHandler, foundRedisDSN bool for _, envVar := range env { if envVar.Name == "PHP_SESSION_HANDLER" { @@ -481,7 +481,7 @@ func TestSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundHandler, foundSavePath bool for _, envVar := range env { if envVar.Name == "PHP_SESSION_HANDLER" { @@ -511,7 +511,7 @@ func TestNewSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_REDIS_SESSION_DSN" { @@ -536,7 +536,7 @@ func TestNewSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_REDIS_SESSION_DSN" { @@ -561,7 +561,7 @@ func TestWorkerRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundDSN, foundConsumerName bool for _, envVar := range env { if envVar.Name == "MESSENGER_TRANSPORT_DSN" { @@ -590,7 +590,7 @@ func TestWorkerRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv("store") + env := store.GetEnv(v1.StoreComponent) var foundDSN, foundConsumerName bool for _, envVar := range env { if envVar.Name == "MESSENGER_TRANSPORT_DSN" { diff --git a/internal/controller/store_status.go b/internal/controller/store_status.go index f751f5e..73a3fbe 100644 --- a/internal/controller/store_status.go +++ b/internal/controller/store_status.go @@ -127,7 +127,7 @@ func (r *StoreReconciler) reconcileCRStatus( func printWarningForEnvs(ctx context.Context, store *v1.Store) { l := logging.FromContext(ctx) - envs := store.GetEnv("store") + envs := store.GetEnv(v1.StoreComponent) // TODO: this check doesn't make sense, because the overwriten envs are in there for _, obj2 := range store.Spec.Container.ExtraEnvs { if slices.ContainsFunc(envs, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }) { diff --git a/internal/cronjob/scheduled_task.go b/internal/cronjob/scheduled_task.go index c9dc375..36b2713 100644 --- a/internal/cronjob/scheduled_task.go +++ b/internal/cronjob/scheduled_task.go @@ -57,7 +57,7 @@ func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { Image: store.Spec.Container.Image, Command: []string{"sh", "-c"}, Args: []string{store.Spec.ScheduledTask.Command}, - Env: store.GetEnv("store"), + Env: store.GetEnv(v1.StoreComponent), Resources: store.Spec.Container.Resources, // Add Resources here }) diff --git a/internal/deployment/admin.go b/internal/deployment/admin.go index 11a104c..5a7c5e3 100644 --- a/internal/deployment/admin.go +++ b/internal/deployment/admin.go @@ -76,7 +76,7 @@ func AdminDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.AdminDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from AdminDeploymentContainer - envs := util.MergeEnv(store.GetEnv("admin"), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(v1.AdminComponent), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ LivenessProbe: &corev1.Probe{ diff --git a/internal/deployment/storefront.go b/internal/deployment/storefront.go index 05fd892..ee09444 100644 --- a/internal/deployment/storefront.go +++ b/internal/deployment/storefront.go @@ -80,7 +80,7 @@ func StorefrontDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.StorefrontDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from StorefrontDeploymentContainer - envs := util.MergeEnv(store.GetEnv("store"), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: DEPLOYMENT_STOREFRONT_CONTAINER_NAME, diff --git a/internal/deployment/worker.go b/internal/deployment/worker.go index 730e3de..91250cb 100644 --- a/internal/deployment/worker.go +++ b/internal/deployment/worker.go @@ -76,7 +76,7 @@ func WorkerDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.WorkerDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from WorkerDeploymentContainer - envs := util.MergeEnv(store.GetEnv("store"), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: appName, diff --git a/internal/job/command.go b/internal/job/command.go index b403eef..f05c5a0 100644 --- a/internal/job/command.go +++ b/internal/job/command.go @@ -114,7 +114,7 @@ func getJobSpec(store v1.Store, ex v1.StoreExec, labels map[string]string) batch containerSpec := store.Spec.Container.DeepCopy() sharedProcessNamespace := true - envs := util.MergeEnv(store.GetEnv("store"), ex.Spec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), ex.Spec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_COMMAND, diff --git a/internal/job/migration.go b/internal/job/migration.go index efd364a..6e9dc16 100644 --- a/internal/job/migration.go +++ b/internal/job/migration.go @@ -51,7 +51,7 @@ func MigrationJob(store v1.Store) *batchv1.Job { annotations["shop.shopware.com/store.newImage"] = containerSpec.Image // Merge containerSpec.ExtraEnvs to override with merged values from MigrationJobContainer - envs := util.MergeEnv(store.GetEnv("store"), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_MIGRATION_JOB, diff --git a/internal/job/setup.go b/internal/job/setup.go index 3307478..5a8d0c5 100644 --- a/internal/job/setup.go +++ b/internal/job/setup.go @@ -41,7 +41,7 @@ func SetupJob(store v1.Store) *batchv1.Job { // Use util function for annotations annotations := util.GetDefaultContainerAnnotations(CONTAINER_NAME_SETUP_JOB, store, store.Spec.SetupJobContainer.Annotations) - envs := append(store.GetEnv("store"), + envs := append(store.GetEnv(v1.StoreComponent), corev1.EnvVar{ Name: "INSTALL_ADMIN_PASSWORD", ValueFrom: &corev1.EnvVarSource{ diff --git a/internal/pod/debug.go b/internal/pod/debug.go index 925b400..a21d995 100644 --- a/internal/pod/debug.go +++ b/internal/pod/debug.go @@ -60,7 +60,7 @@ func DebugPod(store v1.Store, storeDebugInstance v1.StoreDebugInstance) *corev1. // we don't need the liveness and readiness probe to make sure that the container always starts Image: containerImage, // Use custom image if provided ImagePullPolicy: store.Spec.Container.ImagePullPolicy, - Env: store.GetEnv("store"), + Env: store.GetEnv(v1.StoreComponent), VolumeMounts: store.Spec.Container.VolumeMounts, Ports: ports, Resources: store.Spec.Container.Resources, From 8f3f7a6ead1dc958ee7e13aa61cc23caac3bdef5 Mon Sep 17 00:00:00 2001 From: Jonas Date: Thu, 23 Apr 2026 13:14:21 +0200 Subject: [PATCH 4/5] fix: code review changes --- api/v1/store.go | 2 +- api/v1/store_env.go | 58 ++++------------------------- api/v1/store_test.go | 18 ++++----- internal/controller/store_status.go | 2 +- internal/cronjob/scheduled_task.go | 2 +- internal/deployment/admin.go | 7 +++- internal/deployment/storefront.go | 7 +++- internal/deployment/util.go | 39 +++++++++++++++++++ internal/deployment/worker.go | 2 +- internal/job/command.go | 2 +- internal/job/migration.go | 2 +- internal/job/setup.go | 2 +- internal/pod/debug.go | 2 +- 13 files changed, 74 insertions(+), 71 deletions(-) diff --git a/api/v1/store.go b/api/v1/store.go index 6caa89d..520ed0a 100644 --- a/api/v1/store.go +++ b/api/v1/store.go @@ -341,7 +341,7 @@ type RedisSpec struct { } type FPMSpec struct { - // +kubebuilder:validation:Enum=static;dynamic;ondemand + // +kubebuilder:validation:Enum=static;dynamic;ondemand;operator // +kubebuilder:default=static ProcessManagement string `json:"processManagement"` diff --git a/api/v1/store_env.go b/api/v1/store_env.go index f83e039..ae90343 100644 --- a/api/v1/store_env.go +++ b/api/v1/store_env.go @@ -2,20 +2,12 @@ package v1 import ( "fmt" - "math" "slices" "strconv" corev1 "k8s.io/api/core/v1" ) -type Component string - -const ( - AdminComponent Component = "admin" - StoreComponent Component = "store" -) - // TODO: If building more than one instance print a warning for the cache to use // redis func (s *Store) getAppCache() []corev1.EnvVar { @@ -151,26 +143,8 @@ func (s *Store) getSessionCache() []corev1.EnvVar { } } -func (f *FPMSpec) getFPMConfiguration(s *Store, component Component) []corev1.EnvVar { - const ( - startServersRatio = 0.25 - minSpareServersRatio = 0.2 - maxSpareServersRatio = 0.375 - memoryPerChildMiB = 80 //Every PHP-FPM process in an empty shop uses 70.6MiB - ) - var memoryLimitMiB, maxSpare, minSpare, startServers, maxChildren int - - if component == AdminComponent { - memoryLimitMiB = int(s.Spec.AdminDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024)) - } else { - memoryLimitMiB = int(s.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value() / (1024 * 1024)) - } - maxChildren = int(math.Round(float64(memoryLimitMiB / memoryPerChildMiB))) - startServers = int(math.Round(float64(maxChildren) * startServersRatio)) - minSpare = int(math.Round(float64(maxChildren) * minSpareServersRatio)) - maxSpare = int(math.Round(float64(maxChildren)*maxSpareServersRatio) + 1) - // The formulas are based on CPU cores and MiB, not Kubernetes base units. - if f.ProcessManagement != "dynamic" { +func (f *FPMSpec) getFPMConfiguration() []corev1.EnvVar { + if f.ProcessManagement != "dynamic" && f.ProcessManagement != "operator" { return []corev1.EnvVar{ { Name: "FPM_PM", @@ -191,19 +165,19 @@ func (f *FPMSpec) getFPMConfiguration(s *Store, component Component) []corev1.En }, { Name: "FPM_PM_MAX_CHILDREN", - Value: strconv.Itoa(maxChildren), + Value: strconv.Itoa(f.MaxChildren), }, { Name: "FPM_PM_START_SERVERS", - Value: strconv.Itoa(startServers), + Value: strconv.Itoa(f.StartServers), }, { Name: "FPM_PM_MIN_SPARE_SERVERS", - Value: strconv.Itoa(minSpare), + Value: strconv.Itoa(f.MinSpareServers), }, { Name: "FPM_PM_MAX_SPARE_SERVERS", - Value: strconv.Itoa(maxSpare), + Value: strconv.Itoa(f.MaxSpareServers), }, } } @@ -212,22 +186,6 @@ func (f *FPMSpec) getFPMConfiguration(s *Store, component Component) []corev1.En Name: "FPM_PM", Value: f.ProcessManagement, }, - { - Name: "FPM_PM_MAX_CHILDREN", - Value: strconv.Itoa(maxChildren), - }, - { - Name: "FPM_PM_START_SERVERS", - Value: strconv.Itoa(startServers), - }, - { - Name: "FPM_PM_MIN_SPARE_SERVERS", - Value: strconv.Itoa(minSpare), - }, - { - Name: "FPM_PM_MAX_SPARE_SERVERS", - Value: strconv.Itoa(maxSpare), - }, } } @@ -483,7 +441,7 @@ func (s *Store) getFastly() []corev1.EnvVar { return envVars } -func (s *Store) GetEnv(component Component) []corev1.EnvVar { +func (s *Store) GetEnv() []corev1.EnvVar { var appUrl string if s.Spec.Network.AppURLHost == "" { appUrl = fmt.Sprintf("https://%s", s.Spec.Network.Host) @@ -590,7 +548,7 @@ func (s *Store) GetEnv(component Component) []corev1.EnvVar { c = append(c, s.getWorker()...) c = append(c, s.getOpensearch()...) c = append(c, s.getFastly()...) - c = append(c, s.Spec.FPM.getFPMConfiguration(s, component)...) + c = append(c, s.Spec.FPM.getFPMConfiguration()...) for _, obj2 := range s.Spec.Container.ExtraEnvs { if i := slices.IndexFunc(c, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }); i > -1 { diff --git a/api/v1/store_test.go b/api/v1/store_test.go index ab75122..10361fc 100644 --- a/api/v1/store_test.go +++ b/api/v1/store_test.go @@ -353,7 +353,7 @@ func TestEnvMerge(t *testing.T) { }, }, } - env := baseContainer.GetEnv(v1.StoreComponent) + env := baseContainer.GetEnv() for _, envVar := range env { if envVar.Name == "APP_URL" { require.Equal(t, "overwritten", envVar.Value) @@ -377,7 +377,7 @@ func TestAppCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundCacheType, foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_CACHE_TYPE" { @@ -411,7 +411,7 @@ func TestAppCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundHost, foundPort, foundIndex, foundURL bool for _, envVar := range env { if envVar.Name == "K8S_CACHE_HOST" { @@ -451,7 +451,7 @@ func TestSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundHandler, foundRedisDSN bool for _, envVar := range env { if envVar.Name == "PHP_SESSION_HANDLER" { @@ -481,7 +481,7 @@ func TestSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundHandler, foundSavePath bool for _, envVar := range env { if envVar.Name == "PHP_SESSION_HANDLER" { @@ -511,7 +511,7 @@ func TestNewSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_REDIS_SESSION_DSN" { @@ -536,7 +536,7 @@ func TestNewSessionCacheRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundRedisDSN bool for _, envVar := range env { if envVar.Name == "K8S_REDIS_SESSION_DSN" { @@ -561,7 +561,7 @@ func TestWorkerRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundDSN, foundConsumerName bool for _, envVar := range env { if envVar.Name == "MESSENGER_TRANSPORT_DSN" { @@ -590,7 +590,7 @@ func TestWorkerRedisDsnOverwrite(t *testing.T) { }, } - env := store.GetEnv(v1.StoreComponent) + env := store.GetEnv() var foundDSN, foundConsumerName bool for _, envVar := range env { if envVar.Name == "MESSENGER_TRANSPORT_DSN" { diff --git a/internal/controller/store_status.go b/internal/controller/store_status.go index 73a3fbe..3918838 100644 --- a/internal/controller/store_status.go +++ b/internal/controller/store_status.go @@ -127,7 +127,7 @@ func (r *StoreReconciler) reconcileCRStatus( func printWarningForEnvs(ctx context.Context, store *v1.Store) { l := logging.FromContext(ctx) - envs := store.GetEnv(v1.StoreComponent) + envs := store.GetEnv() // TODO: this check doesn't make sense, because the overwriten envs are in there for _, obj2 := range store.Spec.Container.ExtraEnvs { if slices.ContainsFunc(envs, func(c corev1.EnvVar) bool { return c.Name == obj2.Name }) { diff --git a/internal/cronjob/scheduled_task.go b/internal/cronjob/scheduled_task.go index 36b2713..53307a5 100644 --- a/internal/cronjob/scheduled_task.go +++ b/internal/cronjob/scheduled_task.go @@ -57,7 +57,7 @@ func ScheduledTaskJob(store v1.Store) *batchv1.CronJob { Image: store.Spec.Container.Image, Command: []string{"sh", "-c"}, Args: []string{store.Spec.ScheduledTask.Command}, - Env: store.GetEnv(v1.StoreComponent), + Env: store.GetEnv(), Resources: store.Spec.Container.Resources, // Add Resources here }) diff --git a/internal/deployment/admin.go b/internal/deployment/admin.go index 5a7c5e3..9525703 100644 --- a/internal/deployment/admin.go +++ b/internal/deployment/admin.go @@ -75,8 +75,11 @@ func AdminDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.AdminDeploymentContainer.Annotations) - // Merge containerSpec.ExtraEnvs to override with merged values from AdminDeploymentContainer - envs := util.MergeEnv(store.GetEnv(v1.AdminComponent), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) + if store.Spec.FPM.ProcessManagement == "operator" { + phpEnvs := GetCalculatedPHPFPMValues(int(store.Spec.AdminDeploymentContainer.Resources.Limits.Memory().Value())) + envs = util.MergeEnv(envs, phpEnvs) + } containers := append(containerSpec.ExtraContainers, corev1.Container{ LivenessProbe: &corev1.Probe{ diff --git a/internal/deployment/storefront.go b/internal/deployment/storefront.go index ee09444..89c1690 100644 --- a/internal/deployment/storefront.go +++ b/internal/deployment/storefront.go @@ -79,8 +79,11 @@ func StorefrontDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.StorefrontDeploymentContainer.Annotations) - // Merge containerSpec.ExtraEnvs to override with merged values from StorefrontDeploymentContainer - envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) + if store.Spec.FPM.ProcessManagement == "operator" { + phpEnvs := GetCalculatedPHPFPMValues(int(store.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value())) + envs = util.MergeEnv(envs, phpEnvs) + } containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: DEPLOYMENT_STOREFRONT_CONTAINER_NAME, diff --git a/internal/deployment/util.go b/internal/deployment/util.go index 4f9d293..6619131 100644 --- a/internal/deployment/util.go +++ b/internal/deployment/util.go @@ -3,14 +3,23 @@ package deployment import ( "context" "fmt" + "math" v1 "github.com/shopware/shopware-operator/api/v1" appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" ) +const ( + startServersRatio = 0.25 + minSpareServersRatio = 0.2 + maxSpareServersRatio = 0.375 + memoryPerChildMiB = 80 //Every PHP-FPM process in an empty shop uses 70.6MiB +) + func getDeploymentCondition( deployment *appsv1.Deployment, storeReplicas int32, @@ -92,3 +101,33 @@ func GetStoreDeploymentImage( } return "", fmt.Errorf("could not find storefront deployment container") } + +func GetCalculatedPHPFPMValues(memoryLimitMiB int) []corev1.EnvVar { + maxChildren := int(math.Round(float64(memoryLimitMiB / memoryPerChildMiB))) + startServers := int(math.Round(float64(maxChildren) * startServersRatio)) + minSpare := int(math.Round(float64(maxChildren) * minSpareServersRatio)) + maxSpare := int(math.Round(float64(maxChildren)*maxSpareServersRatio) + 1) + + return []corev1.EnvVar{ + { + Name: "FPM_PM", + Value: "dynamic", + }, + { + Name: "FPM_PM_MAX_CHILDREN", + Value: fmt.Sprintf("%d", maxChildren), + }, + { + Name: "FPM_PM_START_SERVERS", + Value: fmt.Sprintf("%d", startServers), + }, + { + Name: "FPM_PM_MIN_SPARE_SERVERS", + Value: fmt.Sprintf("%d", minSpare), + }, + { + Name: "FPM_PM_MAX_SPARE_SERVERS", + Value: fmt.Sprintf("%d", maxSpare), + }, + } +} diff --git a/internal/deployment/worker.go b/internal/deployment/worker.go index 91250cb..4bffca1 100644 --- a/internal/deployment/worker.go +++ b/internal/deployment/worker.go @@ -76,7 +76,7 @@ func WorkerDeployment(store v1.Store) *appsv1.Deployment { annotations := util.GetDefaultContainerAnnotations(appName, store, store.Spec.WorkerDeploymentContainer.Annotations) // Merge containerSpec.ExtraEnvs to override with merged values from WorkerDeploymentContainer - envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: appName, diff --git a/internal/job/command.go b/internal/job/command.go index f05c5a0..0fb66ab 100644 --- a/internal/job/command.go +++ b/internal/job/command.go @@ -114,7 +114,7 @@ func getJobSpec(store v1.Store, ex v1.StoreExec, labels map[string]string) batch containerSpec := store.Spec.Container.DeepCopy() sharedProcessNamespace := true - envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), ex.Spec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(), ex.Spec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_COMMAND, diff --git a/internal/job/migration.go b/internal/job/migration.go index 6e9dc16..3683e14 100644 --- a/internal/job/migration.go +++ b/internal/job/migration.go @@ -51,7 +51,7 @@ func MigrationJob(store v1.Store) *batchv1.Job { annotations["shop.shopware.com/store.newImage"] = containerSpec.Image // Merge containerSpec.ExtraEnvs to override with merged values from MigrationJobContainer - envs := util.MergeEnv(store.GetEnv(v1.StoreComponent), containerSpec.ExtraEnvs) + envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) containers := append(containerSpec.ExtraContainers, corev1.Container{ Name: CONTAINER_NAME_MIGRATION_JOB, diff --git a/internal/job/setup.go b/internal/job/setup.go index 5a8d0c5..53456c8 100644 --- a/internal/job/setup.go +++ b/internal/job/setup.go @@ -41,7 +41,7 @@ func SetupJob(store v1.Store) *batchv1.Job { // Use util function for annotations annotations := util.GetDefaultContainerAnnotations(CONTAINER_NAME_SETUP_JOB, store, store.Spec.SetupJobContainer.Annotations) - envs := append(store.GetEnv(v1.StoreComponent), + envs := append(store.GetEnv(), corev1.EnvVar{ Name: "INSTALL_ADMIN_PASSWORD", ValueFrom: &corev1.EnvVarSource{ diff --git a/internal/pod/debug.go b/internal/pod/debug.go index a21d995..c88b16e 100644 --- a/internal/pod/debug.go +++ b/internal/pod/debug.go @@ -60,7 +60,7 @@ func DebugPod(store v1.Store, storeDebugInstance v1.StoreDebugInstance) *corev1. // we don't need the liveness and readiness probe to make sure that the container always starts Image: containerImage, // Use custom image if provided ImagePullPolicy: store.Spec.Container.ImagePullPolicy, - Env: store.GetEnv(v1.StoreComponent), + Env: store.GetEnv(), VolumeMounts: store.Spec.Container.VolumeMounts, Ports: ports, Resources: store.Spec.Container.Resources, From 51423a5c18267fc689eb05a3a7a6de38ccfa3703 Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 29 Apr 2026 09:38:44 +0200 Subject: [PATCH 5/5] feat: check if memory is 0 befor calculating --- internal/deployment/admin.go | 9 +++++++-- internal/deployment/storefront.go | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/deployment/admin.go b/internal/deployment/admin.go index 9525703..92cbd83 100644 --- a/internal/deployment/admin.go +++ b/internal/deployment/admin.go @@ -77,8 +77,13 @@ func AdminDeployment(store v1.Store) *appsv1.Deployment { envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) if store.Spec.FPM.ProcessManagement == "operator" { - phpEnvs := GetCalculatedPHPFPMValues(int(store.Spec.AdminDeploymentContainer.Resources.Limits.Memory().Value())) - envs = util.MergeEnv(envs, phpEnvs) + if containerSpec.Resources.Limits.Memory() != nil && containerSpec.Resources.Limits.Memory().Value() != 0 { + phpEnvs := GetCalculatedPHPFPMValues(int(containerSpec.Resources.Limits.Memory().Value() / (1024 * 1024))) + envs = util.MergeEnv(envs, phpEnvs) + } else { + phpEnvs := GetCalculatedPHPFPMValues(2048) + envs = util.MergeEnv(envs, phpEnvs) + } } containers := append(containerSpec.ExtraContainers, corev1.Container{ diff --git a/internal/deployment/storefront.go b/internal/deployment/storefront.go index 89c1690..a9f81af 100644 --- a/internal/deployment/storefront.go +++ b/internal/deployment/storefront.go @@ -81,8 +81,14 @@ func StorefrontDeployment(store v1.Store) *appsv1.Deployment { envs := util.MergeEnv(store.GetEnv(), containerSpec.ExtraEnvs) if store.Spec.FPM.ProcessManagement == "operator" { - phpEnvs := GetCalculatedPHPFPMValues(int(store.Spec.StorefrontDeploymentContainer.Resources.Limits.Memory().Value())) - envs = util.MergeEnv(envs, phpEnvs) + if containerSpec.Resources.Limits.Memory() != nil && containerSpec.Resources.Limits.Memory().Value() != 0 { + phpEnvs := GetCalculatedPHPFPMValues(int(containerSpec.Resources.Limits.Memory().Value() / (1024 * 1024))) + envs = util.MergeEnv(envs, phpEnvs) + } else { + phpEnvs := GetCalculatedPHPFPMValues(2048) + envs = util.MergeEnv(envs, phpEnvs) + fmt.Println("envs: ", phpEnvs) + } } containers := append(containerSpec.ExtraContainers, corev1.Container{