@caelo-cms/provisioning 0.11.5 → 0.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/compose.d.ts CHANGED
@@ -16,6 +16,13 @@ export interface DevImages {
16
16
  export type ComposeImages = ReleaseImages | DevImages;
17
17
  /** The admin's HTTP port inside the Compose network (the Caddyfile proxies to it). */
18
18
  export declare const COMPOSE_ADMIN_PORT = 5173;
19
+ /**
20
+ * #1254 — the Compose install's connection budget: one admin and one
21
+ * gateway container on a Postgres started with exactly
22
+ * `DEFAULT_MAX_CONNECTIONS["self-hosted"]` slots (the postgres service's
23
+ * `command`), so the pool sizes below always match the server.
24
+ */
25
+ export declare const COMPOSE_POOL_BUDGET: import("./pool-budget-stack.js").StackPoolBudget;
19
26
  /** `.caelo/<this>/` holds the pending Owner-bootstrap token the admin consumes. */
20
27
  export declare const BOOTSTRAP_DIR = "bootstrap";
21
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"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"}
package/dist/compose.js CHANGED
@@ -27,10 +27,26 @@
27
27
  */
28
28
  import { CADDY_REDIRECTS_FILE } from "@caelo-cms/shared";
29
29
  import { caddyRedirectReloadCommand } from "./caddy-redirects.js";
30
+ import { DEFAULT_MAX_CONNECTIONS, stackPoolBudget } from "./pool-budget-stack.js";
30
31
  import { ADMIN_MEMORY_DEFAULT, GATEWAY_TRUSTED_PROXY_HOPS, memoryQuantityMiB, publicSiteUrl, TRUSTED_PROXY_HOPS_ENV, } from "./stack-contract.js";
31
32
  import { ghcrRepository, isImageDigest } from "./upgrade/release-images.js";
32
33
  /** The admin's HTTP port inside the Compose network (the Caddyfile proxies to it). */
33
34
  export const COMPOSE_ADMIN_PORT = 5173;
35
+ /**
36
+ * #1254 — the Compose install's connection budget: one admin and one
37
+ * gateway container on a Postgres started with exactly
38
+ * `DEFAULT_MAX_CONNECTIONS["self-hosted"]` slots (the postgres service's
39
+ * `command`), so the pool sizes below always match the server.
40
+ */
41
+ export const COMPOSE_POOL_BUDGET = stackPoolBudget("self-hosted", {
42
+ maxConnections: DEFAULT_MAX_CONNECTIONS["self-hosted"],
43
+ adminMaxInstances: 1,
44
+ gatewayMaxInstances: 1,
45
+ });
46
+ /** The budget's env as Compose `environment:` lines for `service`. */
47
+ function poolEnvLines(service) {
48
+ return COMPOSE_POOL_BUDGET.env[service].map((e) => ` ${e.name}: "${e.value}"`).join("\n");
49
+ }
34
50
  /** `.caelo/<this>/` holds the pending Owner-bootstrap token the admin consumes. */
35
51
  export const BOOTSTRAP_DIR = "bootstrap";
36
52
  /**
@@ -154,6 +170,8 @@ name: ${spec.project}
154
170
  services:
155
171
  postgres:
156
172
  image: postgres:16-alpine
173
+ # The pool budget (COMPOSE_POOL_BUDGET) is computed from this number.
174
+ command: ["postgres", "-c", "max_connections=${DEFAULT_MAX_CONNECTIONS["self-hosted"]}"]
157
175
  restart: unless-stopped
158
176
  environment:
159
177
  POSTGRES_PASSWORD: "${escapeYaml(spec.postgresPassword)}"
@@ -266,6 +284,7 @@ ${serviceRuntime(spec.images, "admin", `sh -c "cd apps/admin && bunx svelte-kit
266
284
  CAELO_OUTPUT_ROOT: "${SITE_OUTPUT_ROOT}"
267
285
  MEDIA_ROOT_DIR: "${MEDIA_ROOT}"
268
286
  CAELO_PROVIDER: "self-hosted"
287
+ ${poolEnvLines("admin")}
269
288
  NODE_ENV: production
270
289
  ${env("ANTHROPIC_API_KEY", spec.anthropicApiKey)}
271
290
  ${env("RESEND_API_KEY", spec.resendApiKey)}`;
@@ -283,6 +302,7 @@ ${serviceRuntime(spec.images, "gateway", "bun run apps/api-gateway/src/server.ts
283
302
  GATEWAY_PORT: "${COMPOSE_GATEWAY_PORT}"
284
303
  # Caddy is the one proxy in front (client-ip.ts in the gateway).
285
304
  ${TRUSTED_PROXY_HOPS_ENV}: "${GATEWAY_TRUSTED_PROXY_HOPS["self-hosted"]}"
305
+ ${poolEnvLines("gateway")}
286
306
  # #806 — no remote MCP here: it rides Google IAP, which this install
287
307
  # does not have. CAELO_ADMIN_URL / CAELO_MCP_PUBLIC_URL /
288
308
  # CAELO_OPERATOR_OAUTH_CLIENT_FILE stay unset, so the gateway's /api/mcp/*
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * #1254 — each adapter's connection budget (CLAUDE.md §11.B / §11.C): what
3
+ * its Postgres reserves for itself, which jobs it runs, and the default
4
+ * `max_connections` it provisions. The formula itself is shared
5
+ * (`@caelo-cms/shared` pool-budget.ts); this file only states each
6
+ * provider's inputs, so every stack sizes its pools the same way and a
7
+ * stack that sets a number the formula refuses fails at `pulumi preview`,
8
+ * not under load.
9
+ *
10
+ * docs/dev/connection-budget.md explains the reserves.
11
+ */
12
+ import { type PoolBudget } from "@caelo-cms/shared";
13
+ /** The adapters that provision a Postgres server. */
14
+ export type BudgetProvider = "gcp" | "gcp-firebase" | "aws" | "azure" | "self-hosted";
15
+ /** The fixed reserves of one provider (the part of {@link PoolBudgetInput} it decides). */
16
+ export interface ProviderReserves {
17
+ readonly maintenanceReserve: number;
18
+ readonly migrationsReserve: number;
19
+ readonly jobsReserve: number;
20
+ readonly concurrentBuilds: number;
21
+ }
22
+ /**
23
+ * Reserves per provider.
24
+ *
25
+ * - maintenance: Postgres keeps `superuser_reserved_connections` (3) for
26
+ * itself; Cloud SQL's `cloudsqladmin` and RDS's `rdsadmin` agents take
27
+ * about two more; Azure Flexible Server keeps 15 for replication and
28
+ * monitoring.
29
+ * - migrations: one connection per database of a migration run.
30
+ * - jobs: the GCP installs run the operator-access sync, upgrader and
31
+ * converge jobs (one serial query stream each, plus one spare); the other
32
+ * adapters run lifecycle commands from the operator's machine (backup).
33
+ * - builds: a Stage, a Publish live and a plugin-data build can overlap.
34
+ */
35
+ export declare const PROVIDER_RESERVES: Readonly<Record<BudgetProvider, ProviderReserves>>;
36
+ /**
37
+ * `max_connections` each adapter provisions unless the operator sets the
38
+ * `maxConnections` knob. Every stack sets the server parameter to this value
39
+ * explicitly, so the budget never depends on a tier's implicit default
40
+ * (db-f1-micro's is 25, RDS derives it from instance memory).
41
+ */
42
+ export declare const DEFAULT_MAX_CONNECTIONS: Readonly<Record<BudgetProvider, number>>;
43
+ /**
44
+ * Gateway instances a GCP stack lets Cloud Run start (`gatewayMaxInstances`
45
+ * knob). Before #1254 it was a hard-coded 100, which at even the minimum
46
+ * pool of 2 asks for twice the server's 100 slots; ten instances serve
47
+ * 800 concurrent visitor requests at Cloud Run's default concurrency.
48
+ */
49
+ export declare const DEFAULT_GATEWAY_MAX_INSTANCES = 10;
50
+ /** The server and scale-out a stack sizes its pools for. */
51
+ export interface StackScale {
52
+ readonly maxConnections: number;
53
+ /** Every instance that opens the admin's pools (admin-side services included). */
54
+ readonly adminMaxInstances: number;
55
+ readonly gatewayMaxInstances: number;
56
+ }
57
+ /** A stack's budget plus the env each service sets from it. */
58
+ export interface StackPoolBudget {
59
+ readonly budget: PoolBudget;
60
+ readonly env: {
61
+ readonly admin: {
62
+ readonly name: string;
63
+ readonly value: string;
64
+ }[];
65
+ readonly gateway: {
66
+ readonly name: string;
67
+ readonly value: string;
68
+ }[];
69
+ };
70
+ }
71
+ /**
72
+ * The budget of a `provider` install at `scale`.
73
+ *
74
+ * @throws Error (from the shared formula) naming the connections needed when
75
+ * the server is too small for the configured scale-out.
76
+ */
77
+ export declare function stackPoolBudget(provider: BudgetProvider, scale: StackScale): StackPoolBudget;
78
+ //# sourceMappingURL=pool-budget-stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool-budget-stack.d.ts","sourceRoot":"","sources":["../src/pool-budget-stack.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,KAAK,UAAU,EAGhB,MAAM,mBAAmB,CAAC;AAE3B,qDAAqD;AACrD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,cAAc,GAAG,KAAK,GAAG,OAAO,GAAG,aAAa,CAAC;AAEtF,2FAA2F;AAC3F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAgBhF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAO5E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,kFAAkF;IAClF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACpE,QAAQ,CAAC,OAAO,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KACvE,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,GAAG,eAAe,CAM5F"}
@@ -0,0 +1,78 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * #1254 — each adapter's connection budget (CLAUDE.md §11.B / §11.C): what
4
+ * its Postgres reserves for itself, which jobs it runs, and the default
5
+ * `max_connections` it provisions. The formula itself is shared
6
+ * (`@caelo-cms/shared` pool-budget.ts); this file only states each
7
+ * provider's inputs, so every stack sizes its pools the same way and a
8
+ * stack that sets a number the formula refuses fails at `pulumi preview`,
9
+ * not under load.
10
+ *
11
+ * docs/dev/connection-budget.md explains the reserves.
12
+ */
13
+ import { computePoolBudget, poolBudgetEnv, } from "@caelo-cms/shared";
14
+ /**
15
+ * Reserves per provider.
16
+ *
17
+ * - maintenance: Postgres keeps `superuser_reserved_connections` (3) for
18
+ * itself; Cloud SQL's `cloudsqladmin` and RDS's `rdsadmin` agents take
19
+ * about two more; Azure Flexible Server keeps 15 for replication and
20
+ * monitoring.
21
+ * - migrations: one connection per database of a migration run.
22
+ * - jobs: the GCP installs run the operator-access sync, upgrader and
23
+ * converge jobs (one serial query stream each, plus one spare); the other
24
+ * adapters run lifecycle commands from the operator's machine (backup).
25
+ * - builds: a Stage, a Publish live and a plugin-data build can overlap.
26
+ */
27
+ export const PROVIDER_RESERVES = {
28
+ gcp: { maintenanceReserve: 5, migrationsReserve: 2, jobsReserve: 4, concurrentBuilds: 2 },
29
+ "gcp-firebase": {
30
+ maintenanceReserve: 5,
31
+ migrationsReserve: 2,
32
+ jobsReserve: 4,
33
+ concurrentBuilds: 2,
34
+ },
35
+ aws: { maintenanceReserve: 5, migrationsReserve: 2, jobsReserve: 2, concurrentBuilds: 2 },
36
+ azure: { maintenanceReserve: 15, migrationsReserve: 2, jobsReserve: 2, concurrentBuilds: 2 },
37
+ "self-hosted": {
38
+ maintenanceReserve: 3,
39
+ migrationsReserve: 2,
40
+ jobsReserve: 2,
41
+ concurrentBuilds: 2,
42
+ },
43
+ };
44
+ /**
45
+ * `max_connections` each adapter provisions unless the operator sets the
46
+ * `maxConnections` knob. Every stack sets the server parameter to this value
47
+ * explicitly, so the budget never depends on a tier's implicit default
48
+ * (db-f1-micro's is 25, RDS derives it from instance memory).
49
+ */
50
+ export const DEFAULT_MAX_CONNECTIONS = {
51
+ gcp: 100,
52
+ "gcp-firebase": 100,
53
+ aws: 100,
54
+ // The default Standard_B2s server allows up to 429.
55
+ azure: 429,
56
+ "self-hosted": 100,
57
+ };
58
+ /**
59
+ * Gateway instances a GCP stack lets Cloud Run start (`gatewayMaxInstances`
60
+ * knob). Before #1254 it was a hard-coded 100, which at even the minimum
61
+ * pool of 2 asks for twice the server's 100 slots; ten instances serve
62
+ * 800 concurrent visitor requests at Cloud Run's default concurrency.
63
+ */
64
+ export const DEFAULT_GATEWAY_MAX_INSTANCES = 10;
65
+ /**
66
+ * The budget of a `provider` install at `scale`.
67
+ *
68
+ * @throws Error (from the shared formula) naming the connections needed when
69
+ * the server is too small for the configured scale-out.
70
+ */
71
+ export function stackPoolBudget(provider, scale) {
72
+ const budget = computePoolBudget({ ...PROVIDER_RESERVES[provider], ...scale });
73
+ return {
74
+ budget,
75
+ env: { admin: poolBudgetEnv(budget, "admin"), gateway: poolBudgetEnv(budget, "gateway") },
76
+ };
77
+ }
78
+ //# sourceMappingURL=pool-budget-stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool-budget-stack.js","sourceRoot":"","sources":["../src/pool-budget-stack.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;GAUG;AAEH,OAAO,EACL,iBAAiB,EAGjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAa3B;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAuD;IACnF,GAAG,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE;IACzF,cAAc,EAAE;QACd,kBAAkB,EAAE,CAAC;QACrB,iBAAiB,EAAE,CAAC;QACpB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,CAAC;KACpB;IACD,GAAG,EAAE,EAAE,kBAAkB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE;IACzF,KAAK,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE;IAC5F,aAAa,EAAE;QACb,kBAAkB,EAAE,CAAC;QACrB,iBAAiB,EAAE,CAAC;QACpB,WAAW,EAAE,CAAC;QACd,gBAAgB,EAAE,CAAC;KACpB;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA6C;IAC/E,GAAG,EAAE,GAAG;IACR,cAAc,EAAE,GAAG;IACnB,GAAG,EAAE,GAAG;IACR,oDAAoD;IACpD,KAAK,EAAE,GAAG;IACV,aAAa,EAAE,GAAG;CACnB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAmBhD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAwB,EAAE,KAAiB;IACzE,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAC/E,OAAO;QACL,MAAM;QACN,GAAG,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;KAC1F,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caelo-cms/provisioning",
3
- "version": "0.11.5",
3
+ "version": "0.11.7",
4
4
  "private": false,
5
5
  "license": "MPL-2.0",
6
6
  "description": "Pulumi-driven provisioning for Caelo CMS — `bunx @caelo-cms/provisioning --provider <self-hosted|gcp|aws|azure>` brings up a TLS-served install with Postgres + storage + secrets manager + the admin + the API gateway.",
@@ -40,7 +40,7 @@
40
40
  "prepublishOnly": "tsc -b --force && bun build ../platform-updater/src/agent-db.ts --target=bun --outfile=dist/agent-db.js && tsc --project stacks/gcp/tsconfig.json && tsc --project stacks/gcp-firebase/tsconfig.json"
41
41
  },
42
42
  "dependencies": {
43
- "@caelo-cms/shared": "^0.11.5",
43
+ "@caelo-cms/shared": "^0.11.7",
44
44
  "@clack/prompts": "1.8.1",
45
45
  "@pulumi/command": "^1",
46
46
  "@pulumi/gcp": "^10",
package/src/compose.ts CHANGED
@@ -29,6 +29,7 @@
29
29
 
30
30
  import { CADDY_REDIRECTS_FILE } from "@caelo-cms/shared";
31
31
  import { caddyRedirectReloadCommand } from "./caddy-redirects.js";
32
+ import { DEFAULT_MAX_CONNECTIONS, stackPoolBudget } from "./pool-budget-stack.js";
32
33
  import {
33
34
  ADMIN_MEMORY_DEFAULT,
34
35
  GATEWAY_TRUSTED_PROXY_HOPS,
@@ -58,6 +59,23 @@ export type ComposeImages = ReleaseImages | DevImages;
58
59
 
59
60
  /** The admin's HTTP port inside the Compose network (the Caddyfile proxies to it). */
60
61
  export const COMPOSE_ADMIN_PORT = 5173;
62
+
63
+ /**
64
+ * #1254 — the Compose install's connection budget: one admin and one
65
+ * gateway container on a Postgres started with exactly
66
+ * `DEFAULT_MAX_CONNECTIONS["self-hosted"]` slots (the postgres service's
67
+ * `command`), so the pool sizes below always match the server.
68
+ */
69
+ export const COMPOSE_POOL_BUDGET = stackPoolBudget("self-hosted", {
70
+ maxConnections: DEFAULT_MAX_CONNECTIONS["self-hosted"],
71
+ adminMaxInstances: 1,
72
+ gatewayMaxInstances: 1,
73
+ });
74
+
75
+ /** The budget's env as Compose `environment:` lines for `service`. */
76
+ function poolEnvLines(service: "admin" | "gateway"): string {
77
+ return COMPOSE_POOL_BUDGET.env[service].map((e) => ` ${e.name}: "${e.value}"`).join("\n");
78
+ }
61
79
  /** `.caelo/<this>/` holds the pending Owner-bootstrap token the admin consumes. */
62
80
  export const BOOTSTRAP_DIR = "bootstrap";
63
81
 
@@ -265,6 +283,8 @@ name: ${spec.project}
265
283
  services:
266
284
  postgres:
267
285
  image: postgres:16-alpine
286
+ # The pool budget (COMPOSE_POOL_BUDGET) is computed from this number.
287
+ command: ["postgres", "-c", "max_connections=${DEFAULT_MAX_CONNECTIONS["self-hosted"]}"]
268
288
  restart: unless-stopped
269
289
  environment:
270
290
  POSTGRES_PASSWORD: "${escapeYaml(spec.postgresPassword)}"
@@ -394,6 +414,7 @@ ${serviceRuntime(
394
414
  CAELO_OUTPUT_ROOT: "${SITE_OUTPUT_ROOT}"
395
415
  MEDIA_ROOT_DIR: "${MEDIA_ROOT}"
396
416
  CAELO_PROVIDER: "self-hosted"
417
+ ${poolEnvLines("admin")}
397
418
  NODE_ENV: production
398
419
  ${env("ANTHROPIC_API_KEY", spec.anthropicApiKey)}
399
420
  ${env("RESEND_API_KEY", spec.resendApiKey)}`;
@@ -412,6 +433,7 @@ ${serviceRuntime(spec.images, "gateway", "bun run apps/api-gateway/src/server.ts
412
433
  GATEWAY_PORT: "${COMPOSE_GATEWAY_PORT}"
413
434
  # Caddy is the one proxy in front (client-ip.ts in the gateway).
414
435
  ${TRUSTED_PROXY_HOPS_ENV}: "${GATEWAY_TRUSTED_PROXY_HOPS["self-hosted"]}"
436
+ ${poolEnvLines("gateway")}
415
437
  # #806 — no remote MCP here: it rides Google IAP, which this install
416
438
  # does not have. CAELO_ADMIN_URL / CAELO_MCP_PUBLIC_URL /
417
439
  # CAELO_OPERATOR_OAUTH_CLIENT_FILE stay unset, so the gateway's /api/mcp/*
@@ -157,6 +157,8 @@ describe("self-hosted: the generated compose gateway service (#635)", () => {
157
157
  const env = gateway.slice(gateway.indexOf(" environment:"));
158
158
  const keys = [...env.matchAll(/^ {6}([A-Z_][A-Z0-9_]*):/gm)].map((m) => m[1]);
159
159
  expect(keys.sort()).toEqual([
160
+ // #1254 — its cms_public pool size (pool-budget-stack.ts).
161
+ "CAELO_DB_PUBLIC_POOL_MAX",
160
162
  "CAELO_TRUSTED_PROXY_HOPS",
161
163
  "GATEWAY_PORT",
162
164
  "NODE_ENV",
@@ -0,0 +1,116 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+
3
+ /**
4
+ * #1254 — each adapter's connection budget (CLAUDE.md §11.B / §11.C): what
5
+ * its Postgres reserves for itself, which jobs it runs, and the default
6
+ * `max_connections` it provisions. The formula itself is shared
7
+ * (`@caelo-cms/shared` pool-budget.ts); this file only states each
8
+ * provider's inputs, so every stack sizes its pools the same way and a
9
+ * stack that sets a number the formula refuses fails at `pulumi preview`,
10
+ * not under load.
11
+ *
12
+ * docs/dev/connection-budget.md explains the reserves.
13
+ */
14
+
15
+ import {
16
+ computePoolBudget,
17
+ type PoolBudget,
18
+ type PoolBudgetInput,
19
+ poolBudgetEnv,
20
+ } from "@caelo-cms/shared";
21
+
22
+ /** The adapters that provision a Postgres server. */
23
+ export type BudgetProvider = "gcp" | "gcp-firebase" | "aws" | "azure" | "self-hosted";
24
+
25
+ /** The fixed reserves of one provider (the part of {@link PoolBudgetInput} it decides). */
26
+ export interface ProviderReserves {
27
+ readonly maintenanceReserve: number;
28
+ readonly migrationsReserve: number;
29
+ readonly jobsReserve: number;
30
+ readonly concurrentBuilds: number;
31
+ }
32
+
33
+ /**
34
+ * Reserves per provider.
35
+ *
36
+ * - maintenance: Postgres keeps `superuser_reserved_connections` (3) for
37
+ * itself; Cloud SQL's `cloudsqladmin` and RDS's `rdsadmin` agents take
38
+ * about two more; Azure Flexible Server keeps 15 for replication and
39
+ * monitoring.
40
+ * - migrations: one connection per database of a migration run.
41
+ * - jobs: the GCP installs run the operator-access sync, upgrader and
42
+ * converge jobs (one serial query stream each, plus one spare); the other
43
+ * adapters run lifecycle commands from the operator's machine (backup).
44
+ * - builds: a Stage, a Publish live and a plugin-data build can overlap.
45
+ */
46
+ export const PROVIDER_RESERVES: Readonly<Record<BudgetProvider, ProviderReserves>> = {
47
+ gcp: { maintenanceReserve: 5, migrationsReserve: 2, jobsReserve: 4, concurrentBuilds: 2 },
48
+ "gcp-firebase": {
49
+ maintenanceReserve: 5,
50
+ migrationsReserve: 2,
51
+ jobsReserve: 4,
52
+ concurrentBuilds: 2,
53
+ },
54
+ aws: { maintenanceReserve: 5, migrationsReserve: 2, jobsReserve: 2, concurrentBuilds: 2 },
55
+ azure: { maintenanceReserve: 15, migrationsReserve: 2, jobsReserve: 2, concurrentBuilds: 2 },
56
+ "self-hosted": {
57
+ maintenanceReserve: 3,
58
+ migrationsReserve: 2,
59
+ jobsReserve: 2,
60
+ concurrentBuilds: 2,
61
+ },
62
+ };
63
+
64
+ /**
65
+ * `max_connections` each adapter provisions unless the operator sets the
66
+ * `maxConnections` knob. Every stack sets the server parameter to this value
67
+ * explicitly, so the budget never depends on a tier's implicit default
68
+ * (db-f1-micro's is 25, RDS derives it from instance memory).
69
+ */
70
+ export const DEFAULT_MAX_CONNECTIONS: Readonly<Record<BudgetProvider, number>> = {
71
+ gcp: 100,
72
+ "gcp-firebase": 100,
73
+ aws: 100,
74
+ // The default Standard_B2s server allows up to 429.
75
+ azure: 429,
76
+ "self-hosted": 100,
77
+ };
78
+
79
+ /**
80
+ * Gateway instances a GCP stack lets Cloud Run start (`gatewayMaxInstances`
81
+ * knob). Before #1254 it was a hard-coded 100, which at even the minimum
82
+ * pool of 2 asks for twice the server's 100 slots; ten instances serve
83
+ * 800 concurrent visitor requests at Cloud Run's default concurrency.
84
+ */
85
+ export const DEFAULT_GATEWAY_MAX_INSTANCES = 10;
86
+
87
+ /** The server and scale-out a stack sizes its pools for. */
88
+ export interface StackScale {
89
+ readonly maxConnections: number;
90
+ /** Every instance that opens the admin's pools (admin-side services included). */
91
+ readonly adminMaxInstances: number;
92
+ readonly gatewayMaxInstances: number;
93
+ }
94
+
95
+ /** A stack's budget plus the env each service sets from it. */
96
+ export interface StackPoolBudget {
97
+ readonly budget: PoolBudget;
98
+ readonly env: {
99
+ readonly admin: { readonly name: string; readonly value: string }[];
100
+ readonly gateway: { readonly name: string; readonly value: string }[];
101
+ };
102
+ }
103
+
104
+ /**
105
+ * The budget of a `provider` install at `scale`.
106
+ *
107
+ * @throws Error (from the shared formula) naming the connections needed when
108
+ * the server is too small for the configured scale-out.
109
+ */
110
+ export function stackPoolBudget(provider: BudgetProvider, scale: StackScale): StackPoolBudget {
111
+ const budget = computePoolBudget({ ...PROVIDER_RESERVES[provider], ...scale });
112
+ return {
113
+ budget,
114
+ env: { admin: poolBudgetEnv(budget, "admin"), gateway: poolBudgetEnv(budget, "gateway") },
115
+ };
116
+ }
@@ -0,0 +1,100 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+
3
+ /**
4
+ * #1254 — every adapter sizes its pools from the connection budget
5
+ * (CLAUDE.md §11.C: all four adapters). Pins the numbers each stack's
6
+ * defaults produce and that each stack actually sets them on its services.
7
+ */
8
+
9
+ import { describe, expect, it } from "bun:test";
10
+ import { readFileSync } from "node:fs";
11
+ import { resolve } from "node:path";
12
+ import { COMPOSE_POOL_BUDGET } from "./compose.js";
13
+ import {
14
+ type BudgetProvider,
15
+ DEFAULT_GATEWAY_MAX_INSTANCES,
16
+ DEFAULT_MAX_CONNECTIONS,
17
+ stackPoolBudget,
18
+ } from "./pool-budget-stack.js";
19
+
20
+ const stackSource = (provider: string): string =>
21
+ readFileSync(resolve(import.meta.dir, "..", "stacks", provider, "index.ts"), "utf8");
22
+
23
+ /** Each stack's default scale-out, as its index.ts reads it. */
24
+ const DEFAULT_SCALE: Record<BudgetProvider, { admin: number; gateway: number }> = {
25
+ gcp: { admin: 5, gateway: DEFAULT_GATEWAY_MAX_INSTANCES },
26
+ "gcp-firebase": { admin: 5, gateway: DEFAULT_GATEWAY_MAX_INSTANCES },
27
+ aws: { admin: 5, gateway: DEFAULT_GATEWAY_MAX_INSTANCES },
28
+ // admin + orchestrator + runner apps, 10 replicas each.
29
+ azure: { admin: 30, gateway: 10 },
30
+ "self-hosted": { admin: 1, gateway: 1 },
31
+ };
32
+
33
+ /** [cms_admin pool per admin instance, connections left unassigned]. */
34
+ const EXPECTED: Record<BudgetProvider, [number, number]> = {
35
+ gcp: [5, 1],
36
+ "gcp-firebase": [5, 1],
37
+ aws: [5, 3],
38
+ azure: [7, 12],
39
+ "self-hosted": [77, 0],
40
+ };
41
+
42
+ describe("stack pool budgets at the default config", () => {
43
+ for (const provider of Object.keys(EXPECTED) as BudgetProvider[]) {
44
+ it(`${provider}: pools fit max_connections ${DEFAULT_MAX_CONNECTIONS[provider]}`, () => {
45
+ const { budget, env } = stackPoolBudget(provider, {
46
+ maxConnections: DEFAULT_MAX_CONNECTIONS[provider],
47
+ adminMaxInstances: DEFAULT_SCALE[provider].admin,
48
+ gatewayMaxInstances: DEFAULT_SCALE[provider].gateway,
49
+ });
50
+ expect([budget.adminPoolMax, budget.unassigned]).toEqual(EXPECTED[provider]);
51
+ expect(env.admin).toEqual([
52
+ { name: "CAELO_DB_POOL_MAX", value: String(EXPECTED[provider][0]) },
53
+ { name: "CAELO_DB_PUBLIC_POOL_MAX", value: "4" },
54
+ ]);
55
+ expect(env.gateway).toEqual([{ name: "CAELO_DB_PUBLIC_POOL_MAX", value: "2" }]);
56
+ });
57
+ }
58
+
59
+ it("refuses the pre-#1254 GCP gateway scale-out of 100 on 100 slots", () => {
60
+ expect(() =>
61
+ stackPoolBudget("gcp", {
62
+ maxConnections: 100,
63
+ adminMaxInstances: 5,
64
+ gatewayMaxInstances: 100,
65
+ }),
66
+ ).toThrow(/Raise maxConnections/);
67
+ });
68
+ });
69
+
70
+ describe("stacks set the budget on their services", () => {
71
+ for (const provider of ["gcp", "gcp-firebase"]) {
72
+ it(`${provider}: admin + gateway env, gateway scale-out from the knob`, () => {
73
+ const src = stackSource(provider);
74
+ expect(src).toContain(`stackPoolBudget("${provider}"`);
75
+ expect(src).toContain("...poolBudget.env.admin");
76
+ expect(src).toContain("...poolBudget.env.gateway");
77
+ expect(src).toContain("maxInstances: gatewayMaxInstances");
78
+ expect(src).not.toContain("maxInstances: 100");
79
+ });
80
+ }
81
+
82
+ it("aws: pins max_connections and exports the task env", () => {
83
+ const src = stackSource("aws");
84
+ expect(src).toContain('stackPoolBudget("aws"');
85
+ expect(src).toContain('name: "max_connections"');
86
+ expect(src).toContain("export const poolBudgetEnvOut = poolBudget.env");
87
+ });
88
+
89
+ it("azure: pins max_connections and sets the env on every app", () => {
90
+ const src = stackSource("azure");
91
+ expect(src).toContain('stackPoolBudget("azure"');
92
+ expect(src).toContain('configurationName: "max_connections"');
93
+ expect(src).toContain("...poolBudget.env.admin");
94
+ expect(src).toContain("...poolBudget.env.gateway");
95
+ });
96
+
97
+ it("self-hosted: the Compose budget is the default one (yaml: self-hosted-compose.test.ts)", () => {
98
+ expect(COMPOSE_POOL_BUDGET.budget.adminPoolMax).toBe(EXPECTED["self-hosted"][0]);
99
+ });
100
+ });
@@ -6,6 +6,7 @@ import {
6
6
  COMPOSE_ADMIN_UPSTREAM,
7
7
  COMPOSE_APP_SERVICES,
8
8
  COMPOSE_GATEWAY_UPSTREAM,
9
+ COMPOSE_POOL_BUDGET,
9
10
  type ComposeSpec,
10
11
  composeProjectName,
11
12
  generateDockerCompose,
@@ -59,6 +60,28 @@ describe("self-hosted Compose — internal secret (#770)", () => {
59
60
  });
60
61
  });
61
62
 
63
+ describe("self-hosted Compose — connection budget (#1254)", () => {
64
+ const yaml = generateDockerCompose({
65
+ ...base,
66
+ images: { mode: "release", admin: ADMIN, gateway: GATEWAY },
67
+ });
68
+
69
+ it("starts Postgres with the max_connections the budget is computed from", () => {
70
+ expect(service(yaml, "postgres")).toContain(
71
+ 'command: ["postgres", "-c", "max_connections=100"]',
72
+ );
73
+ });
74
+
75
+ it("sizes the admin's two pools and the gateway's one", () => {
76
+ expect(service(yaml, "caelo-admin")).toContain(
77
+ ` CAELO_DB_POOL_MAX: "${COMPOSE_POOL_BUDGET.budget.adminPoolMax}"`,
78
+ );
79
+ expect(service(yaml, "caelo-admin")).toContain(' CAELO_DB_PUBLIC_POOL_MAX: "4"');
80
+ expect(service(yaml, "caelo-gateway")).toContain(' CAELO_DB_PUBLIC_POOL_MAX: "2"');
81
+ expect(service(yaml, "caelo-gateway")).not.toContain("CAELO_DB_POOL_MAX:");
82
+ });
83
+ });
84
+
62
85
  describe("self-hosted Compose — release images (#696)", () => {
63
86
  const yaml = generateDockerCompose({
64
87
  ...base,
@@ -132,11 +132,15 @@ describe.each(["gcp", "gcp-firebase"] as const)("%s stack ↔ upgrade parity", (
132
132
  });
133
133
 
134
134
  it("builds the admin + gateway env from the shared contracts", () => {
135
+ // #1254 — plus the pool env of the stack's connection budget: derived
136
+ // from stack config (max_connections, instance counts) an upgrade roll
137
+ // cannot see, so it is stack-owned like the remote-MCP env; a roll
138
+ // never removes a var the contract does not own (planEnvUpdate).
135
139
  expect(src).toMatch(
136
- /serviceName: "admin",[\s\S]*?contractEnv: \[\s*\.\.\.adminEnvContract\([\s\S]*?\.\.\.remoteMcpEnv\.admin,?\s*\]/,
140
+ /serviceName: "admin",[\s\S]*?contractEnv: \[\s*\.\.\.adminEnvContract\([\s\S]*?\.\.\.remoteMcpEnv\.admin,\s*(\/\/[^\n]*\n\s*)?\.\.\.poolBudget\.env\.admin,?\s*\]/,
137
141
  );
138
142
  expect(src).toMatch(
139
- /serviceName: "gateway",[\s\S]*?contractEnv: \[\s*\.\.\.gatewayEnvContract\([\s\S]*?\.\.\.remoteMcpEnv\.gateway,?\s*\]/,
143
+ /serviceName: "gateway",[\s\S]*?contractEnv: \[\s*\.\.\.gatewayEnvContract\([\s\S]*?\.\.\.remoteMcpEnv\.gateway,\s*\.\.\.poolBudget\.env\.gateway,?\s*\]/,
140
144
  );
141
145
  expect(src).toContain("envs: [...args.contractEnv],");
142
146
  });