@alchemy.run/docker 0.0.0 → 2.0.0-beta.85

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/LICENSE +201 -0
  2. package/README.md +46 -4
  3. package/lib/Bootstrap.d.ts +7 -0
  4. package/lib/Bootstrap.d.ts.map +1 -0
  5. package/lib/Bootstrap.js +25 -0
  6. package/lib/Bootstrap.js.map +1 -0
  7. package/lib/BuildHash.d.ts +56 -0
  8. package/lib/BuildHash.d.ts.map +1 -0
  9. package/lib/BuildHash.js +172 -0
  10. package/lib/BuildHash.js.map +1 -0
  11. package/lib/Container.d.ts +450 -0
  12. package/lib/Container.d.ts.map +1 -0
  13. package/lib/Container.js +745 -0
  14. package/lib/Container.js.map +1 -0
  15. package/lib/Context.d.ts +86 -0
  16. package/lib/Context.d.ts.map +1 -0
  17. package/lib/Context.js +146 -0
  18. package/lib/Context.js.map +1 -0
  19. package/lib/Docker.d.ts +527 -0
  20. package/lib/Docker.d.ts.map +1 -0
  21. package/lib/Docker.js +437 -0
  22. package/lib/Docker.js.map +1 -0
  23. package/lib/Dockerfile.d.ts +72 -0
  24. package/lib/Dockerfile.d.ts.map +1 -0
  25. package/lib/Dockerfile.js +12 -0
  26. package/lib/Dockerfile.js.map +1 -0
  27. package/lib/HealthcheckCommand.d.ts +17 -0
  28. package/lib/HealthcheckCommand.d.ts.map +1 -0
  29. package/lib/HealthcheckCommand.js +33 -0
  30. package/lib/HealthcheckCommand.js.map +1 -0
  31. package/lib/Image.d.ts +179 -0
  32. package/lib/Image.d.ts.map +1 -0
  33. package/lib/Image.js +210 -0
  34. package/lib/Image.js.map +1 -0
  35. package/lib/ImageSource.d.ts +288 -0
  36. package/lib/ImageSource.d.ts.map +1 -0
  37. package/lib/ImageSource.js +498 -0
  38. package/lib/ImageSource.js.map +1 -0
  39. package/lib/Network.d.ts +70 -0
  40. package/lib/Network.d.ts.map +1 -0
  41. package/lib/Network.js +111 -0
  42. package/lib/Network.js.map +1 -0
  43. package/lib/Providers.d.ts +21 -0
  44. package/lib/Providers.d.ts.map +1 -0
  45. package/lib/Providers.js +26 -0
  46. package/lib/Providers.js.map +1 -0
  47. package/lib/Registry.d.ts +47 -0
  48. package/lib/Registry.d.ts.map +1 -0
  49. package/lib/Registry.js +67 -0
  50. package/lib/Registry.js.map +1 -0
  51. package/lib/RegistryError.d.ts +21 -0
  52. package/lib/RegistryError.d.ts.map +1 -0
  53. package/lib/RegistryError.js +28 -0
  54. package/lib/RegistryError.js.map +1 -0
  55. package/lib/RemoteImage.d.ts +118 -0
  56. package/lib/RemoteImage.d.ts.map +1 -0
  57. package/lib/RemoteImage.js +164 -0
  58. package/lib/RemoteImage.js.map +1 -0
  59. package/lib/Service.d.ts +499 -0
  60. package/lib/Service.d.ts.map +1 -0
  61. package/lib/Service.js +730 -0
  62. package/lib/Service.js.map +1 -0
  63. package/lib/ServiceImage.d.ts +78 -0
  64. package/lib/ServiceImage.d.ts.map +1 -0
  65. package/lib/ServiceImage.js +162 -0
  66. package/lib/ServiceImage.js.map +1 -0
  67. package/lib/Swarm.d.ts +119 -0
  68. package/lib/Swarm.d.ts.map +1 -0
  69. package/lib/Swarm.js +148 -0
  70. package/lib/Swarm.js.map +1 -0
  71. package/lib/Volume.d.ts +94 -0
  72. package/lib/Volume.d.ts.map +1 -0
  73. package/lib/Volume.js +133 -0
  74. package/lib/Volume.js.map +1 -0
  75. package/lib/index.d.ts +14 -0
  76. package/lib/index.d.ts.map +1 -0
  77. package/lib/index.js +13 -0
  78. package/lib/index.js.map +1 -0
  79. package/package.json +58 -3
  80. package/src/Bootstrap.ts +51 -0
  81. package/src/BuildHash.ts +265 -0
  82. package/src/Container.ts +1118 -0
  83. package/src/Context.ts +215 -0
  84. package/src/Docker.ts +1173 -0
  85. package/src/Dockerfile.ts +81 -0
  86. package/src/HealthcheckCommand.ts +35 -0
  87. package/src/Image.ts +322 -0
  88. package/src/ImageSource.ts +842 -0
  89. package/src/Network.ts +169 -0
  90. package/src/Providers.ts +46 -0
  91. package/src/Registry.ts +91 -0
  92. package/src/RegistryError.ts +48 -0
  93. package/src/RemoteImage.ts +255 -0
  94. package/src/Service.ts +1264 -0
  95. package/src/ServiceImage.ts +252 -0
  96. package/src/Swarm.ts +221 -0
  97. package/src/Volume.ts +193 -0
  98. package/src/index.ts +17 -0
package/lib/Docker.js ADDED
@@ -0,0 +1,437 @@
1
+ import { createPhysicalName } from "alchemy/PhysicalName";
2
+ import * as Config from "effect/Config";
3
+ import * as Context from "effect/Context";
4
+ import * as Effect from "effect/Effect";
5
+ import { Base64 } from "effect/encoding";
6
+ import * as FileSystem from "effect/FileSystem";
7
+ import { flow } from "effect/Function";
8
+ import * as Layer from "effect/Layer";
9
+ import * as Option from "effect/Option";
10
+ import * as Path from "effect/Path";
11
+ import { PlatformError, SystemError } from "effect/PlatformError";
12
+ import * as ChildProcess from "effect/process/ChildProcess";
13
+ import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
14
+ import * as Redacted from "effect/Redacted";
15
+ import * as Result from "effect/Result";
16
+ import * as Schema from "effect/Schema";
17
+ import * as Sink from "effect/Sink";
18
+ import * as Stream from "effect/Stream";
19
+ import { classifyDockerRegistryError } from "./RegistryError.js";
20
+ const RegistryAuth = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => {
21
+ const decoded = Base64.decode(value);
22
+ return Result.isSuccess(decoded) && decoded.success.indexOf(58) > 0;
23
+ })));
24
+ const decodeRegistryAuthConfig = Schema.Struct({
25
+ auths: Schema.Record(Schema.String, Schema.Struct({ auth: RegistryAuth })).pipe(Schema.NullOr, Schema.optional),
26
+ }).pipe(Schema.fromJsonString, (schema) => Schema.decodeEffect(schema, { onExcessProperty: "error" }));
27
+ export class Docker extends Context.Service()("@alchemy/Docker") {
28
+ }
29
+ /**
30
+ * Extra environment for every Docker CLI invocation, layered over the
31
+ * process environment (per-call variables still win). Scope it with
32
+ * `Effect.provideService(DockerEnvironment, { BUILDX_BUILDER: "ci" })` to
33
+ * target a buildx builder or Docker context without mutating `process.env`.
34
+ * @default {}
35
+ */
36
+ export const DockerEnvironment = Context.Reference("alchemy/Docker/DockerEnvironment", { defaultValue: () => ({}) });
37
+ /** The Docker CLI client, running `options.bin` (`DOCKER_BIN` overrides). */
38
+ export const dockerLive = (options = {}) => Layer.effect(Docker, makeDocker(options));
39
+ const makeDocker = (options) => Effect.gen(function* () {
40
+ const fs = yield* FileSystem.FileSystem;
41
+ const path = yield* Path.Path;
42
+ const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
43
+ const bin = yield* Config.String("DOCKER_BIN").pipe(Effect.orElseSucceed(() => options.bin ?? "docker"));
44
+ const run = (args, env, tap = Stream.tap(Effect.logDebug)) => Effect.gen(function* () {
45
+ const ambient = yield* DockerEnvironment;
46
+ return yield* spawner.spawn(ChildProcess.make(bin, args, {
47
+ stdin: "ignore",
48
+ stdout: "pipe",
49
+ stderr: "pipe",
50
+ detached: false,
51
+ env: { ...ambient, ...env },
52
+ extendEnv: true,
53
+ }));
54
+ }).pipe(Effect.flatMap((child) => Effect.all({
55
+ exitCode: child.exitCode,
56
+ stdout: child.stdout.pipe(Stream.decodeText, tap, Stream.mkString, Effect.map((stdout) => stdout.trim())),
57
+ stderr: child.stderr.pipe(Stream.decodeText, tap, Stream.mkString, Effect.map((stderr) => stderr.trim())),
58
+ }, { concurrency: "unbounded" })), Effect.mapError((error) => systemError({
59
+ _tag: "Unknown",
60
+ args,
61
+ // Name the CLI: a misconfigured `bin` / DOCKER_BIN fails here.
62
+ description: `Failed to run \`${bin}\`; is it installed and on PATH?`,
63
+ cause: error.reason,
64
+ })), Effect.tap((result) => {
65
+ if (result.exitCode === 0)
66
+ return Effect.void;
67
+ const stderr = result.stderr.replace(/^Error response from daemon: /, "");
68
+ if (stderr.match(/not found|not known|no such/i)) {
69
+ return systemError({ _tag: "NotFound", args, description: stderr });
70
+ }
71
+ if (stderr.match(/already exists/i)) {
72
+ return systemError({ _tag: "AlreadyExists", args, description: stderr });
73
+ }
74
+ return systemError({
75
+ _tag: "Unknown",
76
+ args,
77
+ description: `Command exited with code ${result.exitCode}: ${failureOutput(stderr, result.stdout)}`,
78
+ });
79
+ }), Effect.scoped);
80
+ const runInspect = (args) => run(args).pipe(Effect.map((result) => {
81
+ const [item] = JSON.parse(result.stdout);
82
+ return item;
83
+ }));
84
+ // Merge `credentials` into the ambient auth config: the process's
85
+ // DOCKER_AUTH_CONFIG, overlaid by one provided through DockerEnvironment
86
+ // (as `run` layers DockerEnvironment over the process environment).
87
+ // Merging, not replacing, keeps the user's own registry logins.
88
+ const registryEnvironment = Effect.fn("registryEnvironment")((credentials) => Effect.gen(function* () {
89
+ const value = yield* Config.Redacted("DOCKER_AUTH_CONFIG").pipe(Config.withDefault(Redacted.make("{}")));
90
+ const base = yield* decodeRegistryAuthConfig(Redacted.value(value) || "{}");
91
+ const ambient = yield* DockerEnvironment;
92
+ const overlay = ambient.DOCKER_AUTH_CONFIG === undefined
93
+ ? undefined
94
+ : yield* decodeRegistryAuthConfig(ambient.DOCKER_AUTH_CONFIG || "{}");
95
+ return { auths: { ...base.auths, ...overlay?.auths } };
96
+ }).pipe(
97
+ // Schema diagnostics may include credential input. Do not retain them.
98
+ Effect.mapError(() => systemError({
99
+ _tag: "InvalidData",
100
+ args: ["buildx", "build"],
101
+ description: "Invalid DOCKER_AUTH_CONFIG; expected an auths map.",
102
+ })), Effect.map((current) => {
103
+ const password = Redacted.isRedacted(credentials.password)
104
+ ? Redacted.value(credentials.password)
105
+ : credentials.password;
106
+ const auth = Base64.encode(`${credentials.username}:${password}`);
107
+ // Preserve Docker's file/helper fallback, contexts, and builders.
108
+ return {
109
+ DOCKER_AUTH_CONFIG: JSON.stringify({
110
+ auths: { ...current.auths, [credentials.server]: { auth } },
111
+ }),
112
+ };
113
+ })));
114
+ // How a build reaches a registry. Buildx 0.26 is the first release
115
+ // embedding Docker CLI 28.3's DOCKER_AUTH_CONFIG credential store, so it
116
+ // can `buildx build --push` straight from BuildKit. Older plugins (e.g.
117
+ // the buildx bundled with Docker Desktop < 4.44) silently ignore the
118
+ // variable, so the image is instead `--load`ed into the local store and
119
+ // published with the isolated-config `push`. Without any buildx plugin
120
+ // the legacy builder always loads, so a plain `image build` suffices.
121
+ // Probed once per Docker service instance.
122
+ const publication = yield* Effect.cached(Effect.gen(function* () {
123
+ const version = yield* run(["buildx", "version"]).pipe(Effect.option);
124
+ if (Option.isNone(version))
125
+ return "legacy";
126
+ // Numeric template captures can consume version separators as decimals.
127
+ const match = /^github\.com\/docker\/buildx v?(\d+)\.(\d+)\.\d+(?:[-+][^\s]+)?(?:\s.*)?$/.exec(version.value.stdout);
128
+ if (!match)
129
+ return "load";
130
+ const major = Number(match[1]);
131
+ const minor = Number(match[2]);
132
+ return major >= 1 || minor >= 26 ? "export" : "load";
133
+ }));
134
+ const outputTap = (session) => session
135
+ ? Stream.tapSink(Sink.make()(flow(Stream.splitLines, Stream.runForEach((line) => session.note(line, { kind: "output" })))))
136
+ : undefined;
137
+ // `podman push` prints no `digest:` line, and Podman's RepoDigests can
138
+ // list a source digest under the pushed name, so Podman pushes report the
139
+ // published digest through `--digestfile` instead. Probed once.
140
+ const isPodman = yield* Effect.cached(run(["--version"]).pipe(Effect.map((result) => /^podman\b/i.test(result.stdout.trim())), Effect.orElseSucceed(() => false)));
141
+ const push = Effect.fn(function* (ref, credentials, platform, context, session) {
142
+ // Write the registry credentials directly into an isolated docker config
143
+ // as a plaintext `auths` entry and skip `docker login` entirely.
144
+ //
145
+ // `docker login` is the wrong tool here: on macOS Docker Desktop it routes
146
+ // through the shared `osxkeychain`/`desktop` credential helper *regardless*
147
+ // of an isolated DOCKER_CONFIG, so concurrent deploys either race the system
148
+ // keychain (`The specified item already exists in the keychain (-25299)`) or
149
+ // land the credential in the helper — leaving this isolated config without
150
+ // an `auths` entry, so the subsequent `docker push` fails with "no basic
151
+ // auth credentials". Embedding the base64 `auth` inline (the same thing
152
+ // `docker login` would write when no credsStore is configured) makes each
153
+ // deploy fully self-contained: no credential helper, no keychain, no login
154
+ // race. Only `push` reads this config; `build`/`pull`/`tag` keep using the
155
+ // global docker config (buildx builders, `docker context`, etc. intact).
156
+ const dir = yield* fs.makeTempDirectoryScoped({ prefix: "alchemy-docker-" });
157
+ // The isolated DOCKER_CONFIG holds none of the CLI's contexts. Ask the CLI
158
+ // (same environment as the push) which context it would use, and copy just
159
+ // that context's metadata and TLS material in.
160
+ const selected = context ??
161
+ (yield* run(["context", "show"]).pipe(Effect.map((result) => result.stdout), Effect.orElseSucceed(() => "default")));
162
+ if (selected && selected !== "default") {
163
+ const inspected = yield* runInspect(["context", "inspect", selected]);
164
+ for (const [kind, source] of [
165
+ ["meta", inspected.Storage.MetadataPath],
166
+ ["tls", inspected.Storage.TLSPath],
167
+ ]) {
168
+ if (!(yield* fs.exists(source)))
169
+ continue;
170
+ const target = path.join(dir, "contexts", kind, path.basename(source));
171
+ yield* fs.makeDirectory(path.dirname(target), { recursive: true });
172
+ yield* fs.copy(source, target);
173
+ }
174
+ }
175
+ const pushContext = selected && selected !== "default" ? selected : context;
176
+ const config = yield* Effect.sync(() => {
177
+ const password = Redacted.isRedacted(credentials.password)
178
+ ? Redacted.value(credentials.password)
179
+ : credentials.password;
180
+ const auth = Buffer.from(`${credentials.username}:${password}`).toString("base64");
181
+ return JSON.stringify({ auths: { [credentials.server]: { auth } } });
182
+ });
183
+ yield* fs.writeFileString(path.join(dir, "config.json"), config);
184
+ const digestFile = path.join(dir, "digest");
185
+ const digestArgs = (yield* isPodman) ? ["--digestfile", digestFile] : [];
186
+ const result = platform === undefined
187
+ ? yield* run([...formatArgs({ context: pushContext }), "push", ...digestArgs, ref], { DOCKER_CONFIG: dir }, outputTap(session))
188
+ : yield* run([
189
+ ...formatArgs({ context: pushContext }),
190
+ "push",
191
+ "--platform",
192
+ platform,
193
+ ...digestArgs,
194
+ ref,
195
+ ], { DOCKER_CONFIG: dir }, outputTap(session)).pipe(
196
+ // Engines without the containerd image store reject `--platform`
197
+ // on push; their local tag is already narrowed to the requested
198
+ // platform by `pull --platform`, so a plain push is equivalent.
199
+ Effect.catchIf((error) => /--platform|unknown flag|containerd/i.test(String(error)), () => run([...formatArgs({ context: pushContext }), "push", ...digestArgs, ref], { DOCKER_CONFIG: dir }, outputTap(session))));
200
+ if (digestArgs.length === 0)
201
+ return result;
202
+ const digest = (yield* fs
203
+ .readFileString(digestFile)
204
+ .pipe(Effect.orElseSucceed(() => ""))).trim();
205
+ // Report it the way `docker push` does, so callers parse one format.
206
+ return digest ? { ...result, stdout: `${result.stdout}\ndigest: ${digest}` } : result;
207
+ }, Effect.scoped, Effect.mapError(classifyDockerRegistryError));
208
+ return Docker.of({
209
+ run,
210
+ materialize: Effect.fn((options) => Effect.forEach([...options.files, { path: "Dockerfile", content: options.dockerfile }], (file) => {
211
+ const fullPath = path.join(options.context, file.path);
212
+ return fs
213
+ .makeDirectory(path.dirname(fullPath), { recursive: true })
214
+ .pipe(Effect.andThen(typeof file.content === "string"
215
+ ? fs.writeFileString(fullPath, file.content)
216
+ : fs.writeFile(fullPath, file.content)));
217
+ }, { concurrency: "unbounded" })),
218
+ container: {
219
+ create: ({ image, env, command, context, ...options }) =>
220
+ // `--env KEY` (name-only) keeps values off CLI arguments; Docker
221
+ // copies each value from the CLI process environment, so the
222
+ // normalized container env must be passed to the child process.
223
+ run([
224
+ ...formatArgs({ context }),
225
+ "container",
226
+ "create",
227
+ ...formatArgs({ ...options, env: env ? Object.keys(env) : undefined }),
228
+ image,
229
+ ...(command ?? []),
230
+ ], env),
231
+ inspect: (name, context) => runInspect([...formatArgs({ context }), "container", "inspect", name]),
232
+ remove: (name, force, context) => run([...formatArgs({ context }), "container", "rm", name, ...(force ? ["-f"] : [])]),
233
+ start: (name, context) => run([...formatArgs({ context }), "container", "start", name]),
234
+ stop: (name, context) => run([...formatArgs({ context }), "container", "stop", name]),
235
+ },
236
+ image: {
237
+ build: Effect.fn("Docker.image.build")(function* ({ context: buildContext, engineContext, args, credentials, secrets, ...options }, session, registry) {
238
+ const tap = outputTap(session);
239
+ const secret = buildSecrets(secrets);
240
+ const buildArgs = [buildContext, ...formatArgs(options), ...secret.args, ...(args ?? [])];
241
+ const engine = formatArgs({ context: engineContext });
242
+ if (registry === undefined) {
243
+ return yield* run([...engine, "image", "build", ...buildArgs], {
244
+ ...(credentials ? yield* registryEnvironment(credentials) : undefined),
245
+ ...secret.env,
246
+ }, tap);
247
+ }
248
+ const mode = yield* publication;
249
+ if (mode === "export") {
250
+ // Export straight from BuildKit to the registry; the image never
251
+ // round-trips through the local image store.
252
+ const env = yield* registryEnvironment(registry);
253
+ return yield* run([...engine, "buildx", "build", "--push", ...buildArgs], { ...env, ...secret.env }, tap).pipe(Effect.mapError(classifyDockerRegistryError));
254
+ }
255
+ // Older Buildx ignores DOCKER_AUTH_CONFIG, so a `--push` export
256
+ // would fail with "no basic auth credentials". Build into the local
257
+ // store and publish with the isolated-config `push` instead.
258
+ // `--load` matters for non-loading builders (docker-container):
259
+ // without it the result stays in the build cache and `push` sees no
260
+ // such tag.
261
+ yield* run([
262
+ ...engine,
263
+ ...(mode === "load" ? ["buildx", "build", "--load"] : ["image", "build"]),
264
+ ...buildArgs,
265
+ ], secret.env, tap);
266
+ const [tag, ...tags] = typeof options.tag === "string" ? [options.tag] : options.tag;
267
+ return yield* push(tag, registry, options.platform, engineContext, session).pipe(Effect.tap(() => Effect.forEach(tags, (tag) => push(tag, registry, options.platform, engineContext, session))));
268
+ }),
269
+ pull: (ref, platform, context, session) => run([
270
+ ...formatArgs({ context }),
271
+ "image",
272
+ "pull",
273
+ ref,
274
+ ...(platform ? ["--platform", platform] : []),
275
+ ], undefined, outputTap(session)),
276
+ inspect: (ref, context) => runInspect([...formatArgs({ context }), "image", "inspect", ref]),
277
+ remove: (ref, force, context) => run([
278
+ ...formatArgs({ context }),
279
+ "image",
280
+ "rm",
281
+ ...(Array.isArray(ref) ? ref : [ref]),
282
+ ...(force ? ["-f"] : []),
283
+ ]),
284
+ tag: (source, target, context) => run([...formatArgs({ context }), "image", "tag", source, target]),
285
+ push,
286
+ },
287
+ volume: {
288
+ create: ({ context, ...options }) => run([...formatArgs({ context }), "volume", "create", ...formatArgs(options)]),
289
+ remove: (name, context) => run([...formatArgs({ context }), "volume", "rm", name]),
290
+ inspect: (name, context) => runInspect([...formatArgs({ context }), "volume", "inspect", name]),
291
+ },
292
+ context: {
293
+ create: ({ name, description, docker }) => run(["context", "create", name, ...formatArgs({ description, docker })]),
294
+ update: ({ name, description, docker }) => run(["context", "update", name, ...formatArgs({ description, docker })]),
295
+ inspect: (name) => runInspect(["context", "inspect", name]),
296
+ remove: (name, force) => run(["context", "rm", ...(force ? ["-f"] : []), name]),
297
+ },
298
+ network: {
299
+ create: ({ name, driver, ipv6, label, context }) => run([
300
+ ...formatArgs({ context }),
301
+ "network",
302
+ "create",
303
+ name,
304
+ ...formatArgs({ driver, ipv6, label }),
305
+ ]),
306
+ connect: ({ network, container, alias, context }) => run([
307
+ ...formatArgs({ context }),
308
+ "network",
309
+ "connect",
310
+ network,
311
+ container,
312
+ ...(alias ? alias.flatMap((a) => ["--alias", a]) : []),
313
+ ]),
314
+ disconnect: ({ network, container, context }) => run([...formatArgs({ context }), "network", "disconnect", network, container]),
315
+ inspect: (name, context) => runInspect([...formatArgs({ context }), "network", "inspect", name]),
316
+ remove: (id, context) => run([...formatArgs({ context }), "network", "rm", id]),
317
+ },
318
+ swarm: {
319
+ init: ({ context, ...options }) => run([...formatArgs({ context }), "swarm", "init", ...formatArgs(options)]),
320
+ info: (context) => run([...formatArgs({ context }), "info", "--format", "{{json .Swarm}}"]).pipe(Effect.map((result) => JSON.parse(result.stdout))),
321
+ leave: (force, context) => run([...formatArgs({ context }), "swarm", "leave", ...(force ? ["--force"] : [])]),
322
+ },
323
+ service: {
324
+ create: ({ context, image, command, args, ...options }) => run([
325
+ ...formatArgs({ context }),
326
+ "service",
327
+ "create",
328
+ ...formatArgs({ ...options }),
329
+ image,
330
+ ...(command ?? []),
331
+ ...(args ?? []),
332
+ ]),
333
+ update: ({ context, id, ...options }) => run([
334
+ ...formatArgs({ context }),
335
+ "service",
336
+ "update",
337
+ "--detach=false",
338
+ ...formatArgs({ ...options }),
339
+ id,
340
+ ]),
341
+ inspect: (id, context) => runInspect([...formatArgs({ context }), "service", "inspect", id]),
342
+ remove: (id, context) => run([...formatArgs({ context }), "service", "rm", id]),
343
+ },
344
+ });
345
+ });
346
+ /** The Docker CLI client, running `docker` (or `DOCKER_BIN`). */
347
+ export const DockerLive = dockerLive();
348
+ export const dockerContextName = (context) => {
349
+ const value = typeof context === "string" ? context : context?.name;
350
+ const normalized = value?.trim();
351
+ return normalized && normalized.length > 0 ? normalized : undefined;
352
+ };
353
+ /**
354
+ * Resolve an {@link Docker.EngineRef} to a context name. A `Docker.Swarm`
355
+ * reference (narrowed by its `nodeId` attribute) contributes the context the
356
+ * swarm was initialized on.
357
+ */
358
+ export const dockerEngineContextName = (ref) => {
359
+ if (typeof ref === "object" && ref !== null && "nodeId" in ref) {
360
+ return dockerContextName(ref.context);
361
+ }
362
+ return dockerContextName(ref);
363
+ };
364
+ export const dockerPhysicalName = (id, props, instanceId,
365
+ // Swarm service names are capped at 63 characters; other Docker object
366
+ // names accept much longer values.
367
+ maxLength = 128) => props?.name
368
+ ? Effect.succeed(props.name)
369
+ : createPhysicalName({ id, instanceId, maxLength, lowercase: true });
370
+ /**
371
+ * A failing `docker` command splits its diagnosis over both streams: the
372
+ * builder writes the step log to one and the reason it stopped to the other,
373
+ * and which carries which depends on the builder, the progress mode and
374
+ * whether the output is a terminal. A build that fails inside a `RUN` step
375
+ * therefore reports nothing but its exit code when only `stderr` is kept.
376
+ * Keep both, the reason first, so the error says why the build failed.
377
+ */
378
+ const failureOutput = (stderr, stdout) => {
379
+ const output = [stderr, stdout].filter((text) => text.length > 0);
380
+ return output.length > 0 ? output.join("\n") : "the command wrote no output.";
381
+ };
382
+ /** Constructs a PlatformError from a command execution result. */
383
+ const systemError = (input) => new PlatformError(new SystemError({
384
+ _tag: input._tag,
385
+ module: "Docker",
386
+ method: input.args.slice(0, 2).join("."),
387
+ pathOrDescriptor: input.args.join(" "),
388
+ description: input.description,
389
+ cause: input.cause,
390
+ }));
391
+ /**
392
+ * `--secret id=<id>,env=<var>` per secret, with each value under a generated
393
+ * variable name: an id is the Dockerfile author's choice and may collide with
394
+ * the environment Docker itself reads (`PATH`, `DOCKER_HOST`).
395
+ */
396
+ const buildSecrets = (secrets) => {
397
+ const args = [];
398
+ const env = {};
399
+ Object.entries(secrets ?? {}).forEach(([id, value], index) => {
400
+ const variable = `ALCHEMY_BUILD_SECRET_${index}`;
401
+ args.push("--secret", `id=${id},env=${variable}`);
402
+ env[variable] = Redacted.isRedacted(value) ? Redacted.value(value) : value;
403
+ });
404
+ return { args, env };
405
+ };
406
+ /** Formats a set of options into a list of command-line arguments. */
407
+ const formatArgs = (options) => {
408
+ const args = [];
409
+ for (const [key, value] of Object.entries(options)) {
410
+ // `0` is meaningful (`--replicas 0`, `--update-parallelism 0`), so only
411
+ // absent, `false` and empty values are omitted.
412
+ if (value === undefined || value === false || value === "")
413
+ continue;
414
+ const prefix = key.length > 1 ? `--${key}` : `-${key}`;
415
+ if (value === true) {
416
+ args.push(prefix);
417
+ }
418
+ else if (typeof value === "string") {
419
+ args.push(prefix, value);
420
+ }
421
+ else if (typeof value === "number") {
422
+ args.push(prefix, String(value));
423
+ }
424
+ else if (Array.isArray(value)) {
425
+ for (const item of value) {
426
+ args.push(prefix, item);
427
+ }
428
+ }
429
+ else if (value !== null && typeof value === "object") {
430
+ for (const [k, v] of Object.entries(value)) {
431
+ args.push(prefix, `${k}=${v}`);
432
+ }
433
+ }
434
+ }
435
+ return args;
436
+ };
437
+ //# sourceMappingURL=Docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Docker.js","sourceRoot":"","sources":["../src/Docker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Inline Dockerfile content for container platforms.
3
+ *
4
+ * Container platform props accept `dockerfile: string | { content: Input<string> }`:
5
+ * a plain string is always a **path** (relative to `context`); an object with a
6
+ * `content` key is **inline Dockerfile content**. `Dockerfile.inline` is the
7
+ * ergonomic way to produce the latter — a tagged template whose interpolations
8
+ * ride the normal {@link Output} machinery, so referencing another resource's
9
+ * attributes (e.g. an {@link ECR.Image}'s `imageUri`) creates a real dependency
10
+ * edge and re-resolves on change.
11
+ *
12
+ * The returned value is a plain JSON-serializable object (no symbols or
13
+ * brands) so it round-trips through persisted state unchanged; the structural
14
+ * `content` key is the discriminant.
15
+ *
16
+ * @example Base plus system packages, still bundling your Effect program
17
+ * ```typescript
18
+ * import * as Dockerfile from "@alchemy.run/docker/Dockerfile";
19
+ *
20
+ * const worker = yield* AWS.ECS.Task(
21
+ * "Transcoder",
22
+ * {
23
+ * cluster,
24
+ * main: import.meta.url,
25
+ * dockerfile: Dockerfile.inline`
26
+ * FROM oven/bun:1
27
+ * RUN apt-get update && apt-get install -y ffmpeg
28
+ * `,
29
+ * },
30
+ * impl,
31
+ * );
32
+ * ```
33
+ *
34
+ * @example Deriving from another resource's image (dependency edge for free)
35
+ * ```typescript
36
+ * const base = yield* AWS.ECR.Image("MlBase", { context: "./ml-base" });
37
+ *
38
+ * const trainer = yield* AWS.ECS.Task(
39
+ * "Trainer",
40
+ * {
41
+ * cluster,
42
+ * main: import.meta.url,
43
+ * dockerfile: Dockerfile.inline`
44
+ * FROM ${base.imageUri}
45
+ * RUN pip install -r /opt/requirements.txt
46
+ * `,
47
+ * },
48
+ * impl,
49
+ * );
50
+ * ```
51
+ */
52
+ import type { Input } from "alchemy/Input";
53
+ /**
54
+ * Inline Dockerfile content. A plain, state-serializable object; the
55
+ * structural `content` key distinguishes it from a path string wherever
56
+ * `dockerfile` props accept `string | InlineDockerfile`.
57
+ *
58
+ * Never interpolate secrets: anything in Dockerfile content is baked into
59
+ * image layers. `Input<string>` excludes `Redacted` values at the type level.
60
+ */
61
+ export interface InlineDockerfile {
62
+ readonly content: Input<string>;
63
+ }
64
+ /** Structural guard for {@link InlineDockerfile} vs a path string. */
65
+ export declare const isInlineDockerfile: (value: unknown) => value is InlineDockerfile;
66
+ /**
67
+ * Tagged template producing {@link InlineDockerfile}. Interpolations may be
68
+ * plain strings or `Output<string>`s (resolved at deploy time via
69
+ * `Output.interpolate`); with no interpolations the content is a plain string.
70
+ */
71
+ export declare const inline: (template: TemplateStringsArray, ...args: Array<Input<string>>) => InlineDockerfile;
72
+ //# sourceMappingURL=Dockerfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dockerfile.d.ts","sourceRoot":"","sources":["../src/Dockerfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAG3C;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,UAAW,OAAO,KAAG,KAAK,IAAI,gBACM,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,MAAM,aACP,oBAAoB,WACrB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAC5B,gBAED,CAAC"}
@@ -0,0 +1,12 @@
1
+ import * as Output from "alchemy/Output";
2
+ /** Structural guard for {@link InlineDockerfile} vs a path string. */
3
+ export const isInlineDockerfile = (value) => typeof value === "object" && value !== null && "content" in value;
4
+ /**
5
+ * Tagged template producing {@link InlineDockerfile}. Interpolations may be
6
+ * plain strings or `Output<string>`s (resolved at deploy time via
7
+ * `Output.interpolate`); with no interpolations the content is a plain string.
8
+ */
9
+ export const inline = (template, ...args) => ({
10
+ content: args.length === 0 ? template.raw.join("") : Output.interpolate(template, ...args),
11
+ });
12
+ //# sourceMappingURL=Dockerfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dockerfile.js","sourceRoot":"","sources":["../src/Dockerfile.ts"],"names":[],"mappings":"AAoDA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAczC,sEAAsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAc,EAA6B,EAAE,CAC9E,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS,IAAI,KAAK,CAAC;AAEpE;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,QAA8B,EAC9B,GAAG,IAA0B,EACX,EAAE,CAAC,CAAC;IACtB,OAAO,EAAE,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC;CAC3F,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Renders a healthcheck `cmd` as the single string Docker's `--health-cmd`
3
+ * flag takes. The flag always runs its value through the container's shell, so
4
+ * the Docker API's exec form has to be flattened:
5
+ *
6
+ * - `"cmd"`: used as is.
7
+ * - `["CMD-SHELL", "cmd"]`: the shell command, without the marker.
8
+ * - `["CMD", "pg_isready", "-U", "app"]`: the arguments, each quoted so it
9
+ * reaches the program as one argument.
10
+ * - `["NONE"]`: no command (the caller disables the healthcheck).
11
+ * - any other array: joined with spaces and run in the shell, as before, so
12
+ * `["curl -f localhost || exit 1"]` keeps working.
13
+ */
14
+ export declare const healthcheckCommand: (cmd: string[] | string) => string | undefined;
15
+ /** True when `cmd` is Docker's `["NONE"]` form, which disables the healthcheck. */
16
+ export declare const isHealthcheckDisabled: (cmd: string[] | string) => boolean;
17
+ //# sourceMappingURL=HealthcheckCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HealthcheckCommand.d.ts","sourceRoot":"","sources":["../src/HealthcheckCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,QAAS,MAAM,EAAE,GAAG,MAAM,KAAG,MAAM,GAAG,SAapE,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,qBAAqB,QAAS,MAAM,EAAE,GAAG,MAAM,KAAG,OACtB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Renders a healthcheck `cmd` as the single string Docker's `--health-cmd`
3
+ * flag takes. The flag always runs its value through the container's shell, so
4
+ * the Docker API's exec form has to be flattened:
5
+ *
6
+ * - `"cmd"`: used as is.
7
+ * - `["CMD-SHELL", "cmd"]`: the shell command, without the marker.
8
+ * - `["CMD", "pg_isready", "-U", "app"]`: the arguments, each quoted so it
9
+ * reaches the program as one argument.
10
+ * - `["NONE"]`: no command (the caller disables the healthcheck).
11
+ * - any other array: joined with spaces and run in the shell, as before, so
12
+ * `["curl -f localhost || exit 1"]` keeps working.
13
+ */
14
+ export const healthcheckCommand = (cmd) => {
15
+ if (typeof cmd === "string")
16
+ return cmd;
17
+ const [head, ...rest] = cmd;
18
+ switch (head) {
19
+ case "NONE":
20
+ return undefined;
21
+ case "CMD-SHELL":
22
+ return rest.join(" ");
23
+ case "CMD":
24
+ return rest.map(shellQuote).join(" ");
25
+ default:
26
+ return cmd.join(" ");
27
+ }
28
+ };
29
+ /** True when `cmd` is Docker's `["NONE"]` form, which disables the healthcheck. */
30
+ export const isHealthcheckDisabled = (cmd) => Array.isArray(cmd) && cmd[0] === "NONE";
31
+ /** Single-quotes an argument unless it is made only of shell-safe characters. */
32
+ const shellQuote = (arg) => /^[\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", `'\\''`)}'`;
33
+ //# sourceMappingURL=HealthcheckCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HealthcheckCommand.js","sourceRoot":"","sources":["../src/HealthcheckCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAsB,EAAsB,EAAE;IAC/E,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IAC5B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,KAAK,KAAK;YACR,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC;YACE,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAsB,EAAW,EAAE,CACvE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;AAE1C,iFAAiF;AACjF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAU,EAAE,CACzC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC"}