diff --git a/libs/cli/langgraph_cli/__init__.py b/libs/cli/langgraph_cli/__init__.py index 98a433b31..3dd3d2d51 100644 --- a/libs/cli/langgraph_cli/__init__.py +++ b/libs/cli/langgraph_cli/__init__.py @@ -1 +1 @@ -__version__ = "0.4.5" +__version__ = "0.4.6" diff --git a/libs/cli/langgraph_cli/config.py b/libs/cli/langgraph_cli/config.py index 2d860a619..89819dba9 100644 --- a/libs/cli/langgraph_cli/config.py +++ b/libs/cli/langgraph_cli/config.py @@ -926,35 +926,51 @@ ADD {relpath} /deps/{name} ] ) image_str = docker_tag(config, base_image, api_version) - docker_file_contents = [ - f"FROM {image_str}", - "", - os.linesep.join(config["dockerfile_lines"]), - "", - installs, - "", - "# -- Installing all local dependencies --", - f"""RUN for dep in /deps/*; do \ + + # Prepare docker file contents + docker_file_contents = [] + + # Add syntax directive if we have additional contexts (requires BuildKit frontend.contexts capability) + if local_deps.additional_contexts: + docker_file_contents.extend( + [ + "# syntax=docker/dockerfile:1.4", + "", + ] + ) + + # Add main dockerfile content + docker_file_contents.extend( + [ + f"FROM {image_str}", + "", + os.linesep.join(config["dockerfile_lines"]), + "", + installs, + "", + "# -- Installing all local dependencies --", + f"""RUN for dep in /deps/*; do \ echo "Installing $dep"; \ if [ -d "$dep" ]; then \ echo "Installing $dep"; \ (cd "$dep" && {global_reqs_pip_install} -e .); \ fi; \ done""", - "# -- End of local dependencies install --", - os.linesep.join(env_vars), - "", - js_inst_str, - "", - # Add pip cleanup after all installations are complete - _get_pip_cleanup_lines( - install_cmd=install_cmd, - to_uninstall=build_tools_to_uninstall, - pip_installer=pip_installer, - ), - "", - f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else "", - ] + "# -- End of local dependencies install --", + os.linesep.join(env_vars), + "", + js_inst_str, + "", + # Add pip cleanup after all installations are complete + _get_pip_cleanup_lines( + install_cmd=install_cmd, + to_uninstall=build_tools_to_uninstall, + pip_installer=pip_installer, + ), + "", + f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else "", + ] + ) additional_contexts: dict[str, str] = {} for p in local_deps.additional_contexts: diff --git a/libs/cli/tests/unit_tests/cli/test_cli.py b/libs/cli/tests/unit_tests/cli/test_cli.py index 56fd309a7..862a0e5aa 100644 --- a/libs/cli/tests/unit_tests/cli/test_cli.py +++ b/libs/cli/tests/unit_tests/cli/test_cli.py @@ -141,6 +141,7 @@ services: additional_contexts: - cli_1: {str(pathlib.Path(__file__).parent.parent.parent.parent.absolute())} dockerfile_inline: | + # syntax=docker/dockerfile:1.4 FROM langchain/langgraph-api:3.11 # -- Adding local package . -- ADD . /deps/cli diff --git a/libs/cli/tests/unit_tests/test_config.py b/libs/cli/tests/unit_tests/test_config.py index 4b1751136..1bb761424 100644 --- a/libs/cli/tests/unit_tests/test_config.py +++ b/libs/cli/tests/unit_tests/test_config.py @@ -419,6 +419,7 @@ def test_config_to_docker_simple(): "langchain/langgraph-api", ) expected_docker_stdin = f"""\ +# syntax=docker/dockerfile:1.4 FROM langchain/langgraph-api:3.11 # -- Installing local requirements -- COPY --from=outer-requirements.txt requirements.txt /deps/outer-graphs_reqs_a/graphs_reqs_a/requirements.txt @@ -482,6 +483,7 @@ def test_config_to_docker_outside_path(): ) expected_docker_stdin = ( """\ +# syntax=docker/dockerfile:1.4 FROM langchain/langgraph-api:3.11 # -- Adding non-package dependency unit_tests -- ADD . /deps/outer-unit_tests/unit_tests