sst 2.24.23 → 2.24.25

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.
@@ -15,7 +15,6 @@ export const consoleCommand = async (program) => program.command("console", "Sta
15
15
  ]);
16
16
  clear();
17
17
  printHeader({ console: true, hint: "ready!" });
18
- await exit();
19
18
  }
20
19
  catch (e) {
21
20
  await exitWithError(e);
@@ -566,6 +566,19 @@ export interface ContainerProps {
566
566
  * ```
567
567
  */
568
568
  file?: string;
569
+ /**
570
+ * Build args to pass to the docker build command.
571
+ * @default No build args
572
+ * @example
573
+ * ```js
574
+ * container: {
575
+ * buildArgs: {
576
+ * FOO: "bar"
577
+ * }
578
+ * }
579
+ * ```
580
+ */
581
+ buildArgs?: Record<string, string>;
569
582
  }
570
583
  /**
571
584
  * Used to configure additional files to copy into the function bundle
@@ -206,6 +206,9 @@ export class Function extends CDKFunction {
206
206
  ...(props.container?.file
207
207
  ? { file: props.container.file }
208
208
  : {}),
209
+ ...(props.container?.buildArgs
210
+ ? { buildArgs: props.container.buildArgs }
211
+ : {}),
209
212
  exclude: [".sst"],
210
213
  ignoreMode: IgnoreMode.GLOB,
211
214
  }),
@@ -31,6 +31,19 @@ export interface JobContainerProps {
31
31
  * ```
32
32
  */
33
33
  file?: string;
34
+ /**
35
+ * Build args to pass to the docker build command.
36
+ * @default No build args
37
+ * @example
38
+ * ```js
39
+ * container: {
40
+ * buildArgs: {
41
+ * FOO: "bar"
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ buildArgs?: Record<string, string>;
34
47
  }
35
48
  export interface JobProps {
36
49
  /**
package/constructs/Job.js CHANGED
@@ -213,6 +213,7 @@ export class Job extends Construct {
213
213
  ? Platform.custom("linux/arm64")
214
214
  : Platform.custom("linux/amd64"),
215
215
  file: container?.file,
216
+ buildArgs: container?.buildArgs,
216
217
  exclude: [".sst"],
217
218
  ignoreMode: IgnoreMode.GLOB,
218
219
  });
@@ -4,7 +4,7 @@ import { SSTConstruct } from "./Construct.js";
4
4
  import { Permissions } from "./util/permission.js";
5
5
  import { FunctionBindingProps } from "./util/functionBinding.js";
6
6
  import { IVpc } from "aws-cdk-lib/aws-ec2";
7
- import { Cluster, ContainerDefinitionOptions } from "aws-cdk-lib/aws-ecs";
7
+ import { Cluster, ContainerDefinitionOptions, CpuArchitecture, FargateServiceProps } from "aws-cdk-lib/aws-ecs";
8
8
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
9
9
  import { ApplicationTargetGroupProps } from "aws-cdk-lib/aws-elasticloadbalancingv2";
10
10
  declare const supportedCpus: {
@@ -30,7 +30,18 @@ export interface ServiceProps {
30
30
  */
31
31
  file?: string;
32
32
  /**
33
- * The amount of cpu allocated.
33
+ * The CPU architecture of the container.
34
+ * @default "x86_64"
35
+ * @example
36
+ * ```js
37
+ * {
38
+ * architecture: "arm64",
39
+ * }
40
+ * ```
41
+ */
42
+ architecture?: Lowercase<keyof Pick<typeof CpuArchitecture, "ARM64" | "X86_64">>;
43
+ /**
44
+ * The amount of CPU allocated.
34
45
  * @default "0.25 vCPU"
35
46
  * @example
36
47
  * ```js
@@ -215,6 +226,23 @@ export interface ServiceProps {
215
226
  * ```
216
227
  */
217
228
  waitForInvalidation?: boolean;
229
+ build?: {
230
+ /**
231
+ * Build args to pass to the docker build command.
232
+ * @default No build args
233
+ * @example
234
+ * ```js
235
+ * {
236
+ * build: {
237
+ * buildArgs: {
238
+ * FOO: "bar"
239
+ * }
240
+ * }
241
+ * }
242
+ * ```
243
+ */
244
+ buildArgs?: Record<string, string>;
245
+ };
218
246
  dev?: {
219
247
  /**
220
248
  * When running `sst dev, site is not deployed. This is to ensure `sst dev` can start up quickly.
@@ -286,6 +314,20 @@ export interface ServiceProps {
286
314
  * ```
287
315
  */
288
316
  applicationLoadBalancerTargetGroup?: ApplicationTargetGroupProps;
317
+ /**
318
+ * Customize the Fargate Service.
319
+ * @example
320
+ * ```js
321
+ * {
322
+ * cdk: {
323
+ * fargateService: {
324
+ * circuitBreaker: { rollback: true }
325
+ * }
326
+ * }
327
+ * }
328
+ * ```
329
+ */
330
+ fargateService?: Omit<FargateServiceProps, "cluster" | "taskDefinition">;
289
331
  /**
290
332
  * Customizing the container definition for the ECS task.
291
333
  * @example
@@ -294,14 +336,16 @@ export interface ServiceProps {
294
336
  * cdk: {
295
337
  * container: {
296
338
  * healthCheck: {
297
- * command: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"],
298
- * },
339
+ * command: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
340
+ * }
299
341
  * }
300
342
  * }
301
343
  * }
302
344
  * ```
303
345
  */
304
- container?: Omit<ContainerDefinitionOptions, "image">;
346
+ container?: Omit<ContainerDefinitionOptions, "image"> & {
347
+ image?: ContainerDefinitionOptions["image"];
348
+ };
305
349
  /**
306
350
  * Runs codebuild job in the specified VPC. Note this will only work once deployed.
307
351
  *
@@ -322,8 +366,9 @@ export interface ServiceProps {
322
366
  };
323
367
  }
324
368
  type ServiceNormalizedProps = ServiceProps & {
325
- path: Exclude<ServiceProps["path"], undefined>;
369
+ architecture: Exclude<ServiceProps["architecture"], undefined>;
326
370
  cpu: Exclude<ServiceProps["cpu"], undefined>;
371
+ path: Exclude<ServiceProps["path"], undefined>;
327
372
  memory: Exclude<ServiceProps["memory"], undefined>;
328
373
  port: Exclude<ServiceProps["port"], undefined>;
329
374
  logRetention: Exclude<ServiceProps["logRetention"], undefined>;
@@ -19,7 +19,7 @@ import { attachPermissionsToRole } from "./util/permission.js";
19
19
  import { bindEnvironment, bindPermissions, getParameterPath, getReferencedSecrets, } from "./util/functionBinding.js";
20
20
  import { useProject } from "../project.js";
21
21
  import { Vpc, } from "aws-cdk-lib/aws-ec2";
22
- import { AwsLogDriver, Cluster, FargateTaskDefinition, ContainerImage, FargateService, } from "aws-cdk-lib/aws-ecs";
22
+ import { AwsLogDriver, Cluster, ContainerImage, CpuArchitecture, FargateService, FargateTaskDefinition, } from "aws-cdk-lib/aws-ecs";
23
23
  import { LogGroup, LogRetention, RetentionDays } from "aws-cdk-lib/aws-logs";
24
24
  import { Platform } from "aws-cdk-lib/aws-ecr-assets";
25
25
  import { ApplicationLoadBalancer, } from "aws-cdk-lib/aws-elasticloadbalancingv2";
@@ -153,6 +153,7 @@ export class Service extends Construct {
153
153
  this.id = id;
154
154
  this.props = {
155
155
  path: ".",
156
+ architecture: props?.architecture || "x86_64",
156
157
  cpu: props?.cpu || "0.25 vCPU",
157
158
  memory: props?.memory || "0.5 GB",
158
159
  port: props?.port || 3000,
@@ -188,16 +189,19 @@ export class Service extends Construct {
188
189
  this.attachPermissionsForService(props?.permissions || []);
189
190
  Object.entries(props?.environment || {}).map(([key, value]) => this.addEnvironmentForService(key, value));
190
191
  useDeferredTasks().add(async () => {
191
- if (!app.isRunningSSTTest()) {
192
+ if (!app.isRunningSSTTest() && !props?.cdk?.container?.image) {
192
193
  Colors.line(`➜ Building the container image for the "${this.node.id}" service...`);
193
194
  // Build app
194
195
  let dockerfile;
196
+ // case: custom Dockerfile provided
195
197
  if (this.props.file) {
196
198
  dockerfile = this.props.file;
197
199
  }
200
+ // case: default Dockerfile found
198
201
  else if (await existsAsync(path.join(this.props.path, "Dockerfile"))) {
199
202
  dockerfile = "Dockerfile";
200
203
  }
204
+ // case: nixpack
201
205
  else {
202
206
  await this.createNixpacksBuilder();
203
207
  dockerfile = await this.runNixpacksBuild();
@@ -384,7 +388,7 @@ export class Service extends Construct {
384
388
  }));
385
389
  }
386
390
  createService(vpc) {
387
- const { cpu, memory, port, logRetention, cdk } = this.props;
391
+ const { architecture, cpu, memory, port, logRetention, cdk } = this.props;
388
392
  const app = this.node.root;
389
393
  const clusterName = app.logicalPrefixedName(this.node.id);
390
394
  const logGroup = new LogRetention(this, "LogRetention", {
@@ -402,6 +406,11 @@ export class Service extends Construct {
402
406
  // @ts-ignore
403
407
  memoryLimitMiB: supportedMemories[cpu][memory],
404
408
  cpu: supportedCpus[cpu],
409
+ runtimePlatform: {
410
+ cpuArchitecture: architecture === "arm64"
411
+ ? CpuArchitecture.ARM64
412
+ : CpuArchitecture.X86_64,
413
+ },
405
414
  });
406
415
  const container = taskDefinition.addContainer("Container", {
407
416
  logging: new AwsLogDriver({
@@ -415,11 +424,14 @@ export class Service extends Construct {
415
424
  SST_SSM_PREFIX: useProject().config.ssmPrefix,
416
425
  },
417
426
  ...cdk?.container,
418
- image: { bind: () => ({ imageName: "placeholder" }) },
427
+ image: cdk?.container?.image ?? {
428
+ bind: () => ({ imageName: "placeholder" }),
429
+ },
419
430
  });
420
431
  const service = new FargateService(this, "Service", {
421
432
  cluster,
422
433
  taskDefinition,
434
+ ...cdk?.fargateService,
423
435
  });
424
436
  return { cluster, taskDefinition, container, service };
425
437
  }
@@ -595,13 +607,16 @@ export class Service extends Construct {
595
607
  return ".nixpacks/Dockerfile";
596
608
  }
597
609
  async runDockerBuild(dockerfile) {
610
+ const { path: servicePath, architecture, build } = this.props;
611
+ const platform = architecture === "arm64" ? "linux/arm64" : "linux/amd64";
598
612
  try {
599
613
  await execAsync([
600
614
  "docker",
601
615
  "build",
602
616
  `-t sst-build:service-${this.node.id}`,
603
- "--platform=linux/amd64",
604
- `-f ${path.join(this.props.path, dockerfile)}`,
617
+ `--platform ${platform}`,
618
+ `-f ${path.join(servicePath, dockerfile)}`,
619
+ ...Object.entries(build?.buildArgs || {}).map(([k, v]) => `--build-arg ${k}=${v}`),
605
620
  this.props.path,
606
621
  ].join(" "), {
607
622
  env: {
@@ -615,9 +630,11 @@ export class Service extends Construct {
615
630
  }
616
631
  }
617
632
  updateContainerImage(dockerfile, taskDefinition, container) {
618
- const image = ContainerImage.fromAsset(this.props.path, {
619
- platform: Platform.LINUX_AMD64,
633
+ const { path: servicePath, architecture, build } = this.props;
634
+ const image = ContainerImage.fromAsset(servicePath, {
635
+ platform: architecture === "arm64" ? Platform.LINUX_ARM64 : Platform.LINUX_AMD64,
620
636
  file: dockerfile,
637
+ buildArgs: build?.buildArgs,
621
638
  exclude: [".sst"],
622
639
  ignoreMode: IgnoreMode.GLOB,
623
640
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.24.23",
4
+ "version": "2.24.25",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -58,6 +58,7 @@ export const useContainerHandler = Context.memo(async () => {
58
58
  ...(input.props.container?.file
59
59
  ? [`-f ${input.props.container.file}`]
60
60
  : []),
61
+ ...Object.entries(input.props.container?.buildArgs || {}).map(([k, v]) => `--build-arg ${k}=${v}`),
61
62
  `.`,
62
63
  ].join(" "), {
63
64
  cwd: project,
@@ -84,6 +85,7 @@ export const useContainerHandler = Context.memo(async () => {
84
85
  ...(input.props.container?.file
85
86
  ? [`-f ${input.props.container.file}`]
86
87
  : []),
88
+ ...Object.entries(input.props.container?.buildArgs || {}).map(([k, v]) => `--build-arg ${k}=${v}`),
87
89
  `--platform ${platform}`,
88
90
  `.`,
89
91
  ].join(" "), {