Skip to content

Commit 971ddc3

Browse files
committed
don't require docker binary
1 parent 2aee3de commit 971ddc3

File tree

4 files changed

+57
-48
lines changed

4 files changed

+57
-48
lines changed

apps/supervisor/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
"@kubernetes/client-node": "^1.0.0",
1717
"@trigger.dev/core": "workspace:*",
1818
"dockerode": "^4.0.3",
19-
"nanoid": "^5.0.9",
2019
"prom-client": "^15.1.0",
2120
"socket.io": "4.7.4",
2221
"std-env": "^3.8.0",
23-
"tinyexec": "^0.3.1",
2422
"zod": "3.23.8"
2523
},
2624
"devDependencies": {

apps/supervisor/src/env.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const Env = z.object({
4444

4545
// Used by the workload manager, e.g docker/k8s
4646
DOCKER_NETWORK: z.string().default("host"),
47+
DOCKER_SOCKET_PATH: z.string().default("/var/run/docker.sock"),
4748
OTEL_EXPORTER_OTLP_ENDPOINT: z.string().url(),
4849
ENFORCE_MACHINE_PRESETS: z.coerce.boolean().default(false),
4950
KUBERNETES_IMAGE_PULL_SECRETS: z.string().optional(), // csv

apps/supervisor/src/workloadManager/docker.ts

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,88 +4,104 @@ import {
44
type WorkloadManagerCreateOptions,
55
type WorkloadManagerOptions,
66
} from "./types.js";
7-
import { x } from "tinyexec";
87
import { env } from "../env.js";
98
import { getDockerHostDomain, getRunnerId } from "../util.js";
9+
import Docker from "dockerode";
1010

1111
export class DockerWorkloadManager implements WorkloadManager {
12-
private readonly logger = new SimpleStructuredLogger("docker-workload-provider");
12+
private readonly logger = new SimpleStructuredLogger("docker-workload-manager");
13+
private readonly docker: Docker;
1314

1415
constructor(private opts: WorkloadManagerOptions) {
16+
this.docker = new Docker({
17+
socketPath: env.DOCKER_SOCKET_PATH,
18+
});
19+
1520
if (opts.workloadApiDomain) {
16-
this.logger.warn("[DockerWorkloadProvider] ⚠️ Custom workload API domain", {
21+
this.logger.warn("⚠️ Custom workload API domain", {
1722
domain: opts.workloadApiDomain,
1823
});
1924
}
2025
}
2126

2227
async create(opts: WorkloadManagerCreateOptions) {
23-
this.logger.log("[DockerWorkloadProvider] Creating container", { opts });
28+
this.logger.log("create()", { opts });
2429

2530
const runnerId = getRunnerId(opts.runFriendlyId, opts.nextAttemptNumber);
2631

27-
const runArgs = [
28-
"run",
29-
"--detach",
30-
`--network=${env.DOCKER_NETWORK}`,
31-
`--env=TRIGGER_DEQUEUED_AT_MS=${opts.dequeuedAt.getTime()}`,
32-
`--env=TRIGGER_POD_SCHEDULED_AT_MS=${Date.now()}`,
33-
`--env=TRIGGER_ENV_ID=${opts.envId}`,
34-
`--env=TRIGGER_RUN_ID=${opts.runFriendlyId}`,
35-
`--env=TRIGGER_SNAPSHOT_ID=${opts.snapshotFriendlyId}`,
36-
`--env=TRIGGER_SUPERVISOR_API_PROTOCOL=${this.opts.workloadApiProtocol}`,
37-
`--env=TRIGGER_SUPERVISOR_API_PORT=${this.opts.workloadApiPort}`,
38-
`--env=TRIGGER_SUPERVISOR_API_DOMAIN=${this.opts.workloadApiDomain ?? getDockerHostDomain()}`,
39-
`--env=TRIGGER_WORKER_INSTANCE_NAME=${env.TRIGGER_WORKER_INSTANCE_NAME}`,
40-
`--env=OTEL_EXPORTER_OTLP_ENDPOINT=${env.OTEL_EXPORTER_OTLP_ENDPOINT}`,
41-
`--env=TRIGGER_RUNNER_ID=${runnerId}`,
42-
`--hostname=${runnerId}`,
43-
`--name=${runnerId}`,
32+
// Build environment variables
33+
const envVars: string[] = [
34+
`TRIGGER_DEQUEUED_AT_MS=${opts.dequeuedAt.getTime()}`,
35+
`TRIGGER_POD_SCHEDULED_AT_MS=${Date.now()}`,
36+
`TRIGGER_ENV_ID=${opts.envId}`,
37+
`TRIGGER_RUN_ID=${opts.runFriendlyId}`,
38+
`TRIGGER_SNAPSHOT_ID=${opts.snapshotFriendlyId}`,
39+
`TRIGGER_SUPERVISOR_API_PROTOCOL=${this.opts.workloadApiProtocol}`,
40+
`TRIGGER_SUPERVISOR_API_PORT=${this.opts.workloadApiPort}`,
41+
`TRIGGER_SUPERVISOR_API_DOMAIN=${this.opts.workloadApiDomain ?? getDockerHostDomain()}`,
42+
`TRIGGER_WORKER_INSTANCE_NAME=${env.TRIGGER_WORKER_INSTANCE_NAME}`,
43+
`OTEL_EXPORTER_OTLP_ENDPOINT=${env.OTEL_EXPORTER_OTLP_ENDPOINT}`,
44+
`TRIGGER_RUNNER_ID=${runnerId}`,
4445
];
4546

46-
if (this.opts.dockerAutoremove) {
47-
runArgs.push("--rm");
48-
}
49-
5047
if (this.opts.warmStartUrl) {
51-
runArgs.push(`--env=TRIGGER_WARM_START_URL=${this.opts.warmStartUrl}`);
48+
envVars.push(`TRIGGER_WARM_START_URL=${this.opts.warmStartUrl}`);
5249
}
5350

5451
if (this.opts.metadataUrl) {
55-
runArgs.push(`--env=TRIGGER_METADATA_URL=${this.opts.metadataUrl}`);
52+
envVars.push(`TRIGGER_METADATA_URL=${this.opts.metadataUrl}`);
5653
}
5754

5855
if (this.opts.heartbeatIntervalSeconds) {
59-
runArgs.push(
60-
`--env=TRIGGER_HEARTBEAT_INTERVAL_SECONDS=${this.opts.heartbeatIntervalSeconds}`
61-
);
56+
envVars.push(`TRIGGER_HEARTBEAT_INTERVAL_SECONDS=${this.opts.heartbeatIntervalSeconds}`);
6257
}
6358

6459
if (this.opts.snapshotPollIntervalSeconds) {
65-
runArgs.push(
66-
`--env=TRIGGER_SNAPSHOT_POLL_INTERVAL_SECONDS=${this.opts.snapshotPollIntervalSeconds}`
60+
envVars.push(
61+
`TRIGGER_SNAPSHOT_POLL_INTERVAL_SECONDS=${this.opts.snapshotPollIntervalSeconds}`
6762
);
6863
}
6964

7065
if (this.opts.additionalEnvVars) {
7166
Object.entries(this.opts.additionalEnvVars).forEach(([key, value]) => {
72-
runArgs.push(`--env=${key}=${value}`);
67+
envVars.push(`${key}=${value}`);
7368
});
7469
}
7570

71+
const hostConfig: Docker.HostConfig = {
72+
NetworkMode: env.DOCKER_NETWORK,
73+
AutoRemove: !!this.opts.dockerAutoremove,
74+
};
75+
7676
if (env.ENFORCE_MACHINE_PRESETS) {
77-
runArgs.push(`--cpus=${opts.machine.cpu}`, `--memory=${opts.machine.memory}G`);
78-
runArgs.push(`--env=TRIGGER_MACHINE_CPU=${opts.machine.cpu}`);
79-
runArgs.push(`--env=TRIGGER_MACHINE_MEMORY=${opts.machine.memory}`);
77+
envVars.push(`TRIGGER_MACHINE_CPU=${opts.machine.cpu}`);
78+
envVars.push(`TRIGGER_MACHINE_MEMORY=${opts.machine.memory}`);
79+
80+
hostConfig.NanoCpus = opts.machine.cpu * 1e9;
81+
hostConfig.Memory = opts.machine.memory * 1024 * 1024 * 1024;
8082
}
8183

82-
runArgs.push(`${opts.image}`);
84+
const containerCreateOpts: Docker.ContainerCreateOptions = {
85+
Env: envVars,
86+
name: runnerId,
87+
Hostname: runnerId,
88+
HostConfig: hostConfig,
89+
Image: opts.image,
90+
AttachStdout: false,
91+
AttachStderr: false,
92+
AttachStdin: false,
93+
};
8394

8495
try {
85-
const { stdout, stderr } = await x("docker", runArgs);
86-
this.logger.debug("[DockerWorkloadProvider] Create succeeded", { stdout, stderr });
96+
// Create container
97+
const container = await this.docker.createContainer(containerCreateOpts);
98+
99+
// Start container
100+
const startResult = await container.start();
101+
102+
this.logger.debug("create succeeded", { opts, startResult, container, containerCreateOpts });
87103
} catch (error) {
88-
this.logger.error("[DockerWorkloadProvider] Create failed:", { opts, error });
104+
this.logger.error("create failed:", { opts, error, containerCreateOpts });
89105
}
90106
}
91107
}

pnpm-lock.yaml

Lines changed: 0 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)