@alchemy.run/docker 2.0.0-beta.84 → 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.
Files changed (98) hide show
  1. package/README.md +16 -0
  2. package/lib/Bootstrap.d.ts.map +1 -1
  3. package/lib/Bootstrap.js +2 -1
  4. package/lib/Bootstrap.js.map +1 -1
  5. package/lib/BuildCache.d.ts +87 -0
  6. package/lib/BuildCache.d.ts.map +1 -0
  7. package/lib/BuildCache.js +39 -0
  8. package/lib/BuildCache.js.map +1 -0
  9. package/lib/BuildHash.d.ts +20 -3
  10. package/lib/BuildHash.d.ts.map +1 -1
  11. package/lib/BuildHash.js +60 -21
  12. package/lib/BuildHash.js.map +1 -1
  13. package/lib/BuildPlan.d.ts +202 -0
  14. package/lib/BuildPlan.d.ts.map +1 -0
  15. package/lib/BuildPlan.js +514 -0
  16. package/lib/BuildPlan.js.map +1 -0
  17. package/lib/Container.d.ts +122 -1
  18. package/lib/Container.d.ts.map +1 -1
  19. package/lib/Container.js +232 -4
  20. package/lib/Container.js.map +1 -1
  21. package/lib/Context.d.ts +20 -1
  22. package/lib/Context.d.ts.map +1 -1
  23. package/lib/Context.js +15 -0
  24. package/lib/Context.js.map +1 -1
  25. package/lib/Docker.d.ts +113 -1
  26. package/lib/Docker.d.ts.map +1 -1
  27. package/lib/Docker.js +50 -8
  28. package/lib/Docker.js.map +1 -1
  29. package/lib/Dockerfile.d.ts +0 -2
  30. package/lib/Dockerfile.d.ts.map +1 -1
  31. package/lib/Dockerfile.js.map +1 -1
  32. package/lib/DockerfileParser.d.ts +125 -0
  33. package/lib/DockerfileParser.d.ts.map +1 -0
  34. package/lib/DockerfileParser.js +1040 -0
  35. package/lib/DockerfileParser.js.map +1 -0
  36. package/lib/HealthcheckCommand.d.ts.map +1 -1
  37. package/lib/HealthcheckCommand.js.map +1 -1
  38. package/lib/Image.d.ts +69 -13
  39. package/lib/Image.d.ts.map +1 -1
  40. package/lib/Image.js +59 -9
  41. package/lib/Image.js.map +1 -1
  42. package/lib/ImageArchive.d.ts +41 -0
  43. package/lib/ImageArchive.d.ts.map +1 -0
  44. package/lib/ImageArchive.js +54 -0
  45. package/lib/ImageArchive.js.map +1 -0
  46. package/lib/ImageSource.d.ts +151 -8
  47. package/lib/ImageSource.d.ts.map +1 -1
  48. package/lib/ImageSource.js +247 -72
  49. package/lib/ImageSource.js.map +1 -1
  50. package/lib/Network.d.ts +175 -3
  51. package/lib/Network.d.ts.map +1 -1
  52. package/lib/Network.js +296 -8
  53. package/lib/Network.js.map +1 -1
  54. package/lib/Providers.d.ts.map +1 -1
  55. package/lib/Providers.js.map +1 -1
  56. package/lib/Registry.d.ts.map +1 -1
  57. package/lib/Registry.js.map +1 -1
  58. package/lib/RegistryError.d.ts.map +1 -1
  59. package/lib/RegistryError.js.map +1 -1
  60. package/lib/RemoteImage.d.ts.map +1 -1
  61. package/lib/RemoteImage.js +1 -1
  62. package/lib/RemoteImage.js.map +1 -1
  63. package/lib/Service.d.ts +24 -3
  64. package/lib/Service.d.ts.map +1 -1
  65. package/lib/Service.js +154 -12
  66. package/lib/Service.js.map +1 -1
  67. package/lib/ServiceImage.d.ts.map +1 -1
  68. package/lib/ServiceImage.js.map +1 -1
  69. package/lib/ShellWord.d.ts +28 -0
  70. package/lib/ShellWord.d.ts.map +1 -0
  71. package/lib/ShellWord.js +301 -0
  72. package/lib/ShellWord.js.map +1 -0
  73. package/lib/Swarm.d.ts.map +1 -1
  74. package/lib/Swarm.js.map +1 -1
  75. package/lib/Volume.d.ts +24 -1
  76. package/lib/Volume.d.ts.map +1 -1
  77. package/lib/Volume.js +16 -0
  78. package/lib/Volume.js.map +1 -1
  79. package/lib/index.d.ts.map +1 -1
  80. package/lib/index.js.map +1 -1
  81. package/package.json +9 -9
  82. package/src/Bootstrap.ts +2 -0
  83. package/src/BuildCache.ts +111 -0
  84. package/src/BuildHash.ts +85 -26
  85. package/src/BuildPlan.ts +758 -0
  86. package/src/Container.ts +361 -5
  87. package/src/Context.ts +27 -1
  88. package/src/Docker.ts +157 -9
  89. package/src/Dockerfile.ts +0 -2
  90. package/src/DockerfileParser.ts +1152 -0
  91. package/src/Image.ts +75 -15
  92. package/src/ImageArchive.ts +77 -0
  93. package/src/ImageSource.ts +391 -99
  94. package/src/Network.ts +432 -10
  95. package/src/RemoteImage.ts +1 -1
  96. package/src/Service.ts +246 -62
  97. package/src/ShellWord.ts +326 -0
  98. 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)
@@ -1 +1 @@
1
- {"version":3,"file":"Bootstrap.d.ts","sourceRoot":"","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,eAAO,MAAM,SAAS,eAAgB,OAAO,KAAG,OAAO,CAAC,IAAI,CAyB3D,CAAC"}
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
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Bootstrap.js","sourceRoot":"","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,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,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"}
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"}
@@ -8,6 +8,14 @@
8
8
  import * as Effect from "effect/Effect";
9
9
  import * as FileSystem from "effect/FileSystem";
10
10
  import * as Path from "effect/Path";
11
+ declare const BuildHashInvalidProps_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 & {
12
+ readonly _tag: "BuildHashInvalidProps";
13
+ } & Readonly<A>;
14
+ export declare class BuildHashInvalidProps extends BuildHashInvalidProps_base<{
15
+ readonly message: string;
16
+ readonly cause?: unknown;
17
+ }> {
18
+ }
11
19
  export interface DockerBuildSource {
12
20
  context: string;
13
21
  dockerfile: string;
@@ -23,7 +31,7 @@ export type DockerBuildHashMode = "all" | "effective";
23
31
  export declare const resolveDockerBuildPaths: (source: Pick<DockerBuildSource, "context" | "dockerfile">) => Effect.Effect<{
24
32
  context: string;
25
33
  dockerfile: string;
26
- }, Error | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
34
+ }, BuildHashInvalidProps | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
27
35
  /**
28
36
  * Select the effective files sent for a Docker build.
29
37
  *
@@ -36,12 +44,21 @@ export declare const selectDockerBuildContext: (source: Pick<DockerBuildSource,
36
44
  dockerfile: string;
37
45
  dockerfilePath: string | undefined;
38
46
  includes: (relativePath: string) => boolean;
39
- }, Error | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
47
+ }, BuildHashInvalidProps | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
40
48
  /**
41
49
  * Hash a Docker build context together with the Dockerfile, platform, and
42
50
  * build arguments. In `effective` mode, the selected `.dockerignore` is
43
51
  * applied exactly once before files are hashed. Absolute paths do not
44
52
  * participate.
45
53
  */
46
- export declare const hashDockerBuildInputs: (source: DockerBuildSource, mode: DockerBuildHashMode) => Effect.Effect<string, Error | import("effect/PlatformError").PlatformError, FileSystem.FileSystem | Path.Path>;
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>;
63
+ export {};
47
64
  //# sourceMappingURL=BuildHash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BuildHash.d.ts","sourceRoot":"","sources":["../src/BuildHash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AAIpC,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;;;2FAkBlC,CAAC;AA8CH;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB;;;;6BAkBR,MAAM;2FAQjC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,0KA2GhC,CAAC"}
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,16 @@
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";
12
+ import * as Data from "effect/Data";
10
13
  import * as Effect from "effect/Effect";
11
14
  import * as FileSystem from "effect/FileSystem";
12
15
  import * as Path from "effect/Path";
13
- import * as Result from "effect/Result";
14
16
  import * as Stream from "effect/Stream";
17
+ export class BuildHashInvalidProps extends Data.TaggedError("BuildHashInvalidProps") {
18
+ }
15
19
  /**
16
20
  * Resolve and validate a Docker build context and Dockerfile.
17
21
  *
@@ -25,10 +29,14 @@ export const resolveDockerBuildPaths = Effect.fn(function* (source) {
25
29
  ? source.dockerfile
26
30
  : path.resolve(context, source.dockerfile);
27
31
  if (!(yield* fs.exists(context))) {
28
- return yield* Effect.fail(new Error(`Docker build context does not exist: ${context}`));
32
+ return yield* new BuildHashInvalidProps({
33
+ message: `Docker build context does not exist: ${context}`,
34
+ });
29
35
  }
30
36
  if (!(yield* fs.exists(dockerfile))) {
31
- return yield* Effect.fail(new Error(`Dockerfile does not exist: ${dockerfile}`));
37
+ return yield* new BuildHashInvalidProps({
38
+ message: `Dockerfile does not exist: ${dockerfile}`,
39
+ });
32
40
  }
33
41
  return { context, dockerfile };
34
42
  });
@@ -85,13 +93,30 @@ export const selectDockerBuildContext = Effect.fn(function* (source) {
85
93
  },
86
94
  };
87
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;
88
113
  /**
89
114
  * Hash a Docker build context together with the Dockerfile, platform, and
90
115
  * build arguments. In `effective` mode, the selected `.dockerignore` is
91
116
  * applied exactly once before files are hashed. Absolute paths do not
92
117
  * participate.
93
118
  */
94
- export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
119
+ export const hashDockerBuildInputs = Effect.fn(function* (source, mode, options = {}) {
95
120
  const fs = yield* FileSystem.FileSystem;
96
121
  const path = yield* Path.Path;
97
122
  const { context, dockerfile } = yield* resolveDockerBuildPaths(source);
@@ -116,14 +141,25 @@ export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
116
141
  dockerignore?.path,
117
142
  normalizeRelativePath(path.relative(context, dockerfile)),
118
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);
119
151
  // Walk one level at a time so an excluded directory is discarded before
120
152
  // its contents are read; entries come back sorted, preserving hash order.
121
153
  const entries = yield* walkIgnoring({
122
- list: yield* listFileSystemDirectory(context),
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))),
123
159
  rules: dockerignore?.rules,
124
160
  force: forcedPaths,
125
161
  });
126
- for (const { path: entry } of entries) {
162
+ for (const { path: entry, type } of entries) {
127
163
  // The ignore file and Dockerfile contents are hashed above; excluded
128
164
  // entries were only walked so re-included descendants could be found.
129
165
  if (dockerignore !== undefined &&
@@ -131,17 +167,13 @@ export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
131
167
  continue;
132
168
  }
133
169
  const fullPath = path.join(context, entry);
134
- const hashedEntry = entry;
135
- // FileSystem.stat follows symbolic links, so probe the link itself first.
136
- // Docker preserves the link in the build context; hashing the target file
137
- // would miss retargets between files with identical contents and metadata.
138
- const link = yield* Effect.result(fs.readLink(fullPath));
139
- if (Result.isSuccess(link)) {
140
- yield* Effect.sync(() => hasher.update(`${JSON.stringify({
141
- path: hashedEntry,
142
- type: "SymbolicLink",
143
- target: link.success,
144
- })}\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`));
145
177
  continue;
146
178
  }
147
179
  const info = yield* fs.stat(fullPath);
@@ -149,15 +181,22 @@ export const hashDockerBuildInputs = Effect.fn(function* (source, mode) {
149
181
  // directories. Include that metadata before any file bytes so changes such
150
182
  // as making a Lambda bootstrap executable invalidate the image tag.
151
183
  yield* Effect.sync(() => hasher.update(`${JSON.stringify({
152
- path: hashedEntry,
184
+ path: entry,
153
185
  type: info.type,
154
186
  mode: info.mode & 0o7777,
155
187
  size: info.type === "File" ? String(info.size) : undefined,
156
188
  })}\0`));
157
189
  if (info.type === "File") {
158
- yield* fs.stream(fullPath).pipe(Stream.runForEach((chunk) => Effect.sync(() => {
159
- hasher.update(chunk);
160
- })));
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
+ }
161
200
  }
162
201
  }
163
202
  return (yield* Effect.sync(() => hasher.digest("hex"))).slice(0, 32);
@@ -1 +1 @@
1
- {"version":3,"file":"BuildHash.js","sourceRoot":"","sources":["../src/BuildHash.ts"],"names":[],"mappings":"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"}
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