Docker
Functions
isDockerAvailable
function isDockerAvailable(): boolean
Use isDockerAvailable to check whether Docker is installed and running on the current machine before attempting any container-based operations.
Reach for this before any code path that depends on Docker — for example, gating a sandbox execution feature or providing a clear error message when the runtime isn't present. It's a lightweight preflight check that prevents cryptic failures downstream.
Under the hood, it runs docker info with a 5-second timeout. This means it validates both that the Docker CLI is installed and that the Docker daemon is actually running — a process that's installed but not started will return false.
Parameters
None.
Returns
true if Docker is installed and the daemon is responsive, false otherwise. Use the result to branch your logic — either proceed with container operations or surface a human-readable error before anything fails silently.
Heads up
- Returns
falseif the Docker daemon is stopped, even if the CLI is installed. Don't use this as an install check alone. - The 5-second timeout means this call can block for up to 5 seconds in environments where Docker is unresponsive (e.g., a hung daemon). Avoid calling it in hot paths.
Example:
import { spawnSync } from "child_process";
function isDockerAvailable(): boolean {
try {
const result = spawnSync("docker", ["info"], {
stdio: "pipe",
timeout: 5000,
});
return result.status === 0;
} catch {
return false;
}
}
function generateDocsWithSandbox(sourcePath: string) {
if (!isDockerAvailable()) {
console.error(
"Docker is not available. Sandboxed code execution requires Docker to be installed and running.\n" +
"Install Docker at https://docs.docker.com/get-docker/ and ensure the daemon is started."
);
process.exit(1);
}
console.log("Docker detected — proceeding with sandboxed example generation.");
// Container-dependent logic would follow here
console.log(`Generating docs for: ${sourcePath}`);
}
generateDocsWithSandbox("./src");
// Output when Docker is running:
// Docker detected — proceeding with sandboxed example generation.
// Generating docs for: ./src
// Output when Docker is not running:
// Docker is not available. Sandboxed code execution requires Docker to be installed and running.
// Install Docker at https://docs.docker.com/get-docker/ and ensure the daemon is started.
parseEnvironments
function parseEnvironments(envString: string): DockerEnvironment[]
Use parseEnvironments to convert a comma-separated environment string into structured DockerEnvironment objects ready for container configuration.
Reach for this when you're accepting environment targets as a single string — from a CLI flag, config file, or environment variable — and need to resolve them into typed objects your tooling can act on. It sits at the boundary between user input and the internal environment registry.
The function splits the string on commas, trims whitespace, and looks up each name against a built-in DOCKER_ENVIRONMENTS registry. Only recognized environment names resolve to objects; unrecognized names are silently dropped.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
envString | string | Yes | Comma-separated list of environment names (e.g. "staging,production"). Whitespace around names is ignored. |
Returns
Returns an array of DockerEnvironment objects matching the names found in the registry. Pass the result directly to your container orchestration logic — each object carries the resolved configuration for that environment. If no names match, returns an empty array.
Heads up
- Unrecognized environment names are silently filtered out rather than throwing. If the returned array is shorter than expected, check that your names exactly match the registered environment identifiers.
Example:
type DockerEnvironment = {
name: string
image: string
port: number
}
const DOCKER_ENVIRONMENTS: DockerEnvironment[] = [
{ name: "development", image: "node:20-alpine", port: 3000 },
{ name: "staging", image: "node:20-slim", port: 8080 },
{ name: "production", image: "node:20-slim", port: 443 },
]
function parseEnvironments(envString: string): DockerEnvironment[] {
const names = envString.split(",").map((s) => s.trim()).filter(Boolean)
const envs: DockerEnvironment[] = []
for (const name of names) {
const env = DOCKER_ENVIRONMENTS.find((e) => e.name === name)
if (env) envs.push(env)
}
return envs
}
// Simulates a value coming from a CLI flag: --envs "staging, production"
const cliInput = "staging, production"
const resolved = parseEnvironments(cliInput)
console.log(`Resolved ${resolved.length} environment(s):`)
for (const env of resolved) {
console.log(` ${env.name} → ${env.image} on port ${env.port}`)
}
// Expected output:
// Resolved 2 environment(s):
// staging → node:20-slim on port 8080
// production → node:20-slim on port 443
getCompatibleEnvironments
function getCompatibleEnvironments(language: string, environments: DockerEnvironment[]): DockerEnvironment[]
Use getCompatibleEnvironments to filter a list of Docker environments down to only those that support a given programming language.
Reach for this when you're about to run a code snippet and need to know which execution environments are valid for it. In a typical skrypt workflow, you'd call this before spinning up a container to avoid passing an incompatible environment to the runner.
It filters the provided environments array, keeping only entries whose languages list includes the specified language.
| Name | Type | Required | Description |
|---|---|---|---|
language | string | Yes | The programming language to match against — e.g. "typescript", "python", "go". Must match the strings stored in each environment's languages array exactly (case-sensitive). |
environments | DockerEnvironment[] | Yes | The full pool of available Docker environments to filter. Typically the complete list returned from your environment config or registry. |
Returns the subset of DockerEnvironment[] whose languages field includes the target language. Pass the result directly to your container runner to guarantee compatibility. If no environments match, returns an empty array — check for this before attempting to execute.
- Heads up: Matching is exact and case-sensitive.
"TypeScript"won't match"typescript". Normalize your language strings before calling this if they come from user input or external sources.
Example:
interface DockerEnvironment {
id: string;
image: string;
languages: string[];
description: string;
}
function getCompatibleEnvironments(
language: string,
environments: DockerEnvironment[]
): DockerEnvironment[] {
return environments.filter((env) => env.languages.includes(language));
}
const allEnvironments: DockerEnvironment[] = [
{
id: "node-20",
image: "skrypt/runner-node:20",
languages: ["typescript", "javascript"],
description: "Node.js 20 LTS runtime",
},
{
id: "python-311",
image: "skrypt/runner-python:3.11",
languages: ["python"],
description: "Python 3.11 runtime",
},
{
id: "go-121",
image: "skrypt/runner-go:1.21",
languages: ["go"],
description: "Go 1.21 runtime",
},
{
id: "polyglot",
image: "skrypt/runner-polyglot:latest",
languages: ["typescript", "python", "go"],
description: "Multi-language runtime for mixed projects",
},
];
const compatible = getCompatibleEnvironments("typescript", allEnvironments);
console.log(`Found ${compatible.length} compatible environment(s) for TypeScript:`);
compatible.forEach((env) => {
console.log(` - ${env.id} (${env.image})`);
});
// Expected output:
// Found 2 compatible environment(s) for TypeScript:
// - node-20 (skrypt/runner-node:20)
// - polyglot (skrypt/runner-polyglot:latest)
runInDocker
async function runInDocker(snippet: ExtractedSnippet, environment: DockerEnvironment, config: RunnerConfig): Promise<TestResult>
Use runInDocker to validate that a code snippet actually executes correctly by running it in an isolated Docker container and capturing the result.
This is the core verification step in skrypt's example-testing pipeline. After generating code examples for your documentation, call runInDocker to confirm each snippet runs without errors before publishing — catching broken examples before your users do.
It spins up a fresh Docker container for each snippet, writes the code to a temp file, executes it inside the container, then tears everything down. Each run is fully isolated, so side effects from one snippet can't contaminate another.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
snippet | ExtractedSnippet | Yes | The extracted code snippet to test, including its source code, language, and metadata. Produced by skrypt's scanner. |
environment | DockerEnvironment | Yes | Docker image and runtime configuration — controls which language runtime and version the snippet runs against (e.g., node:20-alpine, python:3.11-slim). |
config | RunnerConfig | Yes | Execution settings including timeout, memory limits, and whether to treat non-zero exit codes as failures. Tune this to avoid flaky timeouts on slow CI machines. |
Returns
Returns a Promise<TestResult> containing the exit code, stdout, stderr, and execution duration. Check result.passed to gate your doc build — if it's false, surface result.stderr to understand what broke.
Heads up
- Docker must be running on the host machine before calling this. If the daemon isn't available, the function will throw rather than return a failed
TestResult. - Each invocation creates and destroys a temporary directory on the host. In high-volume doc generation runs, call these sequentially or with a concurrency limit to avoid exhausting disk I/O.
Example:
type ExtractedSnippet = {
id: string;
language: "typescript" | "python";
code: string;
sourceFile: string;
};
type DockerEnvironment = {
image: string;
workdir: string;
};
type RunnerConfig = {
timeoutMs: number;
memoryLimitMb: number;
failOnNonZeroExit: boolean;
};
type TestResult = {
passed: boolean;
exitCode: number;
stdout: string;
stderr: string;
durationMs: number;
};
// Mock implementation — replace with actual runInDocker import in your project
async function runInDocker(
snippet: ExtractedSnippet,
environment: DockerEnvironment,
config: RunnerConfig
): Promise<TestResult> {
const start = Date.now();
// Simulates a successful run of the snippet
await new Promise((res) => setTimeout(res, 120));
return {
passed: true,
exitCode: 0,
stdout: "User created: usr_4f8a2b1c9d\n",
stderr: "",
durationMs: Date.now() - start,
};
}
const snippet: ExtractedSnippet = {
id: "snip_7e3d91a0b2",
language: "typescript",
sourceFile: "src/users/createUser.ts",
code: `
const user = { id: "usr_4f8a2b1c9d", email: "ada@example.com" };
console.log("User created:", user.id);
`,
};
const environment: DockerEnvironment = {
image: "node:20-alpine",
workdir: "/app",
};
const config: RunnerConfig = {
timeoutMs: 10000,
memoryLimitMb: 128,
failOnNonZeroExit: true,
};
async function main() {
try {
const result = await runInDocker(snippet, environment, config);
if (!result.passed) {
console.error(`Snippet ${snippet.id} failed (exit ${result.exitCode}):`);
console.error(result.stderr);
process.exit(1);
}
console.log(`✓ Snippet ${snippet.id} passed in ${result.durationMs}ms`);
console.log("Output:", result.stdout.trim());
// Expected output:
// ✓ Snippet snip_7e3d91a0b2 passed in 120ms
// Output: User created: usr_4f8a2b1c9d
} catch (err) {
console.error("Docker runner error — is the Docker daemon running?", err);
process.exit(1);
}
}
main();