Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions packages/alchemy/src/Cloudflare/Containers/ContainerApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,24 @@ export namespace ContainerApplication {
>[number];
export type Constraints = {
tier?: number;
/**
* Limit container placement to specific geographic regions.
*/
regions?: (
| "ENAM"
| "WNAM"
| "EEUR"
| "WEUR"
| "APAC"
| "SAM"
| "ME"
| "OC"
| "AFR"
)[];
/**
* Restrict container placement to a compliance/data-residency boundary.
*/
jurisdiction?: "eu" | "fedramp";
};
export type Affinities = {
colocation?: "datacenter";
Expand Down Expand Up @@ -639,9 +657,11 @@ export type ContainerShape = Main<ContainerServices>;
* ```
*
* `schedulingPolicy` selects the control-plane placement strategy,
* `constraints.tier` restricts which capacity tier instances may land on, and
* `affinities.colocation` keeps related instances in the same datacenter to
* reduce inter-instance latency.
* `constraints.tier` restricts which capacity tier instances may land on,
* `constraints.regions`/`constraints.jurisdiction` restrict placement to
* geographic regions or a compliance boundary (e.g. `jurisdiction: "eu"` for
* data residency), and `affinities.colocation` keeps related instances in the
* same datacenter to reduce inter-instance latency.
*
* ### Rollouts
* When an update changes the configuration, `rollout` controls how the new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,36 @@ describe("ContainerApplication", () => {
}).pipe(logLevel),
);

// Placement constraints are a typed pass-through: `constraints.regions`
// and `constraints.jurisdiction` are forwarded verbatim to
// `createContainerApplication` and read back unchanged. This does not
// assert an instance actually lands in the requested region/jurisdiction
// (capacity is account/plan-dependent) — only that the Alchemy API
// boundary threads the fields through without dropping or renaming them.
test.provider("placement constraints round-trip", (scratch) =>
Effect.gen(function* () {
yield* scratch.destroy();

const deployed = yield* scratch.deploy(
Effect.gen(function* () {
return {
app: yield* Cloudflare.Container("ConstrainedPlacement", {
image: "mendhak/http-https-echo:latest",
constraints: { regions: ["WEUR", "EEUR"], jurisdiction: "eu" },
}).Application,
};
}),
);

expect(deployed.app.constraints).toEqual({
regions: ["WEUR", "EEUR"],
jurisdiction: "eu",
});

yield* scratch.destroy();
}).pipe(logLevel),
);

// Issue #953 (2): an `image` that already references the target registry
// (e.g. pushed by CI) is deployed as-is — no docker pull/tag/push
// round-trip. The first deploy pushes a public image into the account
Expand Down