@alchemy.run/docker 2.0.0-beta.85 → 2.0.0-beta.86
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.
- package/README.md +16 -0
- package/lib/Bootstrap.d.ts.map +1 -1
- package/lib/Bootstrap.js +2 -1
- package/lib/Bootstrap.js.map +1 -1
- package/lib/BuildCache.d.ts +87 -0
- package/lib/BuildCache.d.ts.map +1 -0
- package/lib/BuildCache.js +39 -0
- package/lib/BuildCache.js.map +1 -0
- package/lib/BuildHash.d.ts +9 -1
- package/lib/BuildHash.d.ts.map +1 -1
- package/lib/BuildHash.js +51 -19
- package/lib/BuildHash.js.map +1 -1
- package/lib/BuildPlan.d.ts +202 -0
- package/lib/BuildPlan.d.ts.map +1 -0
- package/lib/BuildPlan.js +514 -0
- package/lib/BuildPlan.js.map +1 -0
- package/lib/Container.d.ts +24 -1
- package/lib/Container.d.ts.map +1 -1
- package/lib/Container.js +14 -0
- package/lib/Container.js.map +1 -1
- package/lib/Context.d.ts +20 -1
- package/lib/Context.d.ts.map +1 -1
- package/lib/Context.js +15 -0
- package/lib/Context.js.map +1 -1
- package/lib/Docker.d.ts +33 -0
- package/lib/Docker.d.ts.map +1 -1
- package/lib/Docker.js +23 -2
- package/lib/Docker.js.map +1 -1
- package/lib/Dockerfile.d.ts +0 -2
- package/lib/Dockerfile.d.ts.map +1 -1
- package/lib/Dockerfile.js.map +1 -1
- package/lib/DockerfileParser.d.ts +125 -0
- package/lib/DockerfileParser.d.ts.map +1 -0
- package/lib/DockerfileParser.js +1040 -0
- package/lib/DockerfileParser.js.map +1 -0
- package/lib/HealthcheckCommand.d.ts.map +1 -1
- package/lib/HealthcheckCommand.js.map +1 -1
- package/lib/Image.d.ts +40 -12
- package/lib/Image.d.ts.map +1 -1
- package/lib/Image.js +41 -9
- package/lib/Image.js.map +1 -1
- package/lib/ImageArchive.d.ts +41 -0
- package/lib/ImageArchive.d.ts.map +1 -0
- package/lib/ImageArchive.js +54 -0
- package/lib/ImageArchive.js.map +1 -0
- package/lib/ImageSource.d.ts +100 -11
- package/lib/ImageSource.d.ts.map +1 -1
- package/lib/ImageSource.js +219 -73
- package/lib/ImageSource.js.map +1 -1
- package/lib/Network.d.ts +175 -3
- package/lib/Network.d.ts.map +1 -1
- package/lib/Network.js +296 -8
- package/lib/Network.js.map +1 -1
- package/lib/Providers.d.ts.map +1 -1
- package/lib/Providers.js.map +1 -1
- package/lib/Registry.d.ts.map +1 -1
- package/lib/Registry.js.map +1 -1
- package/lib/RegistryError.d.ts.map +1 -1
- package/lib/RegistryError.js.map +1 -1
- package/lib/RemoteImage.d.ts.map +1 -1
- package/lib/RemoteImage.js.map +1 -1
- package/lib/Service.d.ts.map +1 -1
- package/lib/Service.js.map +1 -1
- package/lib/ServiceImage.d.ts.map +1 -1
- package/lib/ServiceImage.js.map +1 -1
- package/lib/ShellWord.d.ts +28 -0
- package/lib/ShellWord.d.ts.map +1 -0
- package/lib/ShellWord.js +301 -0
- package/lib/ShellWord.js.map +1 -0
- package/lib/Swarm.d.ts.map +1 -1
- package/lib/Swarm.js.map +1 -1
- package/lib/Volume.d.ts +24 -1
- package/lib/Volume.d.ts.map +1 -1
- package/lib/Volume.js +16 -0
- package/lib/Volume.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +9 -9
- package/src/Bootstrap.ts +2 -0
- package/src/BuildCache.ts +111 -0
- package/src/BuildHash.ts +73 -24
- package/src/BuildPlan.ts +758 -0
- package/src/Container.ts +31 -1
- package/src/Context.ts +27 -1
- package/src/Docker.ts +56 -2
- package/src/Dockerfile.ts +0 -2
- package/src/DockerfileParser.ts +1152 -0
- package/src/Image.ts +45 -14
- package/src/ImageArchive.ts +77 -0
- package/src/ImageSource.ts +322 -103
- package/src/Network.ts +432 -10
- package/src/ShellWord.ts +326 -0
- package/src/Volume.ts +33 -1
package/README.md
CHANGED
|
@@ -43,6 +43,22 @@ export default Alchemy.Stack(
|
|
|
43
43
|
|
|
44
44
|
`alchemy deploy` pulls the image and starts the container. Change a prop and the next deploy replaces only what changed; `alchemy destroy` removes all of it.
|
|
45
45
|
|
|
46
|
+
## Network configuration
|
|
47
|
+
|
|
48
|
+
A network can be internal, attachable, and pinned to an explicit subnet:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const internalNetwork = yield* Docker.Network("InternalNetwork", {
|
|
52
|
+
internal: true,
|
|
53
|
+
attachable: true,
|
|
54
|
+
ipam: {
|
|
55
|
+
config: [{ subnet: "10.50.0.0/24", gateway: "10.50.0.1" }],
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Without `ipam`, Docker picks the subnet and gateway. Network settings are fixed at creation, so changing one replaces the network. See [local services](https://alchemy.run/docker/local-services) for dual-stack networks and driver options.
|
|
61
|
+
|
|
46
62
|
## Learn more
|
|
47
63
|
|
|
48
64
|
- [Docker on alchemy.run](https://alchemy.run/docker)
|
package/lib/Bootstrap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Bootstrap.d.ts","
|
|
1
|
+
{"version":3,"file":"Bootstrap.d.ts","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"AAqBA;;;;GAIG;AACH,eAAO,MAAM,SAAS,eAAgB,OAAO,KAAG,OAAO,CAAC,IAAI,CA0B3D,CAAC"}
|
package/lib/Bootstrap.js
CHANGED
|
@@ -8,6 +8,7 @@ import { BunHttpServer } from "alchemy/Http";
|
|
|
8
8
|
import { reifyBoundConfigProvider } from "alchemy/Runtime";
|
|
9
9
|
import { entrypointLayer, resolveProgram, runProcess, stackFromEnv, } from "alchemy/Runtime/Bootstrap";
|
|
10
10
|
import * as ConfigProvider from "effect/ConfigProvider";
|
|
11
|
+
import * as SecureRandom from "effect/crypto/SecureRandom";
|
|
11
12
|
import * as Effect from "effect/Effect";
|
|
12
13
|
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
13
14
|
import * as Layer from "effect/Layer";
|
|
@@ -18,7 +19,7 @@ import * as Logger from "effect/Logger";
|
|
|
18
19
|
* `{ fetch }` handler is actually served and `host.run` loops stay alive.
|
|
19
20
|
*/
|
|
20
21
|
export const bootstrap = (entrypoint) => {
|
|
21
|
-
const platform = Layer.mergeAll(BunServices.layer, FetchHttpClient.layer, Logger.layer([Logger.consolePretty()]));
|
|
22
|
+
const platform = Layer.mergeAll(BunServices.layer, FetchHttpClient.layer, SecureRandom.layerWebCrypto, Logger.layer([Logger.consolePretty()]));
|
|
22
23
|
const program = resolveProgram("program").pipe(Effect.provide(entrypointLayer(entrypoint).pipe(Layer.provideMerge(stackFromEnv), Layer.provideMerge(BunHttpServer()), Layer.provideMerge(platform), Layer.provideMerge(Layer.succeed(ConfigProvider.ConfigProvider, reifyBoundConfigProvider(ConfigProvider.fromEnv(), process.env))))), Effect.scoped);
|
|
23
24
|
return runProcess("Docker service", program);
|
|
24
25
|
};
|
package/lib/Bootstrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Bootstrap.js","
|
|
1
|
+
{"version":3,"file":"Bootstrap.js","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,cAAc,EACd,UAAU,EACV,YAAY,GACb,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAmB,EAAiB,EAAE;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAC7B,WAAW,CAAC,KAAK,EACjB,eAAe,CAAC,KAAK,EACrB,YAAY,CAAC,cAAc,EAC3B,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CACvC,CAAC;IAEF,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC,IAAI,CAC5C,MAAM,CAAC,OAAO,CACZ,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,CAC9B,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,EAChC,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,EACnC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,EAC5B,KAAK,CAAC,YAAY,CAChB,KAAK,CAAC,OAAO,CACX,cAAc,CAAC,cAAc,EAC7B,wBAAwB,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAChE,CACF,CACF,CACF,EACD,MAAM,CAAC,MAAM,CACd,CAAC;IAEF,OAAO,UAAU,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BuildKit layer-cache configuration shared by every Alchemy resource that
|
|
3
|
+
* builds a container image: `Docker.Image`, `Cloudflare.Container`, the
|
|
4
|
+
* `AWS.ECS`/`AWS.EKS`/`Kubernetes` image sources, `GCP.Run`, `AWS.ECR.Image`
|
|
5
|
+
* and `AWS.Lambda` image functions.
|
|
6
|
+
*/
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
import type { RegistryCredentials } from "./Docker.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Where an image build imports layer caches from and exports them to, as
|
|
11
|
+
* BuildKit's own `--cache-from` / `--cache-to` values, e.g.
|
|
12
|
+
* `"type=gha,scope=app,mode=max"`. See
|
|
13
|
+
* [cache backends](https://docs.docker.com/build/cache/backends/).
|
|
14
|
+
*
|
|
15
|
+
* Exporting a cache needs a builder that supports it: a `docker-container`
|
|
16
|
+
* Buildx builder (what `docker/setup-buildx-action` creates in CI), or the
|
|
17
|
+
* `docker` driver with the containerd image store. Backends such as `gha`
|
|
18
|
+
* and `s3` take credentials from the environment; values reach `docker`'s
|
|
19
|
+
* argv, so never put secrets in them.
|
|
20
|
+
*/
|
|
21
|
+
export interface BuildCache {
|
|
22
|
+
/** Cache sources (`--cache-from`), imported in order. */
|
|
23
|
+
from?: ReadonlyArray<string>;
|
|
24
|
+
/** Cache destinations (`--cache-to`). */
|
|
25
|
+
to?: ReadonlyArray<string>;
|
|
26
|
+
}
|
|
27
|
+
/** Decodes a `cache` option: `true`/`false` or a {@link BuildCache}. */
|
|
28
|
+
export declare const BuildCacheSchema: Schema.Union<readonly [Schema.Boolean, Schema.Struct<{
|
|
29
|
+
readonly from: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
30
|
+
readonly to: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
31
|
+
}>]>;
|
|
32
|
+
/** The `cache` option of an image build. */
|
|
33
|
+
export interface BuildCacheOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Keep the image's build layers in a remote cache, so a builder that has
|
|
36
|
+
* never built it (a fresh CI runner, another machine) skips unchanged
|
|
37
|
+
* steps. Without it, builds reuse only the local BuildKit cache of the
|
|
38
|
+
* machine they run on.
|
|
39
|
+
*
|
|
40
|
+
* `true` imports and exports a registry cache at the `:buildcache` tag of
|
|
41
|
+
* the repository the image is published to, keeping every stage's layers
|
|
42
|
+
* (`mode=max`), not only the final image's. For another backend, pass
|
|
43
|
+
* BuildKit's own `--cache-from` / `--cache-to` values as `from` and `to`.
|
|
44
|
+
* The cache is never part of the image's content hash, so changing it
|
|
45
|
+
* never rebuilds an image.
|
|
46
|
+
*
|
|
47
|
+
* @default false
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* // Registry cache next to the image:
|
|
52
|
+
* build: { cache: true }
|
|
53
|
+
*
|
|
54
|
+
* // GitHub Actions cache:
|
|
55
|
+
* build: {
|
|
56
|
+
* cache: {
|
|
57
|
+
* from: ["type=gha,scope=app"],
|
|
58
|
+
* to: ["type=gha,scope=app,mode=max"],
|
|
59
|
+
* },
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
cache?: boolean | BuildCache;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* `--cache-from` / `--cache-to` values for a `cache` option. `true` uses a
|
|
67
|
+
* registry cache at `ref` (the target repository's `:buildcache`), stored as
|
|
68
|
+
* an OCI image manifest, the format every registry accepts (ECR rejects
|
|
69
|
+
* BuildKit's default cache index).
|
|
70
|
+
*/
|
|
71
|
+
export declare const resolveBuildCache: (cache: boolean | BuildCache | undefined, ref: string) => {
|
|
72
|
+
"cache-from": string[];
|
|
73
|
+
"cache-to": string[];
|
|
74
|
+
};
|
|
75
|
+
/** The `:buildcache` ref in the repository of an image ref (`repo:tag` or `repo@digest`). */
|
|
76
|
+
export declare const buildCacheRef: (imageRef: string) => string;
|
|
77
|
+
/**
|
|
78
|
+
* `docker.image.build` options for the `cache` option of an image published
|
|
79
|
+
* to `imageUri`. The build authenticates with the push `credentials`, so it
|
|
80
|
+
* can import and export a cache in the target registry.
|
|
81
|
+
*/
|
|
82
|
+
export declare const imageBuildCacheOptions: (options: BuildCacheOptions | undefined, imageUri: string, credentials: RegistryCredentials | undefined) => {
|
|
83
|
+
"cache-from"?: string[];
|
|
84
|
+
"cache-to"?: string[];
|
|
85
|
+
credentials?: RegistryCredentials;
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=BuildCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildCache.d.ts","sources":["../src/BuildCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB,yDAAyD;IACzD,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,yCAAyC;IACzC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED,wEAAwE;AACxE,eAAO,MAAM,gBAAgB;;;IAM3B,CAAC;AAEH,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,UACrB,OAAO,GAAG,UAAU,GAAG,SAAS,OAClC,MAAM,KACV;IAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAMiD,CAAC;AAEnG,6FAA6F;AAC7F,eAAO,MAAM,aAAa,aAAc,MAAM,KAAG,MACC,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,YACxB,iBAAiB,GAAG,SAAS,YAC5B,MAAM,eACH,mBAAmB,GAAG,SAAS,KAC3C;IACD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,mBAAmB,CAAC;CAI5B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BuildKit layer-cache configuration shared by every Alchemy resource that
|
|
3
|
+
* builds a container image: `Docker.Image`, `Cloudflare.Container`, the
|
|
4
|
+
* `AWS.ECS`/`AWS.EKS`/`Kubernetes` image sources, `GCP.Run`, `AWS.ECR.Image`
|
|
5
|
+
* and `AWS.Lambda` image functions.
|
|
6
|
+
*/
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
import { repositoryFromImageRef } from "./Registry.js";
|
|
9
|
+
/** Decodes a `cache` option: `true`/`false` or a {@link BuildCache}. */
|
|
10
|
+
export const BuildCacheSchema = Schema.Union([
|
|
11
|
+
Schema.Boolean,
|
|
12
|
+
Schema.Struct({
|
|
13
|
+
from: Schema.String.pipe(Schema.Array, Schema.optionalKey),
|
|
14
|
+
to: Schema.String.pipe(Schema.Array, Schema.optionalKey),
|
|
15
|
+
}),
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* `--cache-from` / `--cache-to` values for a `cache` option. `true` uses a
|
|
19
|
+
* registry cache at `ref` (the target repository's `:buildcache`), stored as
|
|
20
|
+
* an OCI image manifest, the format every registry accepts (ECR rejects
|
|
21
|
+
* BuildKit's default cache index).
|
|
22
|
+
*/
|
|
23
|
+
export const resolveBuildCache = (cache, ref) => cache === true
|
|
24
|
+
? {
|
|
25
|
+
"cache-from": [`type=registry,ref=${ref}`],
|
|
26
|
+
"cache-to": [`type=registry,ref=${ref},mode=max,image-manifest=true,oci-mediatypes=true`],
|
|
27
|
+
}
|
|
28
|
+
: { "cache-from": [...((cache || {}).from ?? [])], "cache-to": [...((cache || {}).to ?? [])] };
|
|
29
|
+
/** The `:buildcache` ref in the repository of an image ref (`repo:tag` or `repo@digest`). */
|
|
30
|
+
export const buildCacheRef = (imageRef) => `${repositoryFromImageRef(imageRef)}:buildcache`;
|
|
31
|
+
/**
|
|
32
|
+
* `docker.image.build` options for the `cache` option of an image published
|
|
33
|
+
* to `imageUri`. The build authenticates with the push `credentials`, so it
|
|
34
|
+
* can import and export a cache in the target registry.
|
|
35
|
+
*/
|
|
36
|
+
export const imageBuildCacheOptions = (options, imageUri, credentials) => options?.cache
|
|
37
|
+
? { ...resolveBuildCache(options.cache, buildCacheRef(imageUri)), credentials }
|
|
38
|
+
: {};
|
|
39
|
+
//# sourceMappingURL=BuildCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildCache.js","sources":["../src/BuildCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAqBvD,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3C,MAAM,CAAC,OAAO;IACd,MAAM,CAAC,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC;QAC1D,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC;KACzD,CAAC;CACH,CAAC,CAAC;AAoCH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAuC,EACvC,GAAW,EACuC,EAAE,CACpD,KAAK,KAAK,IAAI;IACZ,CAAC,CAAC;QACE,YAAY,EAAE,CAAC,qBAAqB,GAAG,EAAE,CAAC;QAC1C,UAAU,EAAE,CAAC,qBAAqB,GAAG,mDAAmD,CAAC;KAC1F;IACH,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AAEnG,6FAA6F;AAC7F,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAU,EAAE,CACxD,GAAG,sBAAsB,CAAC,QAAQ,CAAC,aAAa,CAAC;AAEnD;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAAsC,EACtC,QAAgB,EAChB,WAA4C,EAK5C,EAAE,CACF,OAAO,EAAE,KAAK;IACZ,CAAC,CAAC,EAAE,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,EAAE;IAC/E,CAAC,CAAC,EAAE,CAAC"}
|
package/lib/BuildHash.d.ts
CHANGED
|
@@ -51,6 +51,14 @@ export declare const selectDockerBuildContext: (source: Pick<DockerBuildSource,
|
|
|
51
51
|
* applied exactly once before files are hashed. Absolute paths do not
|
|
52
52
|
* participate.
|
|
53
53
|
*/
|
|
54
|
-
export declare const hashDockerBuildInputs: (source: DockerBuildSource, mode: DockerBuildHashMode
|
|
54
|
+
export declare const hashDockerBuildInputs: (source: DockerBuildSource, mode: DockerBuildHashMode, options?: {
|
|
55
|
+
/**
|
|
56
|
+
* Directory names left out of the hash at any depth, on top of
|
|
57
|
+
* `.dockerignore` and `.alchemy` — e.g. `.git` and `node_modules` for a
|
|
58
|
+
* dev watcher that must not restart on git's index writes or re-hash
|
|
59
|
+
* installed dependencies on every edit.
|
|
60
|
+
*/
|
|
61
|
+
readonly excludeNames?: ReadonlyArray<string>;
|
|
62
|
+
} | undefined) => Effect.Effect<string, BuildHashInvalidProps | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
|
|
55
63
|
export {};
|
|
56
64
|
//# sourceMappingURL=BuildHash.d.ts.map
|
package/lib/BuildHash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BuildHash.d.ts","
|
|
1
|
+
{"version":3,"file":"BuildHash.d.ts","sources":["../src/BuildHash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;;;;AAGpC,qBAAa,qBAAsB,SAAQ,2BAA0C;IACnF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;CAAG;AAEL,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,WAAW,CAAC;AAQtD;;;;GAIG;AACH,eAAO,MAAM,uBAAuB;;;2GAsBlC,CAAC;AA8CH;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;;;;6BAkBR,MAAM;2GAQjC,CAAC;AAqBH;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB;IAI9B;;;;;OAKG;4BACqB,aAAa,CAAC,MAAM,CAAC;gJA8H/C,CAAC"}
|
package/lib/BuildHash.js
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
* image packaging; NOT exported from the Docker barrel.
|
|
7
7
|
*/
|
|
8
8
|
import * as crypto from "node:crypto";
|
|
9
|
+
import { dotAlchemyDirectory } from "alchemy/AlchemyContext";
|
|
9
10
|
import { listFileSystemDirectory, normalizeRelativePath, parseIgnoreRules, walkIgnoring, } from "alchemy/Util/Ignore";
|
|
11
|
+
import { initialCwd } from "alchemy/Util/Node";
|
|
10
12
|
import * as Data from "effect/Data";
|
|
11
13
|
import * as Effect from "effect/Effect";
|
|
12
14
|
import * as FileSystem from "effect/FileSystem";
|
|
13
15
|
import * as Path from "effect/Path";
|
|
14
|
-
import * as Result from "effect/Result";
|
|
15
16
|
import * as Stream from "effect/Stream";
|
|
16
17
|
export class BuildHashInvalidProps extends Data.TaggedError("BuildHashInvalidProps") {
|
|
17
18
|
}
|
|
@@ -92,13 +93,30 @@ export const selectDockerBuildContext = Effect.fn(function* (source) {
|
|
|
92
93
|
},
|
|
93
94
|
};
|
|
94
95
|
});
|
|
96
|
+
/**
|
|
97
|
+
* The context-relative path of Alchemy's `.alchemy` directory when it lies
|
|
98
|
+
* strictly inside `context`, otherwise `undefined`.
|
|
99
|
+
*/
|
|
100
|
+
const containedRuntimeDirectory = Effect.fn(function* (context) {
|
|
101
|
+
const path = yield* Path.Path;
|
|
102
|
+
const runtime = path.resolve(initialCwd, yield* dotAlchemyDirectory);
|
|
103
|
+
const relative = normalizeRelativePath(path.relative(context, runtime));
|
|
104
|
+
return relative === "" ||
|
|
105
|
+
relative === ".." ||
|
|
106
|
+
relative.startsWith("../") ||
|
|
107
|
+
path.isAbsolute(relative)
|
|
108
|
+
? undefined
|
|
109
|
+
: relative;
|
|
110
|
+
});
|
|
111
|
+
/** Files below this size are read in one call instead of streamed. */
|
|
112
|
+
const SMALL_FILE_BYTES = 1024 * 1024;
|
|
95
113
|
/**
|
|
96
114
|
* Hash a Docker build context together with the Dockerfile, platform, and
|
|
97
115
|
* build arguments. In `effective` mode, the selected `.dockerignore` is
|
|
98
116
|
* applied exactly once before files are hashed. Absolute paths do not
|
|
99
117
|
* participate.
|
|
100
118
|
*/
|
|
101
|
-
export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
|
|
119
|
+
export const hashDockerBuildInputs = Effect.fn(function* (source, mode, options = {}) {
|
|
102
120
|
const fs = yield* FileSystem.FileSystem;
|
|
103
121
|
const path = yield* Path.Path;
|
|
104
122
|
const { context, dockerfile } = yield* resolveDockerBuildPaths(source);
|
|
@@ -123,14 +141,25 @@ export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
|
|
|
123
141
|
dockerignore?.path,
|
|
124
142
|
normalizeRelativePath(path.relative(context, dockerfile)),
|
|
125
143
|
].filter((entry) => entry !== undefined && entry !== ".." && !entry.startsWith("../") && !path.isAbsolute(entry));
|
|
144
|
+
// Alchemy writes run logs and local state to `.alchemy` on every run. When a
|
|
145
|
+
// context contains it (e.g. `context: "."` at the project root), hashing it
|
|
146
|
+
// would give the image a new tag on every deploy. A context inside
|
|
147
|
+
// `.alchemy` (a generated one) is still hashed in full.
|
|
148
|
+
const runtimeDirectory = yield* containedRuntimeDirectory(context);
|
|
149
|
+
const excludedNames = new Set(options.excludeNames ?? []);
|
|
150
|
+
const listDirectory = yield* listFileSystemDirectory(context);
|
|
126
151
|
// Walk one level at a time so an excluded directory is discarded before
|
|
127
152
|
// its contents are read; entries come back sorted, preserving hash order.
|
|
128
153
|
const entries = yield* walkIgnoring({
|
|
129
|
-
list:
|
|
154
|
+
list: runtimeDirectory === undefined && excludedNames.size === 0
|
|
155
|
+
? listDirectory
|
|
156
|
+
: (directory) => listDirectory(directory).pipe(Effect.map((children) => children.filter((child) => !(child.type === "Directory" && excludedNames.has(child.name)) &&
|
|
157
|
+
(directory.length === 0 ? child.name : `${directory}/${child.name}`) !==
|
|
158
|
+
runtimeDirectory))),
|
|
130
159
|
rules: dockerignore?.rules,
|
|
131
160
|
force: forcedPaths,
|
|
132
161
|
});
|
|
133
|
-
for (const { path: entry } of entries) {
|
|
162
|
+
for (const { path: entry, type } of entries) {
|
|
134
163
|
// The ignore file and Dockerfile contents are hashed above; excluded
|
|
135
164
|
// entries were only walked so re-included descendants could be found.
|
|
136
165
|
if (dockerignore !== undefined &&
|
|
@@ -138,17 +167,13 @@ export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
|
|
|
138
167
|
continue;
|
|
139
168
|
}
|
|
140
169
|
const fullPath = path.join(context, entry);
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
yield* Effect.sync(() => hasher.update(`${JSON.stringify({
|
|
148
|
-
path: hashedEntry,
|
|
149
|
-
type: "SymbolicLink",
|
|
150
|
-
target: link.success,
|
|
151
|
-
})}\0`));
|
|
170
|
+
// Docker preserves a symbolic link in the build context; hashing the
|
|
171
|
+
// target file would miss retargets between files with identical
|
|
172
|
+
// contents and metadata. The walk reports the entry's own type, so only
|
|
173
|
+
// links are read as links.
|
|
174
|
+
if (type === "SymbolicLink") {
|
|
175
|
+
const target = yield* fs.readLink(fullPath);
|
|
176
|
+
yield* Effect.sync(() => hasher.update(`${JSON.stringify({ path: entry, type: "SymbolicLink", target })}\0`));
|
|
152
177
|
continue;
|
|
153
178
|
}
|
|
154
179
|
const info = yield* fs.stat(fullPath);
|
|
@@ -156,15 +181,22 @@ export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
|
|
|
156
181
|
// directories. Include that metadata before any file bytes so changes such
|
|
157
182
|
// as making a Lambda bootstrap executable invalidate the image tag.
|
|
158
183
|
yield* Effect.sync(() => hasher.update(`${JSON.stringify({
|
|
159
|
-
path:
|
|
184
|
+
path: entry,
|
|
160
185
|
type: info.type,
|
|
161
186
|
mode: info.mode & 0o7777,
|
|
162
187
|
size: info.type === "File" ? String(info.size) : undefined,
|
|
163
188
|
})}\0`));
|
|
164
189
|
if (info.type === "File") {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
190
|
+
// Read small files whole (one call); stream large ones so memory stays flat.
|
|
191
|
+
if (info.size < SMALL_FILE_BYTES) {
|
|
192
|
+
const bytes = yield* fs.readFile(fullPath);
|
|
193
|
+
yield* Effect.sync(() => hasher.update(bytes));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
yield* fs.stream(fullPath).pipe(Stream.runForEach((chunk) => Effect.sync(() => {
|
|
197
|
+
hasher.update(chunk);
|
|
198
|
+
})));
|
|
199
|
+
}
|
|
168
200
|
}
|
|
169
201
|
}
|
|
170
202
|
return (yield* Effect.sync(() => hasher.digest("hex"))).slice(0, 32);
|
package/lib/BuildHash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BuildHash.js","
|
|
1
|
+
{"version":3,"file":"BuildHash.js","sources":["../src/BuildHash.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as FileSystem from "effect/FileSystem";
|
|
3
|
+
import * as Path from "effect/Path";
|
|
4
|
+
import type * as Redacted from "effect/Redacted";
|
|
5
|
+
import { Docker } from "./Docker.ts";
|
|
6
|
+
import * as DockerfileParser from "./DockerfileParser.ts";
|
|
7
|
+
import type { CopyInstruction, Instruction, InstructionName, ParsedDockerfile } from "./DockerfileParser.ts";
|
|
8
|
+
import { type ImageSourceProps } from "./ImageSource.ts";
|
|
9
|
+
import { type ImageRegistry } from "./Registry.ts";
|
|
10
|
+
/**
|
|
11
|
+
* A build plan: an image source (`image`, `context` + `dockerfile`, inline
|
|
12
|
+
* `dockerfile`, plus an optional bundled `main`) resolved into data that any
|
|
13
|
+
* builder can consume, Docker or not.
|
|
14
|
+
*
|
|
15
|
+
* Platforms with their own builders (E2B templates, Modal images, Daytona
|
|
16
|
+
* snapshots) lower a plan into their build API; the Docker path can render
|
|
17
|
+
* it back into a Dockerfile and build context. Every platform declares
|
|
18
|
+
* {@link Capabilities}, and a Dockerfile it cannot build fails at plan time
|
|
19
|
+
* with the offending lines, before any upload or remote build.
|
|
20
|
+
*/
|
|
21
|
+
export interface BuildPlan {
|
|
22
|
+
/** Content hash of everything that determines the image: rebuild only when it changes. */
|
|
23
|
+
readonly hash: string;
|
|
24
|
+
/** Target platform, e.g. `linux/amd64`. */
|
|
25
|
+
readonly platform: string;
|
|
26
|
+
/** Every stage, including the generated `main` layer. */
|
|
27
|
+
readonly dockerfile: ParsedDockerfile;
|
|
28
|
+
/** The final stage's base: an image reference, an earlier stage's name, or `scratch`. */
|
|
29
|
+
readonly base: string;
|
|
30
|
+
/** Credentials for pulling a private base image. */
|
|
31
|
+
readonly pull: ImageRegistry | undefined;
|
|
32
|
+
/** The final stage's instructions. */
|
|
33
|
+
readonly instructions: ReadonlyArray<Instruction>;
|
|
34
|
+
/**
|
|
35
|
+
* Files the build reads from its context: everything a `COPY`/`ADD`
|
|
36
|
+
* source reaches (after `.dockerignore`), plus the bundled `main` under
|
|
37
|
+
* {@link BUNDLE_DIR}. Paths are relative to the context, `/`-separated.
|
|
38
|
+
*/
|
|
39
|
+
readonly files: ReadonlyArray<ContextFile>;
|
|
40
|
+
/**
|
|
41
|
+
* Build arguments (`ARG` values) the builder must pass. Empty when the
|
|
42
|
+
* builder takes none ({@link Capabilities.buildArgs}): the values are then
|
|
43
|
+
* written into the `ARG` defaults of {@link dockerfile}.
|
|
44
|
+
*/
|
|
45
|
+
readonly args: Readonly<Record<string, string>>;
|
|
46
|
+
/** BuildKit secrets, by id (`RUN --mount=type=secret,id=…`). */
|
|
47
|
+
readonly secrets: Readonly<Record<string, Redacted.Redacted<string>>>;
|
|
48
|
+
/** Instructions the platform ignores (see {@link Capabilities.instructions}). */
|
|
49
|
+
readonly warnings: ReadonlyArray<string>;
|
|
50
|
+
}
|
|
51
|
+
/** A file in a plan's build context. */
|
|
52
|
+
export interface ContextFile {
|
|
53
|
+
/** Context-relative, `/`-separated. */
|
|
54
|
+
readonly path: string;
|
|
55
|
+
/** Permission bits. */
|
|
56
|
+
readonly mode: number;
|
|
57
|
+
readonly size: number;
|
|
58
|
+
/** Hex SHA-256 of the contents. */
|
|
59
|
+
readonly sha256: string;
|
|
60
|
+
readonly source: {
|
|
61
|
+
readonly _tag: "Path";
|
|
62
|
+
readonly absolutePath: string;
|
|
63
|
+
} | {
|
|
64
|
+
readonly _tag: "Bytes";
|
|
65
|
+
readonly bytes: Uint8Array;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* What a builder supports. Anything not listed is supported.
|
|
70
|
+
*/
|
|
71
|
+
export interface Capabilities {
|
|
72
|
+
/** The resource the plan is for, used in error messages, e.g. `"E2B.Template"`. */
|
|
73
|
+
readonly target: string;
|
|
74
|
+
/** More than one `FROM`, or `COPY --from`. @default true */
|
|
75
|
+
readonly multiStage?: boolean;
|
|
76
|
+
/** `RUN <<EOF` / `COPY <<EOF`. @default true */
|
|
77
|
+
readonly heredocs?: boolean;
|
|
78
|
+
/** `RUN --mount=…` (secrets, caches). @default true */
|
|
79
|
+
readonly runMounts?: boolean;
|
|
80
|
+
/** `ADD <url>`. @default true */
|
|
81
|
+
readonly remoteAdd?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Build arguments passed to the builder. When `false`, the plan writes
|
|
84
|
+
* the values into the Dockerfile's `ARG` defaults instead. @default true
|
|
85
|
+
*/
|
|
86
|
+
readonly buildArgs?: boolean;
|
|
87
|
+
/** BuildKit secrets (`build.secrets`, `RUN --mount=type=secret`). @default true */
|
|
88
|
+
readonly secrets?: boolean;
|
|
89
|
+
/** Platforms the builder targets, also checked against `FROM --platform=`. @default any */
|
|
90
|
+
readonly platforms?: ReadonlyArray<string>;
|
|
91
|
+
/** Instructions the builder ignores (a warning) or rejects (an error). */
|
|
92
|
+
readonly instructions?: Partial<Record<InstructionName, "ignored" | "unsupported">>;
|
|
93
|
+
}
|
|
94
|
+
/** One reason a builder cannot build a plan. */
|
|
95
|
+
export interface Violation {
|
|
96
|
+
/** 1-based Dockerfile line; `0` for the generated `main` layer or the platform. */
|
|
97
|
+
readonly line: number;
|
|
98
|
+
readonly instruction: string;
|
|
99
|
+
readonly reason: string;
|
|
100
|
+
}
|
|
101
|
+
declare const UnsupportedDockerfile_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
102
|
+
readonly _tag: "UnsupportedDockerfile";
|
|
103
|
+
} & Readonly<A>;
|
|
104
|
+
/** The Dockerfile uses something the target builder cannot build. */
|
|
105
|
+
export declare class UnsupportedDockerfile extends UnsupportedDockerfile_base<{
|
|
106
|
+
readonly target: string;
|
|
107
|
+
readonly violations: ReadonlyArray<Violation>;
|
|
108
|
+
readonly message: string;
|
|
109
|
+
}> {
|
|
110
|
+
}
|
|
111
|
+
declare const BuildPlanError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
112
|
+
readonly _tag: "BuildPlanError";
|
|
113
|
+
} & Readonly<A>;
|
|
114
|
+
/** The image source cannot be planned (a missing file, an unresolved input, an inline Dockerfile that copies from a context). */
|
|
115
|
+
export declare class BuildPlanError extends BuildPlanError_base<{
|
|
116
|
+
readonly message: string;
|
|
117
|
+
readonly cause?: unknown;
|
|
118
|
+
}> {
|
|
119
|
+
}
|
|
120
|
+
/** The context directory a plan's bundled `main` files live under. */
|
|
121
|
+
export declare const BUNDLE_DIR = "__alchemy__";
|
|
122
|
+
/** Default base for a `main` program with no environment: Docker Hub's bun image. */
|
|
123
|
+
export declare const DEFAULT_MAIN_BASE = "oven/bun:1";
|
|
124
|
+
export interface PlanOptions {
|
|
125
|
+
readonly capabilities: Capabilities;
|
|
126
|
+
/** @default "linux/amd64" */
|
|
127
|
+
readonly platform?: string;
|
|
128
|
+
/** Port a `main` program listens on; written to `ENV PORT`. */
|
|
129
|
+
readonly port?: number;
|
|
130
|
+
/**
|
|
131
|
+
* Bootstrap wrapped around an Effect-native `main` (the host's virtual
|
|
132
|
+
* entry). Omit it to bundle `main` as-is.
|
|
133
|
+
*/
|
|
134
|
+
readonly bootstrap?: (importPath: string) => string;
|
|
135
|
+
/** Credentials for pulling a private base image. */
|
|
136
|
+
readonly pull?: ImageRegistry;
|
|
137
|
+
/**
|
|
138
|
+
* Dockerfile lines a host's bindings contribute, e.g. the clients of
|
|
139
|
+
* `alchemy/Mount` capabilities (`mountInstallLines`). They go after the
|
|
140
|
+
* final stage's own instructions and before the bundled `main`, so a
|
|
141
|
+
* program change doesn't reinstall them.
|
|
142
|
+
*/
|
|
143
|
+
readonly install?: ReadonlyArray<string>;
|
|
144
|
+
}
|
|
145
|
+
/** The context files one `COPY`/`ADD` reads. */
|
|
146
|
+
export declare const filesFor: (plan: BuildPlan, instruction: CopyInstruction) => ContextFile[];
|
|
147
|
+
/** Check a parsed Dockerfile against a builder's capabilities. */
|
|
148
|
+
export declare const check: (dockerfile: ParsedDockerfile, capabilities: Capabilities, platform: string) => {
|
|
149
|
+
violations: Violation[];
|
|
150
|
+
warnings: string[];
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Resolve an image source into a {@link BuildPlan} for one builder.
|
|
154
|
+
*/
|
|
155
|
+
export declare const plan: (source: ImageSourceProps, options: PlanOptions) => Effect.Effect<{
|
|
156
|
+
hash: string;
|
|
157
|
+
platform: string;
|
|
158
|
+
dockerfile: ParsedDockerfile;
|
|
159
|
+
base: string;
|
|
160
|
+
pull: ImageRegistry | undefined;
|
|
161
|
+
instructions: readonly Instruction[];
|
|
162
|
+
files: ContextFile[];
|
|
163
|
+
args: Record<string, string>;
|
|
164
|
+
secrets: Record<string, Redacted.Redacted<string>>;
|
|
165
|
+
warnings: string[];
|
|
166
|
+
}, import("./BuildHash.ts").BuildHashInvalidProps | BuildPlanError | import("alchemy/Bundle/Bundle").BundleError | DockerfileParser.DockerfileSyntaxError | import("effect/PlatformError").PlatformError | UnsupportedDockerfile, FileSystem.FileSystem | Path.Path>;
|
|
167
|
+
/** A context file's contents. */
|
|
168
|
+
export declare const readContextFile: (file: ContextFile) => Effect.Effect<Uint8Array<ArrayBufferLike>, import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
|
|
169
|
+
/** The plan as Dockerfile text. */
|
|
170
|
+
export declare const render: (plan: BuildPlan) => string;
|
|
171
|
+
/** The plan as one entry per instruction (for APIs that take a list of Dockerfile commands). */
|
|
172
|
+
export declare const renderLines: (plan: BuildPlan) => string[];
|
|
173
|
+
/**
|
|
174
|
+
* The argv the image starts with, from the final stage's `ENTRYPOINT` and
|
|
175
|
+
* `CMD` (Docker's rules: a shell-form `ENTRYPOINT` ignores `CMD`).
|
|
176
|
+
* `undefined` when the final stage sets neither (the base image's applies).
|
|
177
|
+
*/
|
|
178
|
+
export declare const startCommand: (plan: BuildPlan) => ReadonlyArray<string> | undefined;
|
|
179
|
+
/**
|
|
180
|
+
* Check Dockerfile text against a builder's capabilities, without reading a
|
|
181
|
+
* build context or bundling anything: usable where there is no filesystem
|
|
182
|
+
* (a Worker creating images at run time). Returns the warnings.
|
|
183
|
+
*/
|
|
184
|
+
export declare const checkContent: (text: string, options: Pick<PlanOptions, "capabilities" | "platform">) => Effect.Effect<string[], DockerfileParser.DockerfileSyntaxError | UnsupportedDockerfile, never>;
|
|
185
|
+
/** Where {@link push} publishes a plan. */
|
|
186
|
+
export interface PushTarget {
|
|
187
|
+
/** Repository to push to, without a tag, e.g. `ghcr.io/acme/agent`. The plan's hash is the tag. */
|
|
188
|
+
readonly repository: string;
|
|
189
|
+
/** Credentials for the registry the repository lives in. */
|
|
190
|
+
readonly push: ImageRegistry;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Build a plan with the local Docker engine and push it, for platforms that
|
|
194
|
+
* only pull images (Archil). Tagged with the plan's hash, so an unchanged
|
|
195
|
+
* plan pushes the same tag. Returns the pushed reference, `repository@digest`
|
|
196
|
+
* when the registry reports a digest, else `repository:hash`.
|
|
197
|
+
*/
|
|
198
|
+
export declare const push: (plan: BuildPlan, target: PushTarget) => Effect.Effect<{
|
|
199
|
+
imageRef: string;
|
|
200
|
+
}, import("./RegistryError.ts").DockerImagePublicationError, Docker | FileSystem.FileSystem | Path.Path | import("effect/Scope").Scope>;
|
|
201
|
+
export {};
|
|
202
|
+
//# sourceMappingURL=BuildPlan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildPlan.d.ts","sources":["../src/BuildPlan.ts"],"names":[],"mappings":"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"}
|