diff --git a/packages/cdk-docker-cluster/README.md b/packages/cdk-docker-cluster/README.md index e4c892d8..50ccb92e 100644 --- a/packages/cdk-docker-cluster/README.md +++ b/packages/cdk-docker-cluster/README.md @@ -4,11 +4,37 @@ This construct creates a load balanced Fargate service, for which it builds a Do ## Examples +The minimum needed to get a DockerCluster up and running is a path to the source directory that contains a Dockerfile, relative to the CDK app, and the port on which your container needs to be accessible. + +```ts +new DockerCluster(this, "DockerCluster", { + source: "../path/to/source", + port: 3000, +}); +``` + +### With Monorepo Build + +If your Dockerfile is not located directly in the build context directory, which is common for monorepositories, you can provide the path to the Dockerfile relative to the source directory. + ```ts new DockerCluster({ source: { - path: "../../", // path to Docker build context - file: "apps/myApp/DockerFile", // path to Dockerfile + directory: "../path/to/source", + file: "./apps/myApp/DockerFile", + }, + // ... +}); +``` + +### With Arguments and Secrets + +Additionally, if your Dockerfile requires arguments and/or secrets, you can provide those as well. + +```ts +new DockerCluster({ + source: { + // ... arguments: { MY_BUILD_ARGUMENT: "foo", }, @@ -16,17 +42,24 @@ new DockerCluster({ myBuildSecret: DockerBuildSecret.fromSrc("./foo"), }, }, - port: 3000, - cpu: 1024, // 1vCPU - memory: 4096, // 4GB - tasks: { - minimum: 1, - maximum: 10, - }, + // ... +}); +``` + +### With ContainerImage + +Alternatively, you can provide your own `ContainerImage` instance. There are many ways to construct a `ContainerImage`. For example, you can create one from an asset and take full control over how CDK builds your Docker image. + +```ts +new DockerCluster({ + source: ContainerImage.fromAsset("../path/to/source", { + // ... + }), + // ... }); ``` -### From Tarball +Or, if you want to build your Docker image outside of CDK, you can create a `ContainerImage` from a path to your image's tarball. ```ts new DockerCluster({ @@ -35,15 +68,46 @@ new DockerCluster({ }); ``` -### From Image Asset +Or if the image you need is published to a registry, you can create your +`ContainerImage` from a registry path. You can provide credentials in case the registry is private. ```ts new DockerCluster({ - source: ContainerImage.fromImageAsset( - new DockerImageAsset(this, "ImageAsset", { - // ... - }), - ), + source: ContainerImage.fromRegistry("node:20"), // ... }); ``` + +Finally, you can create a `ContainerImage` from an image that you have published to an ECR repository. + +```ts +new DockerCluster({ + source: ContainerImage.fromEcrRepository(myRespository, "my-tag"), + // ... +}); +``` + +### With Scaling + +The `DockerCluster` construct supports both vertical and horizontal scaling. + +```ts +new DockerCluster(this, "DockerCluster", { + // ... + cpu: 1024, // 1vCPU + memory: 4096, // 4GB + tasks: 3, +}); +``` + +Horizontal auto-scaling is also supported. + +```ts +new DockerCluster(this, "DockerCluster", { + // ... + tasks: { + minimum: 1, + maximum: 5, + }, +}); +``` diff --git a/packages/cdk-docker-cluster/src/constructs/DockerCluster.ts b/packages/cdk-docker-cluster/src/constructs/DockerCluster.ts index c1ac542c..fbfc3b86 100644 --- a/packages/cdk-docker-cluster/src/constructs/DockerCluster.ts +++ b/packages/cdk-docker-cluster/src/constructs/DockerCluster.ts @@ -2,11 +2,12 @@ import { SiteDistribution, SiteDistributionProps, } from "@codedazur/cdk-site-distribution"; +import { App, Stack } from "aws-cdk-lib"; import { Certificate } from "aws-cdk-lib/aws-certificatemanager"; import { OriginProtocolPolicy } from "aws-cdk-lib/aws-cloudfront"; import { LoadBalancerV2Origin } from "aws-cdk-lib/aws-cloudfront-origins"; import { DockerImageAsset, Platform } from "aws-cdk-lib/aws-ecr-assets"; -import { Cluster, ContainerImage } from "aws-cdk-lib/aws-ecs"; +import { AssetImageProps, Cluster, ContainerImage } from "aws-cdk-lib/aws-ecs"; import { ApplicationLoadBalancedFargateService, ApplicationLoadBalancedFargateServiceProps, @@ -14,7 +15,7 @@ import { import { Construct } from "constructs"; export interface DockerClusterProps { - source: ContainerImage | DockerBuildProps; + source: string | SourceProps | ContainerImage; port?: number; tasks?: | number @@ -27,8 +28,9 @@ export interface DockerClusterProps { distribution?: Omit; } -interface DockerBuildProps { - path: string; +interface SourceProps { + directory: string; + exclude?: string[]; file?: string; arguments?: Record; secrets?: Record; @@ -54,25 +56,28 @@ export class DockerCluster extends Construct { this.image = this.props.source instanceof ContainerImage ? this.props.source - : this.createImage(); + : this.createImage(this.props.source); this.service = this.createService(); this.distribution = this.createDistribution(); } - protected createImage() { - const props = this.props.source as DockerBuildProps; - - const asset = new DockerImageAsset(this, "Image", { - directory: props.path, - file: props.file, - exclude: ["**/cdk.out"], - buildArgs: props.arguments, - buildSecrets: props.secrets, + protected createImage(source: string | SourceProps) { + const props: Partial = { + exclude: [`**/${this.getOutputDirectory()}`], platform: Platform.LINUX_AMD64, - }); + }; + + if (typeof source === "string") { + return ContainerImage.fromAsset(source, props); + } - return ContainerImage.fromDockerImageAsset(asset); + return ContainerImage.fromAsset(source.directory, { + ...props, + file: source.file, + buildArgs: source.arguments, + buildSecrets: source.secrets, + }); } protected createService() { @@ -87,7 +92,6 @@ export class DockerCluster extends Construct { memoryLimitMiB: this.props.memory, desiredCount: desiredTasks, taskImageOptions: { - // image: ContainerImage.fromEcrRepository(image.repository, image.imageTag), image: this.image, containerPort: this.props.port, }, @@ -119,4 +123,8 @@ export class DockerCluster extends Construct { }), }); } + + protected getOutputDirectory() { + return App.of(this)?.outdir ?? "cdk.out"; + } } diff --git a/packages/cdk-next-app/README.md b/packages/cdk-next-app/README.md index 2300170b..c24d308c 100644 --- a/packages/cdk-next-app/README.md +++ b/packages/cdk-next-app/README.md @@ -22,7 +22,7 @@ const nextConfig = { ### Docker -In order to use this construct, your Next.js application needs to be configure for Docker deployments. See the [official documentation](https://nextjs.org/docs/pages/building-your-application/deploying#docker-image) for more information. +In order to use this construct, your Next.js application needs to be configured for Docker deployments. See the [official documentation](https://nextjs.org/docs/pages/building-your-application/deploying#docker-image) for more information. ## Example @@ -32,9 +32,7 @@ For a non-monorepo build, simply provide the path to the directory that contains ```ts new NextApp(this, "NextApp", { - source: { - path: "../next", - }, + source: "../next", }); ``` @@ -45,7 +43,7 @@ For monorepo builds, set the build context to the root of your monorepo, and pro ```ts new NextApp(this, "NextApp", { source: { - path: "../../", + directory: "../../", file: "apps/next/Dockerfile", }, }); @@ -89,8 +87,6 @@ new NextApp(this, "NextApp", { ```ts new NextApp(this, "NextApp", { // ... - cpu: 1024, - memory: 4096, tasks: { minimum: 1, maximum: 5, diff --git a/packages/cdk-static-site/README.md b/packages/cdk-static-site/README.md index 69c6dac0..7e6f3011 100644 --- a/packages/cdk-static-site/README.md +++ b/packages/cdk-static-site/README.md @@ -4,10 +4,21 @@ The minimum needed to get a `StaticSite` up and running is to provide the path to the directory that you want to deploy as your website. +```ts +new StaticSite({ + source: "./path/to/build/output", +}); +``` + +### With Excludes + +If your output directory contains files you don't want to include in the deployment, you can exclude those with glob patterns. + ```ts new StaticSite({ source: { directory: "./path/to/build/output", + excludes: ["foo/*"], }, }); ``` diff --git a/packages/cdk-static-site/src/constructs/StaticSite.ts b/packages/cdk-static-site/src/constructs/StaticSite.ts index 8d1372cd..84258e18 100644 --- a/packages/cdk-static-site/src/constructs/StaticSite.ts +++ b/packages/cdk-static-site/src/constructs/StaticSite.ts @@ -12,10 +12,12 @@ import { Secret } from "aws-cdk-lib/aws-secretsmanager"; import { Construct } from "constructs"; export interface StaticSiteProps { - source: { - directory: string; - exclude?: string[]; - }; + source: + | string + | { + directory: string; + exclude?: string[]; + }; bucket?: { accelerate?: boolean; }; @@ -114,9 +116,11 @@ export class StaticSite extends Construct { protected createDeployment() { return new BucketDeployment(this, "BucketDeployment", { sources: [ - Source.asset(this.props.source.directory, { - exclude: this.props.source.exclude, - }), + typeof this.props.source === "string" + ? Source.asset(this.props.source) + : Source.asset(this.props.source.directory, { + exclude: this.props.source.exclude, + }), ], destinationBucket: this.bucket, destinationKeyPrefix: this.props.deployment?.prefix,