feat(deploy): configurable CPU/RAM/disk for app databases
Let users size the database workload from the deploy wizard the same way Redis/RabbitMQ are configured: a resource card (CPU request/limit, memory request/limit, storage) on the Resources step, stored in optionalServiceResources.database. - entity/DTO: add `database` to optionalServiceResources - k8s: resolveDatabaseResources() applies user-selected resources on both the Helm and K8s-API deploy paths (was hardcoded 100m/256Mi→500m/512Mi) - billing: bill database CPU/RAM as a separate line on top of the app's resources; merge it through the upgrade path too - wizard: db resource card on the Resources step, disk moved into the card, cost preview + review summary include the database resources Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,10 @@ interface ManifestContext {
|
||||
dbPassword: string;
|
||||
dbVersion: string;
|
||||
dbStorageSize: string;
|
||||
dbCpuRequest: string;
|
||||
dbCpuLimit: string;
|
||||
dbMemoryRequest: string;
|
||||
dbMemoryLimit: string;
|
||||
appStorageSize: string;
|
||||
enableRedis: boolean;
|
||||
redisVersion: string;
|
||||
@@ -126,6 +130,21 @@ export class KubernetesService implements OnModuleInit {
|
||||
/**
|
||||
* Build Helm values object from an Application entity and image URI.
|
||||
*/
|
||||
/**
|
||||
* Resolve the database workload's CPU/RAM. Prefers the user-selected
|
||||
* per-database resources (optionalServiceResources.database); falls back to
|
||||
* the app's main resources for managed databases / legacy apps.
|
||||
*/
|
||||
private resolveDatabaseResources(app: Application) {
|
||||
const res = app.optionalServiceResources?.database;
|
||||
return {
|
||||
cpuRequest: res?.cpuRequest || app.cpuRequest || '100m',
|
||||
cpuLimit: res?.cpuLimit || app.cpuLimit || '500m',
|
||||
memoryRequest: res?.memoryRequest || app.memoryRequest || '256Mi',
|
||||
memoryLimit: res?.memoryLimit || app.memoryLimit || '512Mi',
|
||||
};
|
||||
}
|
||||
|
||||
private buildRedisHelmBlock(app: Application) {
|
||||
const res = app.optionalServiceResources?.redis;
|
||||
const storageGi = res?.storageGi ?? 1;
|
||||
@@ -254,12 +273,7 @@ export class KubernetesService implements OnModuleInit {
|
||||
username: app.dbUsername || 'appuser',
|
||||
password: app.dbPassword || this.generatePassword(),
|
||||
storageSize: app.dbStorageSize || '1Gi',
|
||||
resources: {
|
||||
cpuRequest: app.cpuRequest || '100m',
|
||||
cpuLimit: app.cpuLimit || '500m',
|
||||
memoryRequest: app.memoryRequest || '256Mi',
|
||||
memoryLimit: app.memoryLimit || '512Mi',
|
||||
},
|
||||
resources: this.resolveDatabaseResources(app),
|
||||
},
|
||||
redis: { enabled: false, storageSize: '1Gi', resources: {} },
|
||||
rabbitmq: { enabled: false, storageSize: '2Gi', resources: {} },
|
||||
@@ -342,12 +356,7 @@ export class KubernetesService implements OnModuleInit {
|
||||
username: app.dbUsername || 'appuser',
|
||||
password: app.dbPassword || this.generatePassword(),
|
||||
storageSize: app.dbStorageSize || '1Gi',
|
||||
resources: {
|
||||
cpuRequest: app.cpuRequest || '100m',
|
||||
cpuLimit: app.cpuLimit || '500m',
|
||||
memoryRequest: app.memoryRequest || '256Mi',
|
||||
memoryLimit: app.memoryLimit || '512Mi',
|
||||
},
|
||||
resources: this.resolveDatabaseResources(app),
|
||||
},
|
||||
wordpress: {
|
||||
enabled: isWordPress,
|
||||
@@ -481,6 +490,10 @@ export class KubernetesService implements OnModuleInit {
|
||||
dbPassword: app.dbPassword || '',
|
||||
dbVersion: app.dbVersion || '',
|
||||
dbStorageSize: app.dbStorageSize || '1Gi',
|
||||
dbCpuRequest: this.resolveDatabaseResources(app).cpuRequest,
|
||||
dbCpuLimit: this.resolveDatabaseResources(app).cpuLimit,
|
||||
dbMemoryRequest: this.resolveDatabaseResources(app).memoryRequest,
|
||||
dbMemoryLimit: this.resolveDatabaseResources(app).memoryLimit,
|
||||
appStorageSize: app.appStorageSize || '2Gi',
|
||||
enableRedis: app.enableRedis || false,
|
||||
redisVersion: app.redisVersion || '7.2',
|
||||
@@ -559,6 +572,10 @@ export class KubernetesService implements OnModuleInit {
|
||||
dbPassword: app.dbPassword || this.generatePassword(),
|
||||
dbVersion: app.dbVersion || '',
|
||||
dbStorageSize: app.dbStorageSize || '1Gi',
|
||||
dbCpuRequest: this.resolveDatabaseResources(app).cpuRequest,
|
||||
dbCpuLimit: this.resolveDatabaseResources(app).cpuLimit,
|
||||
dbMemoryRequest: this.resolveDatabaseResources(app).memoryRequest,
|
||||
dbMemoryLimit: this.resolveDatabaseResources(app).memoryLimit,
|
||||
appStorageSize: app.appStorageSize || '2Gi',
|
||||
enableRedis: false,
|
||||
redisVersion: app.redisVersion || '7.2',
|
||||
@@ -626,6 +643,10 @@ export class KubernetesService implements OnModuleInit {
|
||||
dbPassword: app.dbPassword || this.generatePassword(),
|
||||
dbVersion: app.dbVersion || '',
|
||||
dbStorageSize: app.dbStorageSize || '1Gi',
|
||||
dbCpuRequest: this.resolveDatabaseResources(app).cpuRequest,
|
||||
dbCpuLimit: this.resolveDatabaseResources(app).cpuLimit,
|
||||
dbMemoryRequest: this.resolveDatabaseResources(app).memoryRequest,
|
||||
dbMemoryLimit: this.resolveDatabaseResources(app).memoryLimit,
|
||||
appStorageSize: app.appStorageSize || '2Gi',
|
||||
enableRedis: app.enableRedis || false,
|
||||
redisVersion: app.redisVersion || '7.2',
|
||||
@@ -1808,8 +1829,8 @@ export class KubernetesService implements OnModuleInit {
|
||||
env: envVars,
|
||||
volumeMounts: [{ name: 'db-storage', mountPath: dataPath }],
|
||||
resources: {
|
||||
requests: { cpu: '100m', memory: '256Mi' },
|
||||
limits: { cpu: '500m', memory: '512Mi' },
|
||||
requests: { cpu: ctx.dbCpuRequest, memory: ctx.dbMemoryRequest },
|
||||
limits: { cpu: ctx.dbCpuLimit, memory: ctx.dbMemoryLimit },
|
||||
},
|
||||
readinessProbe,
|
||||
livenessProbe,
|
||||
|
||||
Reference in New Issue
Block a user