MCPcopy Create free account
hub / github.com/ShipSecAI/studio / runComponentInDocker

Function runComponentInDocker

packages/component-sdk/src/runner.ts:93–204  ·  view source on GitHub ↗

* Execute a component in a Docker container * - Starts container with specified image and command * - Mounts a temp directory for structured output at /shipsec-output * - Components should write results to /shipsec-output/result.json * - Stdout/stderr are used purely for logging/progress * - Au

(
  runner: DockerRunnerConfig,
  params: I,
  context: ExecutionContext,
)

Source from the content-addressed store, hash-verified

91 * - Automatically cleans up container and temp directory on exit
92 */
93async function runComponentInDocker<I, O>(
94 runner: DockerRunnerConfig,
95 params: I,
96 context: ExecutionContext,
97): Promise<O> {
98 const { image, command, entrypoint, env = {}, network = 'none', platform, containerName, volumes, timeoutSeconds = 300, detached } = runner;
99
100 context.logger.info(`[Docker] Running ${image} with command: ${formatArgs(command)}`);
101 context.emitProgress(`Starting Docker container: ${image}`);
102
103 // Create temp directory for output and input
104 const outputDir = await mkdtemp(join(tmpdir(), 'shipsec-run-'));
105 const hostOutputPath = join(outputDir, OUTPUT_FILENAME);
106 const hostInputPath = join(outputDir, 'input.json');
107
108 try {
109 // Write inputs to file instead of passing via env or stdin
110 await writeFile(hostInputPath, JSON.stringify(params));
111
112 const dockerArgs = [
113 'run',
114 '--rm',
115 '-i',
116 '--network', network,
117 '--label', `shipsec.runId=${context.runId}`,
118 '--label', `shipsec.nodeRef=${context.componentRef}`,
119 // Mount the directory containing both input and output
120 '-v', `${outputDir}:${CONTAINER_OUTPUT_PATH}`,
121 ];
122
123 if (containerName) {
124 dockerArgs.push('--name', containerName);
125 }
126
127 if (platform && platform.trim().length > 0) {
128 dockerArgs.push('--platform', platform);
129 }
130
131 if (Array.isArray(volumes)) {
132 for (const vol of volumes) {
133 if (!vol || !vol.source || !vol.target) continue;
134 const mode = vol.readOnly ? ':ro' : '';
135 dockerArgs.push('-v', `${vol.source}:${vol.target}${mode}`);
136 }
137 }
138
139 if (runner.ports) {
140 for (const [hostPort, containerPort] of Object.entries(runner.ports)) {
141 dockerArgs.push('-p', `${hostPort}:${containerPort}`);
142 }
143 }
144
145 for (const [key, value] of Object.entries(env)) {
146 dockerArgs.push('-e', `${key}=${value}`);
147 }
148
149 // Tell the container where to read input and write output
150 dockerArgs.push('-e', `SHIPSEC_INPUT_PATH=${CONTAINER_OUTPUT_PATH}/input.json`);

Callers 1

runComponentWithRunnerFunction · 0.85

Calls 6

formatArgsFunction · 0.85
runDockerWithStandardIOFunction · 0.85
runDockerWithPtyFunction · 0.85
infoMethod · 0.80
warnMethod · 0.80
pushMethod · 0.65

Tested by

no test coverage detected