Skip to content

Commit 478fde8

Browse files
feat: support custom package index (UV_DEFAULT_INDEX) for Container builds (#453)
* feat: support custom package index (UV_INDEX_URL) for Container builds Enterprise customers using internal artifact repositories instead of public PyPI can now configure custom uv index URLs in ~/.agentcore/config.json. The CLI forwards these as Docker build args during container image builds (dev, package, deploy). * feat: support custom package index (UV_DEFAULT_INDEX) for Container builds Enterprise customers using internal artifact repositories instead of public PyPI can now configure custom uv index URLs in ~/.agentcore/config.json. The CLI forwards these as Docker build args during container image builds (dev, package, deploy).
1 parent 33523a6 commit 478fde8

File tree

6 files changed

+65
-9
lines changed

6 files changed

+65
-9
lines changed

src/assets/container/python/Dockerfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
22

3+
ARG UV_DEFAULT_INDEX
4+
ARG UV_INDEX
5+
36
WORKDIR /app
47

58
ENV UV_SYSTEM_PYTHON=1 \
69
UV_COMPILE_BYTECODE=1 \
710
UV_NO_PROGRESS=1 \
811
PYTHONUNBUFFERED=1 \
9-
DOCKER_CONTAINER=1
12+
DOCKER_CONTAINER=1 \
13+
UV_DEFAULT_INDEX=${UV_DEFAULT_INDEX} \
14+
UV_INDEX=${UV_INDEX}
1015

1116
RUN useradd -m -u 1000 bedrock_agentcore
1217

src/cli/operations/dev/container-dev-server.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CONTAINER_INTERNAL_PORT, DOCKERFILE_NAME } from '../../../lib';
2+
import { getUvBuildArgs } from '../../../lib/packaging/build-args';
23
import { detectContainerRuntime, getStartHint } from '../../external-requirements/detect';
34
import { DevServer, type LogLevel, type SpawnConfig } from './dev-server';
45
import { convertEntrypointToModule } from './utils';
@@ -62,7 +63,7 @@ export class ContainerDevServer extends DevServer {
6263
onLog('system', `Building container image: ${this.imageName}...`);
6364
const buildResult = spawnSync(
6465
this.runtimeBinary,
65-
['build', '-t', baseImageName, '-f', dockerfilePath, this.config.directory],
66+
['build', '-t', baseImageName, '-f', dockerfilePath, ...getUvBuildArgs(), this.config.directory],
6667
{ stdio: 'pipe' }
6768
);
6869

@@ -86,10 +87,14 @@ export class ContainerDevServer extends DevServer {
8687
' || (pip install -q uvicorn && pip install -q /app)',
8788
].join('\n');
8889

89-
const devBuild = spawnSync(this.runtimeBinary, ['build', '-t', this.imageName, '-f', '-', this.config.directory], {
90-
input: devDockerfile,
91-
stdio: ['pipe', 'pipe', 'pipe'],
92-
});
90+
const devBuild = spawnSync(
91+
this.runtimeBinary,
92+
['build', '-t', this.imageName, '-f', '-', ...getUvBuildArgs(), this.config.directory],
93+
{
94+
input: devDockerfile,
95+
stdio: ['pipe', 'pipe', 'pipe'],
96+
}
97+
);
9398

9499
this.logBuildOutput(devBuild.stdout, devBuild.stderr, onLog);
95100

src/lib/packaging/build-args.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { readCliConfig } from '../schemas/io/cli-config';
2+
3+
/**
4+
* Return Docker --build-arg flags for UV index URLs configured in ~/.agentcore/config.json.
5+
* Returns an empty array when no custom indexes are configured.
6+
*/
7+
export function getUvBuildArgs(): string[] {
8+
const config = readCliConfig();
9+
const args: string[] = [];
10+
if (config.uvDefaultIndex) args.push('--build-arg', `UV_DEFAULT_INDEX=${config.uvDefaultIndex}`);
11+
if (config.uvIndex) args.push('--build-arg', `UV_INDEX=${config.uvIndex}`);
12+
return args;
13+
}

src/lib/packaging/container.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { AgentEnvSpec } from '../../schema';
22
import { CONTAINER_RUNTIMES, DOCKERFILE_NAME, ONE_GB } from '../constants';
3+
import { getUvBuildArgs } from './build-args';
34
import { PackagingError } from './errors';
45
import { resolveCodeLocation } from './helpers';
56
import type { ArtifactResult, PackageOptions, RuntimePackager } from './types/packaging';
@@ -57,9 +58,13 @@ export class ContainerPackager implements RuntimePackager {
5758

5859
// Build locally
5960
const imageName = `agentcore-package-${agentName}`;
60-
const buildResult = spawnSync(runtime, ['build', '-t', imageName, '-f', dockerfilePath, codeLocation], {
61-
stdio: 'pipe',
62-
});
61+
const buildResult = spawnSync(
62+
runtime,
63+
['build', '-t', imageName, '-f', dockerfilePath, ...getUvBuildArgs(), codeLocation],
64+
{
65+
stdio: 'pipe',
66+
}
67+
);
6368

6469
if (buildResult.status !== 0) {
6570
return Promise.reject(new PackagingError(`Container build failed:\n${buildResult.stderr?.toString()}`));

src/lib/schemas/io/cli-config.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { readFileSync } from 'fs';
2+
import { homedir } from 'os';
3+
import { join } from 'path';
4+
5+
const CONFIG_FILE = join(homedir(), '.agentcore', 'config.json');
6+
7+
export interface CliConfig {
8+
uvDefaultIndex?: string;
9+
uvIndex?: string;
10+
}
11+
12+
/**
13+
* Read the global CLI config from ~/.agentcore/config.json.
14+
* Returns an empty object if the file doesn't exist or is malformed.
15+
*/
16+
export function readCliConfig(): CliConfig {
17+
try {
18+
const data = readFileSync(CONFIG_FILE, 'utf-8');
19+
const parsed: Record<string, unknown> = JSON.parse(data) as Record<string, unknown>;
20+
const config: CliConfig = {};
21+
if (typeof parsed.uvDefaultIndex === 'string') config.uvDefaultIndex = parsed.uvDefaultIndex;
22+
if (typeof parsed.uvIndex === 'string') config.uvIndex = parsed.uvIndex;
23+
return config;
24+
} catch {
25+
return {};
26+
}
27+
}

src/lib/schemas/io/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ export {
1111
type PathConfig,
1212
} from './path-resolver';
1313
export { ConfigIO, createConfigIO } from './config-io';
14+
export { readCliConfig, type CliConfig } from './cli-config';

0 commit comments

Comments
 (0)