diff --git a/src/assets/container/python/Dockerfile b/src/assets/container/python/Dockerfile index eb959c63..20d04017 100644 --- a/src/assets/container/python/Dockerfile +++ b/src/assets/container/python/Dockerfile @@ -1,12 +1,17 @@ FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim +ARG UV_DEFAULT_INDEX +ARG UV_INDEX + WORKDIR /app ENV UV_SYSTEM_PYTHON=1 \ UV_COMPILE_BYTECODE=1 \ UV_NO_PROGRESS=1 \ PYTHONUNBUFFERED=1 \ - DOCKER_CONTAINER=1 + DOCKER_CONTAINER=1 \ + UV_DEFAULT_INDEX=${UV_DEFAULT_INDEX} \ + UV_INDEX=${UV_INDEX} RUN useradd -m -u 1000 bedrock_agentcore diff --git a/src/cli/operations/dev/container-dev-server.ts b/src/cli/operations/dev/container-dev-server.ts index 1fceb571..a2652302 100644 --- a/src/cli/operations/dev/container-dev-server.ts +++ b/src/cli/operations/dev/container-dev-server.ts @@ -1,4 +1,5 @@ import { CONTAINER_INTERNAL_PORT, DOCKERFILE_NAME } from '../../../lib'; +import { getUvBuildArgs } from '../../../lib/packaging/build-args'; import { detectContainerRuntime, getStartHint } from '../../external-requirements/detect'; import { DevServer, type LogLevel, type SpawnConfig } from './dev-server'; import { convertEntrypointToModule } from './utils'; @@ -62,7 +63,7 @@ export class ContainerDevServer extends DevServer { onLog('system', `Building container image: ${this.imageName}...`); const buildResult = spawnSync( this.runtimeBinary, - ['build', '-t', baseImageName, '-f', dockerfilePath, this.config.directory], + ['build', '-t', baseImageName, '-f', dockerfilePath, ...getUvBuildArgs(), this.config.directory], { stdio: 'pipe' } ); @@ -86,10 +87,14 @@ export class ContainerDevServer extends DevServer { ' || (pip install -q uvicorn && pip install -q /app)', ].join('\n'); - const devBuild = spawnSync(this.runtimeBinary, ['build', '-t', this.imageName, '-f', '-', this.config.directory], { - input: devDockerfile, - stdio: ['pipe', 'pipe', 'pipe'], - }); + const devBuild = spawnSync( + this.runtimeBinary, + ['build', '-t', this.imageName, '-f', '-', ...getUvBuildArgs(), this.config.directory], + { + input: devDockerfile, + stdio: ['pipe', 'pipe', 'pipe'], + } + ); this.logBuildOutput(devBuild.stdout, devBuild.stderr, onLog); diff --git a/src/lib/packaging/build-args.ts b/src/lib/packaging/build-args.ts new file mode 100644 index 00000000..e5af3404 --- /dev/null +++ b/src/lib/packaging/build-args.ts @@ -0,0 +1,13 @@ +import { readCliConfig } from '../schemas/io/cli-config'; + +/** + * Return Docker --build-arg flags for UV index URLs configured in ~/.agentcore/config.json. + * Returns an empty array when no custom indexes are configured. + */ +export function getUvBuildArgs(): string[] { + const config = readCliConfig(); + const args: string[] = []; + if (config.uvDefaultIndex) args.push('--build-arg', `UV_DEFAULT_INDEX=${config.uvDefaultIndex}`); + if (config.uvIndex) args.push('--build-arg', `UV_INDEX=${config.uvIndex}`); + return args; +} diff --git a/src/lib/packaging/container.ts b/src/lib/packaging/container.ts index 8ce985b0..79cf7325 100644 --- a/src/lib/packaging/container.ts +++ b/src/lib/packaging/container.ts @@ -1,5 +1,6 @@ import type { AgentEnvSpec } from '../../schema'; import { CONTAINER_RUNTIMES, DOCKERFILE_NAME, ONE_GB } from '../constants'; +import { getUvBuildArgs } from './build-args'; import { PackagingError } from './errors'; import { resolveCodeLocation } from './helpers'; import type { ArtifactResult, PackageOptions, RuntimePackager } from './types/packaging'; @@ -57,9 +58,13 @@ export class ContainerPackager implements RuntimePackager { // Build locally const imageName = `agentcore-package-${agentName}`; - const buildResult = spawnSync(runtime, ['build', '-t', imageName, '-f', dockerfilePath, codeLocation], { - stdio: 'pipe', - }); + const buildResult = spawnSync( + runtime, + ['build', '-t', imageName, '-f', dockerfilePath, ...getUvBuildArgs(), codeLocation], + { + stdio: 'pipe', + } + ); if (buildResult.status !== 0) { return Promise.reject(new PackagingError(`Container build failed:\n${buildResult.stderr?.toString()}`)); diff --git a/src/lib/schemas/io/cli-config.ts b/src/lib/schemas/io/cli-config.ts new file mode 100644 index 00000000..2155bd8b --- /dev/null +++ b/src/lib/schemas/io/cli-config.ts @@ -0,0 +1,27 @@ +import { readFileSync } from 'fs'; +import { homedir } from 'os'; +import { join } from 'path'; + +const CONFIG_FILE = join(homedir(), '.agentcore', 'config.json'); + +export interface CliConfig { + uvDefaultIndex?: string; + uvIndex?: string; +} + +/** + * Read the global CLI config from ~/.agentcore/config.json. + * Returns an empty object if the file doesn't exist or is malformed. + */ +export function readCliConfig(): CliConfig { + try { + const data = readFileSync(CONFIG_FILE, 'utf-8'); + const parsed: Record = JSON.parse(data) as Record; + const config: CliConfig = {}; + if (typeof parsed.uvDefaultIndex === 'string') config.uvDefaultIndex = parsed.uvDefaultIndex; + if (typeof parsed.uvIndex === 'string') config.uvIndex = parsed.uvIndex; + return config; + } catch { + return {}; + } +} diff --git a/src/lib/schemas/io/index.ts b/src/lib/schemas/io/index.ts index c1fb2aad..d9e8c9b5 100644 --- a/src/lib/schemas/io/index.ts +++ b/src/lib/schemas/io/index.ts @@ -11,3 +11,4 @@ export { type PathConfig, } from './path-resolver'; export { ConfigIO, createConfigIO } from './config-io'; +export { readCliConfig, type CliConfig } from './cli-config';