From 80b6845a6f0023da29fccda49b838dfd9d26ce32 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Sat, 21 Feb 2026 14:51:25 +0000 Subject: [PATCH 1/2] fix(docker-runner): ship dist artifacts --- packages/docker-runner/Dockerfile | 11 ++++++---- packages/docker-runner/src/contracts/api.ts | 2 +- packages/docker-runner/src/contracts/auth.ts | 2 +- packages/docker-runner/src/index.ts | 22 +++++++++---------- .../docker-runner/src/lib/container.handle.ts | 4 ++-- .../src/lib/container.service.ts | 14 ++++++------ .../src/lib/containerRegistry.port.ts | 2 +- .../src/lib/dockerClient.port.ts | 4 ++-- packages/docker-runner/src/service/app.ts | 8 +++---- packages/docker-runner/src/service/main.ts | 6 ++--- 10 files changed, 39 insertions(+), 36 deletions(-) diff --git a/packages/docker-runner/Dockerfile b/packages/docker-runner/Dockerfile index 49fa86b8b..8de7328a9 100644 --- a/packages/docker-runner/Dockerfile +++ b/packages/docker-runner/Dockerfile @@ -23,18 +23,21 @@ FROM base AS build COPY . . -# Avoid workspace-wide postinstall/prepare (platform-server runs prisma generate) RUN pnpm install --filter @agyn/docker-runner... --offline --frozen-lockfile --ignore-scripts RUN pnpm --filter @agyn/docker-runner run build -# pnpm deploy copies workspace deps and re-runs postinstall/prepare; skip scripts -RUN PNPM_SKIP_POSTINSTALL=1 PNPM_SKIP_PREPARE=1 npm_config_ignore_scripts=true pnpm deploy --filter @agyn/docker-runner --prod --legacy /opt/app +RUN PNPM_SKIP_POSTINSTALL=1 PNPM_SKIP_PREPARE=1 npm_config_ignore_scripts=true \ + pnpm deploy --filter @agyn/docker-runner --prod --legacy /opt/app + +RUN mkdir -p /opt/app/packages/docker-runner/dist \ + && cp -R /workspace/packages/docker-runner/dist/* /opt/app/packages/docker-runner/dist/ FROM node:20-slim AS runtime ENV NODE_ENV=production \ - PORT=7071 + DOCKER_RUNNER_HOST=0.0.0.0 \ + DOCKER_RUNNER_PORT=7071 WORKDIR /opt/app/packages/docker-runner diff --git a/packages/docker-runner/src/contracts/api.ts b/packages/docker-runner/src/contracts/api.ts index 42eeef9e9..cb975ebcb 100644 --- a/packages/docker-runner/src/contracts/api.ts +++ b/packages/docker-runner/src/contracts/api.ts @@ -1,5 +1,5 @@ import type Docker from 'dockerode'; -import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types'; +import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types.js'; export type ErrorPayload = { error: { diff --git a/packages/docker-runner/src/contracts/auth.ts b/packages/docker-runner/src/contracts/auth.ts index 8dbebc5e0..e6d61518a 100644 --- a/packages/docker-runner/src/contracts/auth.ts +++ b/packages/docker-runner/src/contracts/auth.ts @@ -1,5 +1,5 @@ import crypto from 'node:crypto'; -import { canonicalJsonStringify } from './json'; +import { canonicalJsonStringify } from './json.js'; export type SignatureHeaders = { timestamp: string; diff --git a/packages/docker-runner/src/index.ts b/packages/docker-runner/src/index.ts index 44a37adc5..d4e53ec20 100644 --- a/packages/docker-runner/src/index.ts +++ b/packages/docker-runner/src/index.ts @@ -1,11 +1,11 @@ -export * from './lib/container.service'; -export * from './lib/container.handle'; -export * from './lib/container.mounts'; -export * from './lib/containerStream.util'; -export * from './lib/containerRegistry.port'; -export * from './lib/dockerClient.port'; -export * from './lib/execTimeout'; -export * from './lib/types'; -export * from './contracts/auth'; -export * from './contracts/json'; -export * from './contracts/api'; +export * from './lib/container.service.js'; +export * from './lib/container.handle.js'; +export * from './lib/container.mounts.js'; +export * from './lib/containerStream.util.js'; +export * from './lib/containerRegistry.port.js'; +export * from './lib/dockerClient.port.js'; +export * from './lib/execTimeout.js'; +export * from './lib/types.js'; +export * from './contracts/auth.js'; +export * from './contracts/json.js'; +export * from './contracts/api.js'; diff --git a/packages/docker-runner/src/lib/container.handle.ts b/packages/docker-runner/src/lib/container.handle.ts index b0964b2fa..be21f7b2e 100644 --- a/packages/docker-runner/src/lib/container.handle.ts +++ b/packages/docker-runner/src/lib/container.handle.ts @@ -1,5 +1,5 @@ -import type { DockerClientPort } from './dockerClient.port'; -import type { ExecOptions } from './types'; +import type { DockerClientPort } from './dockerClient.port.js'; +import type { ExecOptions } from './types.js'; /** * Lightweight entity wrapper representing a running (or created) container. diff --git a/packages/docker-runner/src/lib/container.service.ts b/packages/docker-runner/src/lib/container.service.ts index d2682419d..cd42b47a5 100644 --- a/packages/docker-runner/src/lib/container.service.ts +++ b/packages/docker-runner/src/lib/container.service.ts @@ -1,12 +1,12 @@ import { Injectable, Logger } from '@nestjs/common'; import Docker, { ContainerCreateOptions, Exec, type GetEventsOptions } from 'dockerode'; import { PassThrough, Writable } from 'node:stream'; -import { ContainerHandle } from './container.handle'; -import { mapInspectMounts } from './container.mounts'; -import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util'; -import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout'; -import type { ContainerRegistryPort } from './containerRegistry.port'; -import type { DockerClientPort } from './dockerClient.port'; +import { ContainerHandle } from './container.handle.js'; +import { mapInspectMounts } from './container.mounts.js'; +import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util.js'; +import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout.js'; +import type { ContainerRegistryPort } from './containerRegistry.port.js'; +import type { DockerClientPort } from './dockerClient.port.js'; import { ContainerOpts, ExecOptions, @@ -17,7 +17,7 @@ import { LogsStreamSession, Platform, PLATFORM_LABEL, -} from './types'; +} from './types.js'; const INTERACTIVE_EXEC_CLOSE_CAPTURE_LIMIT = 256 * 1024; // 256 KiB of characters (~512 KiB memory) diff --git a/packages/docker-runner/src/lib/containerRegistry.port.ts b/packages/docker-runner/src/lib/containerRegistry.port.ts index a0490a7f9..0250c6adf 100644 --- a/packages/docker-runner/src/lib/containerRegistry.port.ts +++ b/packages/docker-runner/src/lib/containerRegistry.port.ts @@ -1,4 +1,4 @@ -import type { ContainerMount } from './container.mounts'; +import type { ContainerMount } from './container.mounts.js'; export type RegisterContainerStartInput = { containerId: string; diff --git a/packages/docker-runner/src/lib/dockerClient.port.ts b/packages/docker-runner/src/lib/dockerClient.port.ts index 66fd1be98..29d64978e 100644 --- a/packages/docker-runner/src/lib/dockerClient.port.ts +++ b/packages/docker-runner/src/lib/dockerClient.port.ts @@ -1,4 +1,4 @@ -import type { ContainerHandle } from './container.handle'; +import type { ContainerHandle } from './container.handle.js'; import type { ContainerOpts, ExecOptions, @@ -8,7 +8,7 @@ import type { LogsStreamOptions, LogsStreamSession, Platform, -} from './types'; +} from './types.js'; export type DockerEventFilters = Record>; diff --git a/packages/docker-runner/src/service/app.ts b/packages/docker-runner/src/service/app.ts index 209bb5dbd..56e270ed1 100644 --- a/packages/docker-runner/src/service/app.ts +++ b/packages/docker-runner/src/service/app.ts @@ -10,10 +10,10 @@ import { verifyAuthHeaders, type ContainerOpts, type ExecOptions, -} from '..'; -import { createDockerEventsParser } from './dockerEvents.parser'; -import type { RunnerConfig } from './config'; -import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util'; +} from '../index.js'; +import { createDockerEventsParser } from './dockerEvents.parser.js'; +import type { RunnerConfig } from './config.js'; +import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util.js'; const ensureImageSchema = z.object({ image: z.string().min(1), diff --git a/packages/docker-runner/src/service/main.ts b/packages/docker-runner/src/service/main.ts index 61be2f7f2..53926b912 100644 --- a/packages/docker-runner/src/service/main.ts +++ b/packages/docker-runner/src/service/main.ts @@ -1,7 +1,7 @@ -import './env'; +import './env.js'; -import { loadRunnerConfig } from './config'; -import { createRunnerApp } from './app'; +import { loadRunnerConfig } from './config.js'; +import { createRunnerApp } from './app.js'; async function bootstrap(): Promise { try { From 5353be8ad634f41d26a779bf69dcef274783b302 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Sat, 21 Feb 2026 15:43:02 +0000 Subject: [PATCH 2/2] fix(docker-runner): mirror server build structure --- packages/docker-runner/Dockerfile | 6 ++--- .../{eslint.config.js => eslint.config.mjs} | 0 packages/docker-runner/package.json | 1 - packages/docker-runner/src/contracts/api.ts | 2 +- packages/docker-runner/src/contracts/auth.ts | 2 +- packages/docker-runner/src/index.ts | 22 +++++++++---------- .../docker-runner/src/lib/container.handle.ts | 4 ++-- .../src/lib/container.service.ts | 14 ++++++------ .../src/lib/containerRegistry.port.ts | 2 +- .../src/lib/dockerClient.port.ts | 4 ++-- packages/docker-runner/src/service/app.ts | 8 +++---- packages/docker-runner/src/service/env.ts | 3 +-- packages/docker-runner/src/service/main.ts | 6 ++--- packages/docker-runner/tsconfig.json | 2 ++ 14 files changed, 38 insertions(+), 38 deletions(-) rename packages/docker-runner/{eslint.config.js => eslint.config.mjs} (100%) diff --git a/packages/docker-runner/Dockerfile b/packages/docker-runner/Dockerfile index 8de7328a9..7ea587c31 100644 --- a/packages/docker-runner/Dockerfile +++ b/packages/docker-runner/Dockerfile @@ -10,7 +10,7 @@ RUN corepack enable \ && corepack prepare pnpm@10.5.0 --activate RUN apt-get update \ - && apt-get install -y --no-install-recommends git \ + && apt-get install -y --no-install-recommends git openssl \ && rm -rf /var/lib/apt/lists/* WORKDIR /workspace @@ -31,7 +31,7 @@ RUN PNPM_SKIP_POSTINSTALL=1 PNPM_SKIP_PREPARE=1 npm_config_ignore_scripts=true \ pnpm deploy --filter @agyn/docker-runner --prod --legacy /opt/app RUN mkdir -p /opt/app/packages/docker-runner/dist \ - && cp -R /workspace/packages/docker-runner/dist/* /opt/app/packages/docker-runner/dist/ + && cp -a /workspace/packages/docker-runner/dist/. /opt/app/packages/docker-runner/dist/ FROM node:20-slim AS runtime @@ -42,7 +42,7 @@ ENV NODE_ENV=production \ WORKDIR /opt/app/packages/docker-runner RUN apt-get update \ - && apt-get install -y --no-install-recommends git \ + && apt-get install -y --no-install-recommends git openssl \ && rm -rf /var/lib/apt/lists/* COPY --from=build --chown=node:node /opt/app /opt/app diff --git a/packages/docker-runner/eslint.config.js b/packages/docker-runner/eslint.config.mjs similarity index 100% rename from packages/docker-runner/eslint.config.js rename to packages/docker-runner/eslint.config.mjs diff --git a/packages/docker-runner/package.json b/packages/docker-runner/package.json index 941443a00..f2c1fdac3 100644 --- a/packages/docker-runner/package.json +++ b/packages/docker-runner/package.json @@ -2,7 +2,6 @@ "name": "@agyn/docker-runner", "version": "1.0.0", "private": true, - "type": "module", "main": "src/index.ts", "scripts": { "dev": "tsx src/service/main.ts", diff --git a/packages/docker-runner/src/contracts/api.ts b/packages/docker-runner/src/contracts/api.ts index cb975ebcb..42eeef9e9 100644 --- a/packages/docker-runner/src/contracts/api.ts +++ b/packages/docker-runner/src/contracts/api.ts @@ -1,5 +1,5 @@ import type Docker from 'dockerode'; -import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types.js'; +import type { ContainerOpts, ExecOptions, ExecResult, Platform } from '../lib/types'; export type ErrorPayload = { error: { diff --git a/packages/docker-runner/src/contracts/auth.ts b/packages/docker-runner/src/contracts/auth.ts index e6d61518a..8dbebc5e0 100644 --- a/packages/docker-runner/src/contracts/auth.ts +++ b/packages/docker-runner/src/contracts/auth.ts @@ -1,5 +1,5 @@ import crypto from 'node:crypto'; -import { canonicalJsonStringify } from './json.js'; +import { canonicalJsonStringify } from './json'; export type SignatureHeaders = { timestamp: string; diff --git a/packages/docker-runner/src/index.ts b/packages/docker-runner/src/index.ts index d4e53ec20..44a37adc5 100644 --- a/packages/docker-runner/src/index.ts +++ b/packages/docker-runner/src/index.ts @@ -1,11 +1,11 @@ -export * from './lib/container.service.js'; -export * from './lib/container.handle.js'; -export * from './lib/container.mounts.js'; -export * from './lib/containerStream.util.js'; -export * from './lib/containerRegistry.port.js'; -export * from './lib/dockerClient.port.js'; -export * from './lib/execTimeout.js'; -export * from './lib/types.js'; -export * from './contracts/auth.js'; -export * from './contracts/json.js'; -export * from './contracts/api.js'; +export * from './lib/container.service'; +export * from './lib/container.handle'; +export * from './lib/container.mounts'; +export * from './lib/containerStream.util'; +export * from './lib/containerRegistry.port'; +export * from './lib/dockerClient.port'; +export * from './lib/execTimeout'; +export * from './lib/types'; +export * from './contracts/auth'; +export * from './contracts/json'; +export * from './contracts/api'; diff --git a/packages/docker-runner/src/lib/container.handle.ts b/packages/docker-runner/src/lib/container.handle.ts index be21f7b2e..b0964b2fa 100644 --- a/packages/docker-runner/src/lib/container.handle.ts +++ b/packages/docker-runner/src/lib/container.handle.ts @@ -1,5 +1,5 @@ -import type { DockerClientPort } from './dockerClient.port.js'; -import type { ExecOptions } from './types.js'; +import type { DockerClientPort } from './dockerClient.port'; +import type { ExecOptions } from './types'; /** * Lightweight entity wrapper representing a running (or created) container. diff --git a/packages/docker-runner/src/lib/container.service.ts b/packages/docker-runner/src/lib/container.service.ts index cd42b47a5..d2682419d 100644 --- a/packages/docker-runner/src/lib/container.service.ts +++ b/packages/docker-runner/src/lib/container.service.ts @@ -1,12 +1,12 @@ import { Injectable, Logger } from '@nestjs/common'; import Docker, { ContainerCreateOptions, Exec, type GetEventsOptions } from 'dockerode'; import { PassThrough, Writable } from 'node:stream'; -import { ContainerHandle } from './container.handle.js'; -import { mapInspectMounts } from './container.mounts.js'; -import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util.js'; -import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout.js'; -import type { ContainerRegistryPort } from './containerRegistry.port.js'; -import type { DockerClientPort } from './dockerClient.port.js'; +import { ContainerHandle } from './container.handle'; +import { mapInspectMounts } from './container.mounts'; +import { createUtf8Collector, demuxDockerMultiplex } from './containerStream.util'; +import { ExecIdleTimeoutError, ExecTimeoutError, isExecIdleTimeoutError, isExecTimeoutError } from './execTimeout'; +import type { ContainerRegistryPort } from './containerRegistry.port'; +import type { DockerClientPort } from './dockerClient.port'; import { ContainerOpts, ExecOptions, @@ -17,7 +17,7 @@ import { LogsStreamSession, Platform, PLATFORM_LABEL, -} from './types.js'; +} from './types'; const INTERACTIVE_EXEC_CLOSE_CAPTURE_LIMIT = 256 * 1024; // 256 KiB of characters (~512 KiB memory) diff --git a/packages/docker-runner/src/lib/containerRegistry.port.ts b/packages/docker-runner/src/lib/containerRegistry.port.ts index 0250c6adf..a0490a7f9 100644 --- a/packages/docker-runner/src/lib/containerRegistry.port.ts +++ b/packages/docker-runner/src/lib/containerRegistry.port.ts @@ -1,4 +1,4 @@ -import type { ContainerMount } from './container.mounts.js'; +import type { ContainerMount } from './container.mounts'; export type RegisterContainerStartInput = { containerId: string; diff --git a/packages/docker-runner/src/lib/dockerClient.port.ts b/packages/docker-runner/src/lib/dockerClient.port.ts index 29d64978e..66fd1be98 100644 --- a/packages/docker-runner/src/lib/dockerClient.port.ts +++ b/packages/docker-runner/src/lib/dockerClient.port.ts @@ -1,4 +1,4 @@ -import type { ContainerHandle } from './container.handle.js'; +import type { ContainerHandle } from './container.handle'; import type { ContainerOpts, ExecOptions, @@ -8,7 +8,7 @@ import type { LogsStreamOptions, LogsStreamSession, Platform, -} from './types.js'; +} from './types'; export type DockerEventFilters = Record>; diff --git a/packages/docker-runner/src/service/app.ts b/packages/docker-runner/src/service/app.ts index 56e270ed1..209bb5dbd 100644 --- a/packages/docker-runner/src/service/app.ts +++ b/packages/docker-runner/src/service/app.ts @@ -10,10 +10,10 @@ import { verifyAuthHeaders, type ContainerOpts, type ExecOptions, -} from '../index.js'; -import { createDockerEventsParser } from './dockerEvents.parser.js'; -import type { RunnerConfig } from './config.js'; -import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util.js'; +} from '..'; +import { createDockerEventsParser } from './dockerEvents.parser'; +import type { RunnerConfig } from './config'; +import { closeWebsocket, getWebsocket, type SocketStream } from './websocket.util'; const ensureImageSchema = z.object({ image: z.string().min(1), diff --git a/packages/docker-runner/src/service/env.ts b/packages/docker-runner/src/service/env.ts index 2c569f815..517100d3c 100644 --- a/packages/docker-runner/src/service/env.ts +++ b/packages/docker-runner/src/service/env.ts @@ -1,13 +1,12 @@ import fs from 'node:fs'; import path from 'node:path'; -import { fileURLToPath } from 'node:url'; import { config } from 'dotenv'; const isProduction = () => process.env.NODE_ENV?.toLowerCase() === 'production'; function resolveCandidatePaths(): string[] { - const moduleDir = path.dirname(fileURLToPath(new URL('.', import.meta.url))); + const moduleDir = __dirname; const repoEnv = path.resolve(process.cwd(), '.env'); const packageEnv = path.resolve(moduleDir, '../../.env'); return [repoEnv, packageEnv]; diff --git a/packages/docker-runner/src/service/main.ts b/packages/docker-runner/src/service/main.ts index 53926b912..61be2f7f2 100644 --- a/packages/docker-runner/src/service/main.ts +++ b/packages/docker-runner/src/service/main.ts @@ -1,7 +1,7 @@ -import './env.js'; +import './env'; -import { loadRunnerConfig } from './config.js'; -import { createRunnerApp } from './app.js'; +import { loadRunnerConfig } from './config'; +import { createRunnerApp } from './app'; async function bootstrap(): Promise { try { diff --git a/packages/docker-runner/tsconfig.json b/packages/docker-runner/tsconfig.json index 777bb6885..672bbef46 100644 --- a/packages/docker-runner/tsconfig.json +++ b/packages/docker-runner/tsconfig.json @@ -1,6 +1,8 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { + "module": "CommonJS", + "moduleResolution": "Node", "rootDir": "src", "outDir": "dist", "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo",