in packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts [452:566]
constructor(scope: Construct, id: string, props: DockerImageAssetProps) {
super(scope, id);
// none of the properties use tokens
validateProps(props);
// resolve full path
const dir = path.resolve(props.directory);
if (!fs.existsSync(dir)) {
throw new ValidationError(`Cannot find image directory at ${dir}`, this);
}
// validate the docker file exists
this.dockerfilePath = props.file || 'Dockerfile';
const file = path.join(dir, this.dockerfilePath);
if (!fs.existsSync(file)) {
throw new ValidationError(`Cannot find file at ${file}`, this);
}
const defaultIgnoreMode = FeatureFlags.of(this).isEnabled(cxapi.DOCKER_IGNORE_SUPPORT)
? IgnoreMode.DOCKER : IgnoreMode.GLOB;
let ignoreMode = props.ignoreMode ?? defaultIgnoreMode;
let exclude: string[] = props.exclude || [];
const ignore = path.join(dir, '.dockerignore');
if (fs.existsSync(ignore)) {
const dockerIgnorePatterns = fs.readFileSync(ignore).toString().split('\n').filter(e => !!e);
exclude = [
...dockerIgnorePatterns,
...exclude,
// Ensure .dockerignore is included no matter what.
'!.dockerignore',
];
}
// Ensure the Dockerfile is included no matter what.
exclude.push('!' + path.basename(file));
// Ensure the cdk.out folder is not included to avoid infinite loops.
const cdkout = Stage.of(this)?.outdir ?? 'cdk.out';
exclude.push(cdkout);
if (props.repositoryName) {
Annotations.of(this).addWarningV2('@aws-cdk/aws-ecr-assets:repositoryNameDeprecated', 'DockerImageAsset.repositoryName is deprecated. Override "core.Stack.addDockerImageAsset" to control asset locations');
}
// include build context in "extra" so it will impact the hash
const extraHash: { [field: string]: any } = {};
if (props.invalidation?.extraHash !== false && props.extraHash) { extraHash.user = props.extraHash; }
if (props.invalidation?.buildArgs !== false && props.buildArgs) { extraHash.buildArgs = props.buildArgs; }
if (props.invalidation?.buildSecrets !== false && props.buildSecrets) { extraHash.buildSecrets = props.buildSecrets; }
if (props.invalidation?.buildSsh !== false && props.buildSsh) {extraHash.buildSsh = props.buildSsh; }
if (props.invalidation?.target !== false && props.target) { extraHash.target = props.target; }
if (props.invalidation?.file !== false && props.file) { extraHash.file = props.file; }
if (props.invalidation?.repositoryName !== false && props.repositoryName) { extraHash.repositoryName = props.repositoryName; }
if (props.invalidation?.networkMode !== false && props.networkMode) { extraHash.networkMode = props.networkMode; }
if (props.invalidation?.platform !== false && props.platform) { extraHash.platform = props.platform; }
if (props.invalidation?.outputs !== false && props.outputs) { extraHash.outputs = props.outputs; }
// add "salt" to the hash in order to invalidate the image in the upgrade to
// 1.21.0 which removes the AdoptedRepository resource (and will cause the
// deletion of the ECR repository the app used).
extraHash.version = '1.21.0';
const staging = new AssetStaging(this, 'Staging', {
...props,
follow: props.followSymlinks ?? toSymlinkFollow(props.follow),
exclude,
ignoreMode,
sourcePath: dir,
extraHash: Object.keys(extraHash).length === 0
? undefined
: JSON.stringify(extraHash),
});
this.assetHash = staging.assetHash;
this.sourceHash = this.assetHash;
const stack = Stack.of(this);
this.assetPath = staging.relativeStagedPath(stack);
this.assetName = props.assetName;
this.dockerBuildArgs = props.buildArgs;
this.dockerBuildSecrets = props.buildSecrets;
this.dockerBuildSsh = props.buildSsh;
this.dockerBuildTarget = props.target;
this.dockerOutputs = props.outputs;
this.dockerCacheFrom = props.cacheFrom;
this.dockerCacheTo = props.cacheTo;
this.dockerCacheDisabled = props.cacheDisabled;
const location = stack.synthesizer.addDockerImageAsset({
directoryName: this.assetPath,
assetName: this.assetName,
dockerBuildArgs: this.dockerBuildArgs,
dockerBuildSecrets: this.dockerBuildSecrets,
dockerBuildSsh: this.dockerBuildSsh,
dockerBuildTarget: this.dockerBuildTarget,
dockerFile: props.file,
sourceHash: staging.assetHash,
networkMode: props.networkMode?.mode,
platform: props.platform?.platform,
dockerOutputs: this.dockerOutputs,
dockerCacheFrom: this.dockerCacheFrom,
dockerCacheTo: this.dockerCacheTo,
dockerCacheDisabled: this.dockerCacheDisabled,
displayName: props.displayName ?? props.assetName ?? Names.stackRelativeConstructPath(this),
});
this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName);
this.imageUri = location.imageUri;
this.imageTag = location.imageTag ?? this.assetHash;
}