Skip to main content
A build machine on a restricted network has no route to pypi.org, npmjs.org, GitHub, or Docker Hub. Every package, tool, interpreter, and container image comes from an internal registry, such as Artifactory or Nexus. Configure each tool on that machine to use the internal registry, then build an Agent Server image with the LangGraph CLI. pip, uv, uv’s Python downloads, and the image build each read their own setting. Configuring one leaves the others pointed at the public internet. Work through the sections in order, then run the checks in Verify the setup. The LangGraph CLI is a Python package, so a JavaScript project needs the pip and uv setup too.
This page covers the build machine. To run the image you build, see Deploy with control plane or Self-host standalone servers. For the egress a running deployment needs, see Egress for billing and operational telemetry.

Prerequisites

Collect the following from your platform team before you start:
  • PyPI repository URL: The internal index that proxies or hosts Python packages, written as <PYPI_INDEX_URL> on this page. For example, https://pypi.example.internal/simple.
  • Container registry: The registry host, plus the port if it has one, written as <DOCKER_REGISTRY>. It must hold a mirror of the Agent Server base image. See Additional images for Agent Server builds.
  • npm registry URL (JavaScript only): The internal registry that proxies or hosts npm packages, written as <NPM_REGISTRY_URL>. For example, https://npm.example.internal. Leave off the trailing slash, because Corepack appends paths to it.
  • CA bundle: The path to the PEM file for your internal certificate authority (CA), written as <CA_BUNDLE_PATH>. Internal registries usually serve certificates signed by your organization’s own CA, which operating systems and tools do not trust by default.
  • Root access: Whether you have sudo on the build machine. Without sudo, use the per-user file locations on this page. Ask the platform team to install OS packages and the CA.
  • Python versions: Which versions the OS package repositories provide.

Trust the internal CA

Every later step connects to the internal registry over HTTPS. Until the machine trusts the internal CA, those connections fail with certificate errors, so install the CA first:
  1. Add <CA_BUNDLE_PATH> to the operating system trust store. The command depends on the OS. For example, on Debian and Ubuntu, copy the file to /usr/local/share/ca-certificates/ with a .crt extension. Then run sudo update-ca-certificates.
  2. On Linux, copy the CA to /etc/docker/certs.d/<DOCKER_REGISTRY>/ca.crt so Docker trusts the internal registry. For details, see Docker’s Verify repository client with certificates.
pip and uv each need their own CA setting, covered in Configure pip and Configure uv.

Configure pip

Set the index once in a pip configuration file. A long URL passed as --index-url on each command is easy to get wrong, and a missing space between two flags produces a misleading 404. Create ~/.config/pip/pip.conf. To apply the setting to every user on the machine, create /etc/pip.conf instead:
  • index-url: Replaces pypi.org as the package index.
  • cert: The CA bundle pip uses to verify the index. Older pip releases do not read the OS trust store, so set it explicitly.
If the index uses plain HTTP, add trusted-host = <host> with the index host name. For the full list of file locations and keys, see pip’s Configuration docs.

Install uv from the internal index

Install uv as a Python package from the internal index. The uv install script (curl ... | sh) does not work on a restricted network, because it downloads the uv binary from releases.astral.sh or GitHub. PyPI hosts uv as a wheel that contains the binary. On some distributions, venv ships as a separate OS package, such as python3-venv on Debian and Ubuntu. Install uv into its own virtual environment so it does not touch the system Python. Then link the binaries onto your PATH:
The pip install reads the pip.conf from the previous section, so it resolves against <PYPI_INDEX_URL>. uv self update works only for a uv installed by the install script. To upgrade this uv, run ~/.local/share/uv-bootstrap/bin/pip install --upgrade uv.

Configure uv

uv does not read pip.conf or PIP_INDEX_URL. Without its own setting, uv resolves against pypi.org. Set the following once in your shell profile, such as ~/.bashrc:
  • UV_DEFAULT_INDEX: Replaces pypi.org as the default index.
  • UV_SYSTEM_CERTS: Loads certificates from the OS trust store, which holds the internal CA. By default, uv trusts only its bundled roots.
  • UV_PYTHON_DOWNLOADS: Stops uv from downloading Python. Provide the Python interpreter explains why.
UV_SYSTEM_CERTS requires uv 0.11.0 or later. Earlier versions use UV_NATIVE_TLS=true, which later versions still accept with a deprecation warning.
To trust only the internal CA, set SSL_CERT_FILE=<CA_BUNDLE_PATH> in place of UV_SYSTEM_CERTS. SSL_CERT_FILE replaces both uv’s bundled roots and the OS trust store. For every setting, see uv’s environment variable reference.

Provide the Python interpreter

The Agent Server image ships its own Python. The build machine needs Python 3.10 or later only to run pip, uv, and the LangGraph CLI. Install it from the OS repositories, for example on RHEL-family distributions:
uv finds the interpreter on PATH. Keep UV_PYTHON_DOWNLOADS=never: without it, uv tries to download a missing interpreter from GitHub and retries with no clear error. If the OS repositories do not provide a supported version, see uv’s Installing Python guide.

Build the Agent Server image

The image build runs inside Docker, so the pip and uv settings and the OS trust store on the build machine do not apply to it. Set the base image, the package registry, and the internal CA in langgraph.json instead. To prepare the build:
  1. Install the LangGraph CLI. It resolves against UV_DEFAULT_INDEX:
  2. Log in to the internal registry:
  3. Copy the CA bundle into the project directory, next to langgraph.json. The build can copy files only from the project directory:
Then follow the steps for your project language.

Build a Python project

Do not rely on pip_config_file alone. The CLI installs dependencies with uv pip install by default (pip_installer set to auto), and uv does not read the pip configuration file. The build then resolves against pypi.org and fails. Setting pip_installer to pip does not fix it either: the step that installs the server package still reads the default index. Set the UV_DEFAULT_INDEX build argument in dockerfile_lines instead.
To build the image:
  1. Set base_image and dockerfile_lines in langgraph.json:
    • base_image: The mirrored Agent Server image, without a tag. The CLI appends a tag built from python_version, plus api_version or image_distro when you set them. With the configuration above, the build pulls <DOCKER_REGISTRY>/langchain/langgraph-api:3.12, so that tag must exist in the registry.
    • dockerfile_lines: Lines the CLI inserts after FROM. The COPY and RUN lines append the internal CA to the image’s system CA bundle, which keeps the public roots. The two ARG lines apply to every install step in the build, including installs from a uv.lock file. SSL_CERT_FILE points uv at the system bundle, which uv otherwise ignores, and UV_DEFAULT_INDEX points uv at the internal index. ARG values are visible in docker history, so do not put credentials in <PYPI_INDEX_URL>.
    If the index uses a certificate from a public CA, leave out the COPY, RUN, and SSL_CERT_FILE lines.
  2. Build the image:

Build a JavaScript project

The build installs packages with the package manager that matches the project’s lockfile. Node.js does not read the system CA bundle, so the build trusts the internal CA through NODE_EXTRA_CA_CERTS instead. To build the image:
  1. Set base_image and dockerfile_lines in langgraph.json:
    • base_image: The mirrored JavaScript Agent Server image, without a tag. With the configuration above, the build pulls <DOCKER_REGISTRY>/langchain/langgraphjs-api:20, so that tag must exist in the registry.
    • dockerfile_lines: The COPY line puts the internal CA in the image, and NODE_EXTRA_CA_CERTS adds it to the roots Node.js trusts. NPM_CONFIG_REGISTRY points npm and pnpm at the internal registry. ARG values are visible in docker history, so do not put credentials in <NPM_REGISTRY_URL>.
    If the registry uses a certificate from a public CA, leave out the COPY and NODE_EXTRA_CA_CERTS lines.
  2. Add the settings for your package manager. The image runs pnpm and Yarn through Corepack, which downloads the package manager itself from the npm registry:
    • npm (package-lock.json, or no lockfile): No other settings. npm fetches from NPM_CONFIG_REGISTRY even when package-lock.json records public URLs.
    • pnpm (pnpm-lock.yaml): Add "ARG COREPACK_NPM_REGISTRY=<NPM_REGISTRY_URL>" to dockerfile_lines. Pin pnpm in package.json, for example "packageManager": "pnpm@9.15.9".
    • Yarn 1 (yarn.lock): Add the same COREPACK_NPM_REGISTRY line, and pin Yarn, for example "packageManager": "yarn@1.22.22". Yarn 1 downloads from the URLs recorded in yarn.lock, so regenerate the lockfile against <NPM_REGISTRY_URL>.
    • Yarn 2 or later (yarn.lock): Replace the NPM_CONFIG_REGISTRY line with "ARG YARN_NPM_REGISTRY_SERVER=<NPM_REGISTRY_URL>", add the COREPACK_NPM_REGISTRY line, and pin Yarn, for example "packageManager": "yarn@4.9.2".
    The build copies the whole project directory into the image, including any .npmrc file. Do not store registry tokens in a project .npmrc.
  3. Build the image:
For every langgraph.json key, see the LangGraph CLI configuration file reference.

Verify the setup

Run these checks after setup and at the start of each working session. Each check confirms one section and shows the expected output.

Check CA trust

A certificate error here means the CA is not in the OS trust store.

Check pip

The first line must show <PYPI_INDEX_URL>. If it is missing, pip is using pypi.org.

Check the uv installation

The output shows the installed version. A command not found error means ~/.local/bin is not on your PATH.

Check the uv configuration

The --index-url line must show <PYPI_INDEX_URL>, and a resolved version confirms TLS works.

Check the Python interpreter

The output is the path to the interpreter, such as /usr/bin/python3.12. To confirm that a missing version fails immediately:

Check the image build

For a Python project:
For a JavaScript project that uses npm:
FROM must name the internal registry, and every line from dockerfile_lines must be present.

Next steps

langgraph build leaves the image on the build machine. To run it: