-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add Image component for sharing Docker images
#6359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 24 commits
fd174a0
1d2f245
0d5097f
43a7d80
013b303
6b0929f
576bc66
8bf8856
b5a01dd
e552538
844979d
60bc639
5d5b26a
ef2cecd
2fa3000
a840d37
e8a69fa
022506a
8d7752d
7b84ec1
974af5d
008fbc6
ba01a21
547703e
fea4451
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,6 @@ | |
| "author": "", | ||
| "license": "ISC", | ||
| "dependencies": { | ||
| "sst": "^4" | ||
| "sst": "latest" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,3 @@ | ||
| import fs from "fs"; | ||
| import path from "path"; | ||
| import { ComponentResourceOptions, interpolate, secret } from "@pulumi/pulumi"; | ||
| import { all, output } from "@pulumi/pulumi"; | ||
| import { Input } from "../input"; | ||
|
|
@@ -13,7 +11,6 @@ import { ImageArgs, Platform } from "@pulumi/docker-build"; | |
| import { Component, Transform, transform } from "../component"; | ||
| import { | ||
| cloudwatch, | ||
| ecr, | ||
| ecs, | ||
| getCallerIdentityOutput, | ||
| getPartitionOutput, | ||
|
|
@@ -23,11 +20,11 @@ import { | |
| import { Link } from "../link"; | ||
| import { Permission } from "./permission"; | ||
| import { bootstrap } from "./helpers/bootstrap"; | ||
| import { imageBuilder } from "./helpers/container-builder"; | ||
| import { toNumber } from "../cpu"; | ||
| import { toSeconds } from "../duration"; | ||
| import { Cluster } from "./cluster"; | ||
| import { physicalName } from "../naming"; | ||
| import { Image } from "./image"; | ||
|
|
||
| export const supportedCpus = { | ||
| "0.25 vCPU": 256, | ||
|
|
@@ -1052,86 +1049,20 @@ export function createTaskDefinition( | |
| image: (() => { | ||
| if (typeof container.image === "string") return output(container.image); | ||
|
|
||
| const containerImage = container.image; | ||
| const contextPath = path.join($cli.paths.root, container.image.context); | ||
| const dockerfile = container.image.dockerfile ?? "Dockerfile"; | ||
| const dockerfilePath = path.join(contextPath, dockerfile); | ||
| const dockerIgnorePath = fs.existsSync( | ||
| path.join(contextPath, `${dockerfile}.dockerignore`), | ||
| ) | ||
| ? path.join(contextPath, `${dockerfile}.dockerignore`) | ||
| : path.join(contextPath, ".dockerignore"); | ||
|
|
||
| // add .sst to .dockerignore if not exist | ||
| const lines = fs.existsSync(dockerIgnorePath) | ||
| ? fs.readFileSync(dockerIgnorePath).toString().split("\n") | ||
| : []; | ||
| if (!lines.find((line) => line === ".sst")) { | ||
| fs.writeFileSync( | ||
| dockerIgnorePath, | ||
| [...lines, "", "# sst", ".sst"].join("\n"), | ||
| ); | ||
| } | ||
|
|
||
| // Build image | ||
| const image = imageBuilder( | ||
| ...transform( | ||
| args.transform?.image, | ||
| `${name}Image${container.name}`, | ||
| { | ||
| context: { location: contextPath }, | ||
| dockerfile: { location: dockerfilePath }, | ||
| buildArgs: containerImage.args, | ||
| secrets: all([linkEnvs, containerImage.secrets ?? {}]).apply( | ||
| ([link, secrets]) => ({ ...link, ...secrets }), | ||
| ), | ||
| target: container.image.target, | ||
| platforms: [container.image.platform], | ||
| tags: [container.name, ...(container.image.tags ?? [])].map( | ||
| (tag) => interpolate`${bootstrapData.assetEcrUrl}:${tag}`, | ||
| ), | ||
| registries: [ | ||
| ecr | ||
| .getAuthorizationTokenOutput( | ||
| { | ||
| registryId: bootstrapData.assetEcrRegistryId, | ||
| }, | ||
| { parent }, | ||
| ) | ||
| .apply((authToken) => ({ | ||
| address: authToken.proxyEndpoint, | ||
| password: secret(authToken.password), | ||
| username: authToken.userName, | ||
| })), | ||
| ], | ||
| ...(container.image.cache !== false | ||
| ? { | ||
| cacheFrom: [ | ||
| { | ||
| registry: { | ||
| ref: interpolate`${bootstrapData.assetEcrUrl}:${container.name}-cache`, | ||
| }, | ||
| }, | ||
| ], | ||
| cacheTo: [ | ||
| { | ||
| registry: { | ||
| ref: interpolate`${bootstrapData.assetEcrUrl}:${container.name}-cache`, | ||
| imageManifest: true, | ||
| ociMediaTypes: true, | ||
| mode: "max", | ||
| }, | ||
| }, | ||
| ], | ||
| } | ||
| : {}), | ||
| push: true, | ||
| }, | ||
| { parent }, | ||
| ), | ||
| ); | ||
| const image = new Image(`${name}${container.name}`, { | ||
| context: container.image.context, | ||
| dockerfile: container.image.dockerfile, | ||
| args: container.image.args, | ||
| secrets: linkEnvs, | ||
| target: container.image.target, | ||
| platforms: [container.image.platform], | ||
| tags: [container.name, ...(container.image.tags ?? [])], | ||
| transform: { | ||
| image: args.transform?.image, | ||
| }, | ||
| }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
|
|
||
| return interpolate`${bootstrapData.assetEcrUrl}@${image.digest}`; | ||
| return image.uri; | ||
| })(), | ||
| cpu: container.cpu ? toNumber(container.cpu) : undefined, | ||
| memory: container.memory ? toMBs(container.memory) : undefined, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,7 +37,7 @@ import { | |
| } from "@pulumi/aws"; | ||
| import { Permission, permission } from "./permission.js"; | ||
| import { Vpc } from "./vpc.js"; | ||
| import { Image } from "@pulumi/docker-build"; | ||
| import { Image } from "./image"; | ||
| import { rpc } from "../rpc/rpc.js"; | ||
| import { parseRoleArn } from "./helpers/arn.js"; | ||
| import { RandomBytes } from "@pulumi/random"; | ||
|
|
@@ -2234,67 +2234,15 @@ export class Function extends Component implements Link.Linkable { | |
| // The build artifact directory already exists, with all the user code and | ||
| // config files. It also has the dockerfile, we need to now just build and push to | ||
| // the container registry. | ||
| return all([isContainer, dev, bundle, containerCache]).apply( | ||
| ([ | ||
| isContainer, | ||
| dev, | ||
| bundle, // We need the bundle to be resolved because of implicit dockerfiles even though we don't use it here | ||
| containerCache, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are no longer using this variable, perhaps we can remove it?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which variable? bundle is already removed |
||
| ]) => { | ||
| if (!isContainer || dev) return; | ||
|
|
||
| const authToken = ecr.getAuthorizationTokenOutput({ | ||
| registryId: bootstrapData.assetEcrRegistryId, | ||
| return all([isContainer, dev, architecture]).apply( | ||
| ([isContainer, dev, architecture]) => { | ||
| if (!isContainer || dev) return; | ||
| return new Image(name, { | ||
| context: `.sst/artifacts/${name}-src`, | ||
| tags: ['latest'], | ||
| platforms: [architecture === "arm64" ? "linux/arm64" : "linux/amd64"], | ||
| }); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should pass
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
|
|
||
| return new Image( | ||
| `${name}Image`, | ||
| { | ||
| tags: [$interpolate`${bootstrapData.assetEcrUrl}:latest`], | ||
| context: { | ||
| location: path.join( | ||
| $cli.paths.work, | ||
| "artifacts", | ||
| `${name}-src`, | ||
| ), | ||
| }, | ||
| ...(containerCache !== false | ||
| ? { | ||
| cacheFrom: [ | ||
| { | ||
| registry: { | ||
| ref: $interpolate`${bootstrapData.assetEcrUrl}:${name}-cache`, | ||
| }, | ||
| }, | ||
| ], | ||
| cacheTo: [ | ||
| { | ||
| registry: { | ||
| ref: $interpolate`${bootstrapData.assetEcrUrl}:${name}-cache`, | ||
| imageManifest: true, | ||
| ociMediaTypes: true, | ||
| mode: "max", | ||
| }, | ||
| }, | ||
| ], | ||
| } | ||
| : {}), | ||
| platforms: [ | ||
| architecture.apply((v) => | ||
| v === "arm64" ? "linux/arm64" : "linux/amd64", | ||
| ), | ||
| ], | ||
| push: true, | ||
| registries: [ | ||
| authToken.apply((authToken) => ({ | ||
| address: authToken.proxyEndpoint, | ||
| username: authToken.userName, | ||
| password: secret(authToken.password), | ||
| })), | ||
| ], | ||
| }, | ||
| { parent }, | ||
| ); | ||
| }, | ||
| ); | ||
| } | ||
|
|
@@ -2513,9 +2461,7 @@ export class Function extends Component implements Link.Linkable { | |
| ...(isContainer | ||
| ? { | ||
| packageType: "Image", | ||
| imageUri: imageAsset!.ref.apply( | ||
| (ref) => ref?.replace(":latest", ""), | ||
| ), | ||
| imageUri: imageAsset!.uri, | ||
| imageConfig: { | ||
| commands: [ | ||
| all([handler, runtime]).apply(([handler, runtime]) => { | ||
|
|
||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.