feat(cli): add internal docker tag support

This commit is contained in:
Tat Dat Duong
2025-04-17 22:15:10 +02:00
parent 18a9ae45f3
commit 5a200cd89e
2 changed files with 43 additions and 11 deletions
+15 -3
View File
@@ -273,6 +273,7 @@ def _build(
pull: bool,
tag: str,
passthrough: Sequence[str] = (),
base_docker_tag: Optional[str] = None,
):
# pull latest images
if pull:
@@ -280,10 +281,13 @@ def _build(
subp_exec(
"docker",
"pull",
langgraph_cli.config.docker_tag(config_json, base_image),
langgraph_cli.config.docker_tag(
config_json, base_image, base_docker_tag
),
verbose=True,
)
)
set("Building...")
# apply options
args = [
@@ -294,7 +298,7 @@ def _build(
]
# apply config
stdin, additional_contexts = langgraph_cli.config.config_to_docker(
config, config_json, base_image
config, config_json, base_image, base_docker_tag
)
# add additional_contexts
if additional_contexts:
@@ -355,7 +359,15 @@ def build(
raise click.UsageError("Docker not installed") from None
config_json = langgraph_cli.config.validate_config_file(config)
_build(
runner, set, config, config_json, base_image, pull, tag, docker_build_args
runner,
set,
config,
config_json,
base_image,
pull,
tag,
docker_build_args,
config_json.get("_INTERNAL_docker_tag"),
)
+28 -8
View File
@@ -326,6 +326,10 @@ class Config(TypedDict, total=False):
Must be >= 20 if provided.
"""
_INTERNAL_docker_tag: Optional[str]
"""Optional. Internal use only.
"""
pip_config_file: Optional[str]
"""Optional. Path to a pip config file (e.g., "/etc/pip.conf" or "pip.ini") for controlling
package installation (custom indices, credentials, etc.).
@@ -480,6 +484,7 @@ def validate_config(config: Config) -> Config:
"node_version": node_version,
"python_version": python_version,
"pip_config_file": config.get("pip_config_file"),
"_INTERNAL_docker_tag": config.get("_INTERNAL_docker_tag"),
"dependencies": config.get("dependencies", []),
"dockerfile_lines": config.get("dockerfile_lines", []),
"graphs": config.get("graphs", {}),
@@ -1025,7 +1030,10 @@ def _get_node_pm_install_cmd(config_path: pathlib.Path, config: Config) -> str:
def python_config_to_docker(
config_path: pathlib.Path, config: Config, base_image: str
config_path: pathlib.Path,
config: Config,
base_image: str,
base_docker_tag: Optional[str] = None,
) -> tuple[str, dict[str, str]]:
"""Generate a Dockerfile from the configuration."""
# configure pip
@@ -1160,7 +1168,7 @@ ADD {relpath} /deps/{name}
)
docker_file_contents = [
f"FROM {base_image}:{config['python_version']}",
f"FROM {base_image}:{base_docker_tag or config['python_version']}",
"",
os.linesep.join(config["dockerfile_lines"]),
"",
@@ -1192,7 +1200,10 @@ ADD {relpath} /deps/{name}
def node_config_to_docker(
config_path: pathlib.Path, config: Config, base_image: str
config_path: pathlib.Path,
config: Config,
base_image: str,
base_docker_tag: Optional[str] = None,
) -> tuple[str, dict[str, str]]:
faux_path = f"/deps/{config_path.parent.name}"
install_cmd = _get_node_pm_install_cmd(config_path, config)
@@ -1222,7 +1233,7 @@ def node_config_to_docker(
env_vars.append(f"ENV LANGSERVE_GRAPHS='{json.dumps(config['graphs'])}'")
docker_file_contents = [
f"FROM {base_image}:{config['node_version']}",
f"FROM {base_image}:{base_docker_tag or config['node_version']}",
"",
os.linesep.join(config["dockerfile_lines"]),
"",
@@ -1246,8 +1257,14 @@ def default_base_image(config: Config) -> str:
return "langchain/langgraph-api"
def docker_tag(config: Config, base_image: Optional[str] = None) -> str:
def docker_tag(
config: Config,
base_image: Optional[str] = None,
base_docker_tag: Optional[str] = None,
) -> str:
base_image = base_image or default_base_image(config)
if base_docker_tag:
return f"{base_image}:{base_docker_tag}"
if config.get("node_version") and not config.get("python_version"):
return f"{base_image}:{config['node_version']}"
@@ -1255,14 +1272,17 @@ def docker_tag(config: Config, base_image: Optional[str] = None) -> str:
def config_to_docker(
config_path: pathlib.Path, config: Config, base_image: Optional[str] = None
config_path: pathlib.Path,
config: Config,
base_image: Optional[str] = None,
base_docker_tag: Optional[str] = None,
) -> tuple[str, dict[str, str]]:
base_image = base_image or default_base_image(config)
if config.get("node_version") and not config.get("python_version"):
return node_config_to_docker(config_path, config, base_image)
return node_config_to_docker(config_path, config, base_image, base_docker_tag)
return python_config_to_docker(config_path, config, base_image)
return python_config_to_docker(config_path, config, base_image, base_docker_tag)
def config_to_compose(