@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/src/Image.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as Effect from "effect/Effect";
|
|
|
6
6
|
import * as FileSystem from "effect/FileSystem";
|
|
7
7
|
import * as Path from "effect/Path";
|
|
8
8
|
import type * as Redacted from "effect/Redacted";
|
|
9
|
+
import { type BuildCacheOptions, buildCacheRef, resolveBuildCache } from "./BuildCache.ts";
|
|
9
10
|
import { Docker, dockerContextName, dockerPhysicalName } from "./Docker.ts";
|
|
10
11
|
import type { Providers } from "./Providers.ts";
|
|
11
12
|
import {
|
|
@@ -16,7 +17,7 @@ import {
|
|
|
16
17
|
withRegistryHost,
|
|
17
18
|
} from "./Registry.ts";
|
|
18
19
|
|
|
19
|
-
export interface DockerBuildOptions {
|
|
20
|
+
export interface DockerBuildOptions extends BuildCacheOptions {
|
|
20
21
|
/**
|
|
21
22
|
* Build context directory.
|
|
22
23
|
*
|
|
@@ -45,10 +46,6 @@ export interface DockerBuildOptions {
|
|
|
45
46
|
secrets?: Record<string, Redacted.Redacted<string>>;
|
|
46
47
|
/** Multi-stage build target. */
|
|
47
48
|
target?: string;
|
|
48
|
-
/** Cache sources passed as `--cache-from`. */
|
|
49
|
-
cacheFrom?: string[];
|
|
50
|
-
/** Cache destinations passed as `--cache-to`. */
|
|
51
|
-
cacheTo?: string[];
|
|
52
49
|
/** Additional Docker build options. */
|
|
53
50
|
options?: string[];
|
|
54
51
|
}
|
|
@@ -159,18 +156,35 @@ export interface Image extends Resource<
|
|
|
159
156
|
* });
|
|
160
157
|
* ```
|
|
161
158
|
*
|
|
162
|
-
* ### Private Base Images
|
|
163
|
-
* **Example:** Build FROM a private base image
|
|
159
|
+
* ### Private Base Images
|
|
160
|
+
* **Example:** Build FROM a private base image
|
|
164
161
|
* ```typescript
|
|
165
162
|
* // Dockerfile: FROM registry.example.com/base:v1
|
|
166
163
|
* const image = yield* Docker.Image("app", {
|
|
167
164
|
* name: "registry.example.com/app",
|
|
168
|
-
* build: {
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
165
|
+
* build: { context: "./app" },
|
|
166
|
+
* // Authenticates the base-image pull, then the push.
|
|
167
|
+
* registry: {
|
|
168
|
+
* server: "registry.example.com",
|
|
169
|
+
* username: "deploy",
|
|
170
|
+
* password: Config.Redacted("REGISTRY_PASSWORD"),
|
|
172
171
|
* },
|
|
173
|
-
*
|
|
172
|
+
* });
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* ### Caching Build Layers
|
|
176
|
+
* Builds reuse the local BuildKit cache of the machine they run on, and
|
|
177
|
+
* nothing but the image is pushed. A builder that has never built the image,
|
|
178
|
+
* such as a fresh CI runner, reruns every step. Set `build.cache: true` to keep
|
|
179
|
+
* every stage's layers at the image repository's `:buildcache` tag, so fresh
|
|
180
|
+
* builders skip unchanged steps. For another backend, pass BuildKit's own
|
|
181
|
+
* `--cache-from` / `--cache-to` values as `from` and `to`.
|
|
182
|
+
*
|
|
183
|
+
* **Example:** Cache layers in the image's registry
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const image = yield* Docker.Image("app", {
|
|
186
|
+
* name: "registry.example.com/app",
|
|
187
|
+
* build: { context: "./app", cache: true },
|
|
174
188
|
* registry: {
|
|
175
189
|
* server: "registry.example.com",
|
|
176
190
|
* username: "deploy",
|
|
@@ -179,6 +193,20 @@ export interface Image extends Resource<
|
|
|
179
193
|
* });
|
|
180
194
|
* ```
|
|
181
195
|
*
|
|
196
|
+
* **Example:** Cache layers in GitHub Actions
|
|
197
|
+
* ```typescript
|
|
198
|
+
* const image = yield* Docker.Image("app", {
|
|
199
|
+
* name: "my-app",
|
|
200
|
+
* build: {
|
|
201
|
+
* context: "./app",
|
|
202
|
+
* cache: {
|
|
203
|
+
* from: ["type=gha,scope=app"],
|
|
204
|
+
* to: ["type=gha,scope=app,mode=max"],
|
|
205
|
+
* },
|
|
206
|
+
* },
|
|
207
|
+
* });
|
|
208
|
+
* ```
|
|
209
|
+
*
|
|
182
210
|
* ### Docker Context
|
|
183
211
|
* **Example:** Build in a named Docker context
|
|
184
212
|
* ```typescript
|
|
@@ -221,8 +249,11 @@ export const ImageProvider = () =>
|
|
|
221
249
|
target: props.build.target,
|
|
222
250
|
"build-arg": props.build.args,
|
|
223
251
|
secrets: props.build.secrets,
|
|
224
|
-
|
|
225
|
-
|
|
252
|
+
// The registry cache lives next to the image.
|
|
253
|
+
...resolveBuildCache(
|
|
254
|
+
props.build.cache,
|
|
255
|
+
buildCacheRef(props.registry ? withRegistryHost(ref, props.registry) : ref),
|
|
256
|
+
),
|
|
226
257
|
args: props.build.options,
|
|
227
258
|
engineContext,
|
|
228
259
|
// Base images and registry caches may live in the same registry;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image archives: a Docker build context built for one platform and saved
|
|
3
|
+
* with `docker save`, for hosts with no registry between the deploy and the
|
|
4
|
+
* machine that runs it (a VM that loads the archive into its own Docker).
|
|
5
|
+
*/
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import * as FileSystem from "effect/FileSystem";
|
|
8
|
+
import * as Path from "effect/Path";
|
|
9
|
+
import { hashDockerBuildInputs, resolveDockerBuildPaths } from "./BuildHash.ts";
|
|
10
|
+
import { Docker } from "./Docker.ts";
|
|
11
|
+
|
|
12
|
+
export interface ImageArchiveSource {
|
|
13
|
+
/** The Docker build context directory. */
|
|
14
|
+
context: string;
|
|
15
|
+
/**
|
|
16
|
+
* The Dockerfile, relative to the context unless absolute.
|
|
17
|
+
* @default "Dockerfile"
|
|
18
|
+
*/
|
|
19
|
+
dockerfile?: string;
|
|
20
|
+
/** The platform the archive's image is built for, e.g. `linux/amd64`. */
|
|
21
|
+
platform: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const pathsOf = Effect.fn(function* (source: ImageArchiveSource) {
|
|
25
|
+
const path = yield* Path.Path;
|
|
26
|
+
const dockerfile =
|
|
27
|
+
source.dockerfile === undefined
|
|
28
|
+
? path.join(source.context, "Dockerfile")
|
|
29
|
+
: path.isAbsolute(source.dockerfile)
|
|
30
|
+
? source.dockerfile
|
|
31
|
+
: path.join(source.context, source.dockerfile);
|
|
32
|
+
return yield* resolveDockerBuildPaths({ context: source.context, dockerfile });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A content hash of the inputs an archive is built from: the context's
|
|
37
|
+
* files (after `.dockerignore`), the Dockerfile and the platform. It
|
|
38
|
+
* changes exactly when the archive's image would.
|
|
39
|
+
*/
|
|
40
|
+
export const hashImageArchive = Effect.fn(function* (source: ImageArchiveSource) {
|
|
41
|
+
const { context, dockerfile } = yield* pathsOf(source);
|
|
42
|
+
return yield* hashDockerBuildInputs(
|
|
43
|
+
{ context, dockerfile, platform: source.platform },
|
|
44
|
+
"effective",
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Build `source` and save its image to an archive at `output`, tagged
|
|
50
|
+
* `tag`, the name `docker load` reports where the archive is loaded.
|
|
51
|
+
* Resolves to the archive's bytes.
|
|
52
|
+
*/
|
|
53
|
+
export const buildImageArchive = Effect.fn(function* (
|
|
54
|
+
source: ImageArchiveSource,
|
|
55
|
+
options: { readonly tag: string; readonly output: string },
|
|
56
|
+
) {
|
|
57
|
+
const docker = yield* Docker;
|
|
58
|
+
const fs = yield* FileSystem.FileSystem;
|
|
59
|
+
const path = yield* Path.Path;
|
|
60
|
+
const { context, dockerfile } = yield* pathsOf(source);
|
|
61
|
+
yield* docker.image.build({
|
|
62
|
+
context,
|
|
63
|
+
file: dockerfile,
|
|
64
|
+
tag: options.tag,
|
|
65
|
+
platform: source.platform,
|
|
66
|
+
});
|
|
67
|
+
yield* fs.makeDirectory(path.dirname(options.output), { recursive: true });
|
|
68
|
+
yield* docker.run(["save", options.tag, "-o", options.output]);
|
|
69
|
+
return yield* fs.readFile(options.output);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Shell lines that load the archive at `archive` into Docker and set the
|
|
74
|
+
* shell variable `IMAGE` to the image it holds.
|
|
75
|
+
*/
|
|
76
|
+
export const loadImageArchiveScript = (archive: string) =>
|
|
77
|
+
`IMAGE="$(docker load -i ${archive} | sed -n 's/^Loaded image: //p' | tail -1)"`;
|