MCPcopy Create free account
hub / github.com/vercel/vercel / startContainer

Function startContainer

packages/container/src/dev.ts:468–658  ·  view source on GitHub ↗
(
  options: StartDevServerOptions,
  reuseKey: string
)

Source from the content-addressed store, hash-verified

466}
467
468async function startContainer(
469 options: StartDevServerOptions,
470 reuseKey: string
471): Promise<StartDevServerResult> {
472 return withSpan(
473 options.span,
474 'container.dev.start',
475 { 'service.name': options.service?.name },
476 async span => {
477 const { config, meta, onStdout, onStderr } = options;
478 const out: DevOutput = { onStdout, onStderr };
479
480 // Fail fast with a clear message if Docker isn't running, rather than
481 // letting `docker build`/`docker run` fail later with a bare exit code.
482 await assertDockerAvailable(out);
483
484 const image = await withSpan(span, 'container.dev.resolve_image', {}, s =>
485 resolveDevImage(options, out, s)
486 );
487
488 const containerPort = await resolveContainerPort(image, out);
489 const containerName = uniqueContainerName(
490 options.service?.name ?? 'service'
491 );
492
493 // Env precedence: CLI process env, then the orchestrator's per-service
494 // env (service URLs, resolved .env values), then a `PORT` the app honors.
495 // Host/shell-only vars (TMPDIR, HOME, PATH, …) are filtered out: they
496 // describe the developer's machine, not the Linux container, and leaking
497 // them breaks apps that rely on container-native values (see
498 // `isHostOnlyEnvVar`). Passed via a temp `--env-file` to keep secrets off
499 // the command line and avoid arg-length limits.
500 const mergedEnv: Record<string, string> = {};
501 for (const [key, value] of Object.entries(process.env)) {
502 if (typeof value === 'string' && !isHostOnlyEnvVar(key)) {
503 mergedEnv[key] = value;
504 }
505 }
506 const metaEnv = (meta?.env ?? {}) as Record<string, string | undefined>;
507 for (const [key, value] of Object.entries(metaEnv)) {
508 if (typeof value === 'string' && !isHostOnlyEnvVar(key)) {
509 mergedEnv[key] = value;
510 }
511 }
512 mergedEnv.PORT = String(containerPort);
513 const envFilePath = writeEnvFile(mergedEnv);
514
515 const command = normalizeCommand(
516 (config as { command?: unknown }).command
517 );
518
519 // Honor the host port the orchestrator pre-allocated for this service
520 // (passed via `meta.port`). Service bindings are built against this port
521 // (`http://127.0.0.1:${preAllocatedPort}/`), so the container must listen
522 // on it for cross-service requests to reach it. Fall back to `0` (an
523 // ephemeral port chosen by Docker) when no port was provided.
524 const requestedHostPort = typeof meta?.port === 'number' ? meta.port : 0;
525

Callers 1

startDevServerFunction · 0.85

Calls 15

withSpanFunction · 0.90
debugFunction · 0.90
assertDockerAvailableFunction · 0.85
resolveDevImageFunction · 0.85
resolveContainerPortFunction · 0.85
uniqueContainerNameFunction · 0.85
isHostOnlyEnvVarFunction · 0.85
writeEnvFileFunction · 0.85
emitFunction · 0.85
spawnFunction · 0.85
onStdoutFunction · 0.85
onStderrFunction · 0.85

Tested by

no test coverage detected