# How to Set Up Needle 2 for Offline and Air-Gapped Environments: Complete Deployment Guide

> Deploy Needle 2 for offline and air-gapped environments. Run local inference, fine-tuning, and tool-calling with a single binary and offline Hugging Face caching. Get the complete guide.

- Repository: [Cactus Compute, Inc./needle](https://github.com/cactus-compute/needle)
- Tags: how-to-guide
- Published: 2026-08-25

---

**Needle 2 runs entirely from a single native engine binary downloaded once from Hugging Face, after which all inference, LoRA fine-tuning, and tool-calling execute locally without network access by caching `libneedle.so` (or platform equivalent) and setting `HF_HUB_OFFLINE=1`.**

Needle 2 by Cactus-Compute is engineered for secure deployments where network connectivity is restricted or impossible. Unlike frameworks that require ongoing cloud dependencies, Needle 2 depends solely on a single native library that can be transferred manually to air-gapped systems, making offline setup straightforward once you understand the cache mechanics and environment overrides.

## Step 1: Download the Engine Binary on a Connected Host

The first step in air-gapped deployment is obtaining the platform-specific native engine on a machine with internet access. According to the source code in [`needle/agent/fetch.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/fetch.py), the `ENGINE_VERSION` is hardcoded as `"2.0.3"` (lines 8-9), and the `fetch_library` function (lines 88-101) handles platform detection, downloads the appropriate wheel from the Hugging Face repository *Cactus-Compute/needle2*, extracts the native library, and writes it to `~/.cache/cactus-needle/<engine-version>/`.

To download the engine manually, use the CLI command:

```bash
needle fetch --platform-tag manylinux2014_x86_64

```

This command places the engine at `~/.cache/cactus-needle/2.0.3/libneedle.so` on Linux (or `.dylib` on macOS, `.dll` on Windows). You can also trigger this programmatically via the Python API by calling `fetch_library()` from `needle.agent.fetch`, which performs the same extraction logic.

## Step 2: Transfer the Engine to the Air-Gapped Device

Once cached, the engine file must be transferred to the target device via physical media (USB, external drive) or secure file transfer. You have three options for placing the library on the air-gapped system:

1. **Standard Cache Location**: Copy the file to `~/.cache/cactus-needle/2.0.3/libneedle.so` (matching the exact version directory structure).
2. **Package Directory**: Place the library inside the installed `needle/` package directory, which takes precedence over the cache lookup.
3. **Environment Override**: Set `NEEDLE_LIB_PATH` to point directly to the file location, bypassing cache discovery entirely.

As implemented in [`needle/cli.py`](https://github.com/cactus-compute/needle/blob/main/needle/cli.py) (lines 38-43), the `NEEDLE_LIB_PATH` environment variable allows you to specify an exact path:

```bash
export NEEDLE_LIB_PATH=/secure/path/to/libneedle.so

```

This override is particularly useful in hardened environments where home directories are non-standard or read-only.

## Step 3: Install the Python Package Without Network Access

With the engine binary staged, install the Python package and its dependencies using local wheels only. On your connected machine, first download all necessary artifacts:

```bash
pip download cactus-needle -d ./needle_packages

```

Transfer the entire `needle_packages` directory to your air-gapped host. Then install using the `--no-index` flag to prevent pip from reaching out to PyPI:

```bash
pip install --no-index --find-links ./needle_packages cactus-needle

```

For strict air-gapped safety, export `HF_HUB_OFFLINE=1` before running Needle. As documented in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md) (lines 156-164), this setting ensures that any accidental request for the engine fails fast with a clear error instead of attempting to download. Configure this in your shell profile or deployment scripts:

```bash
export HF_HUB_OFFLINE=1
export NEEDLE_LIB_PATH=$HOME/.cache/cactus-needle/2.0.3/libneedle.so

```

## Including Model Weights in Offline Environments

Model weights are not bundled with the engine binary. According to the repository structure, models are packaged as `.cact` archives produced via `needle build`. These archives contain all weights necessary for inference and must be transferred alongside the engine.

To deploy a complete offline solution:

1. Build your model archive on the connected host: `needle build --model <path> --output model.cact`
2. Transfer the `.cact` file to the air-gapped device
3. Reference the local path when running inference

## Verifying Your Offline Installation

Confirm that Needle 2 operates without network connectivity by testing the cache status and running inference:

```bash

# Should report the engine is already cached without network traffic

needle fetch

# Should execute entirely locally

needle run --checkpoint model.cact --query "Test prompt"

```

If `needle fetch` attempts to download or hangs, verify that `HF_HUB_OFFLINE=1` is set and that `NEEDLE_LIB_PATH` points to a valid `libneedle` file.

## Key Source Files and Implementation Details

Understanding these core files helps troubleshoot offline deployments:

- **[`needle/agent/fetch.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/fetch.py)**: Contains `fetch_library()` which manages platform detection and engine extraction (lines 88-101). Defines `ENGINE_VERSION` constant (lines 8-9).
- **[`needle/cli.py`](https://github.com/cactus-compute/needle/blob/main/needle/cli.py)**: Implements the `needle fetch` command and `NEEDLE_LIB_PATH` environment variable parsing (lines 38-43).
- **[`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md)**: Documents the `HF_HUB_OFFLINE` flag and cache location conventions (lines 156-164).

## Summary

- **Single Binary Dependency**: Needle 2 requires only `libneedle.so` (or platform equivalent) to run offline, cached at `~/.cache/cactus-needle/2.0.3/`.
- **Three-Step Deployment**: Download the engine via `needle fetch` on a connected host, transfer the file to the air-gapped device, and install Python wheels using `pip install --no-index`.
- **Environment Hardening**: Set `HF_HUB_OFFLINE=1` to prevent accidental network calls and `NEEDLE_LIB_PATH` to override default cache locations.
- **Model Portability**: Transfer `.cact` archives built with `needle build` separately from the engine binary for complete offline inference capabilities.

## Frequently Asked Questions

### Where does Needle 2 store the engine binary after download?

The engine is stored in the user cache directory under `~/.cache/cactus-needle/<engine-version>/`, where `<engine-version>` corresponds to the `ENGINE_VERSION` constant (currently `"2.0.3"`). The specific file is `libneedle.so` on Linux, `libneedle.dylib` on macOS, or `needle.dll` on Windows, as handled by `fetch_library` in [`needle/agent/fetch.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/fetch.py).

### Can I run Needle 2 on a machine that has never had internet access?

Yes. As long as you manually transfer the engine binary (via `NEEDLE_LIB_PATH` or by placing it in the cache directory) and install the Python package from local wheels, Needle 2 operates entirely offline. The framework makes no external calls once the engine is present on disk, provided you set `HF_HUB_OFFLINE=1`.

### What happens if I forget to set `HF_HUB_OFFLINE=1` in an air-gapped environment?

Without `HF_HUB_OFFLINE=1`, Needle 2 may attempt to fetch the engine from Hugging Face if the cache lookup fails, resulting in connection timeouts or unclear errors. Setting this environment variable forces an immediate, explicit failure with a clear error message if the engine is missing, as documented in [`doc/apis.md`](https://github.com/cactus-compute/needle/blob/main/doc/apis.md).

### How do I update the Needle 2 engine in an offline environment?

Download the updated engine binary on a connected machine using `needle fetch` (which respects the `ENGINE_VERSION` defined in [`needle/agent/fetch.py`](https://github.com/cactus-compute/needle/blob/main/needle/agent/fetch.py)), then transfer the new `libneedle` file to your air-gapped systems. Update the `NEEDLE_LIB_PATH` if necessary, or place it in the version-specific cache directory corresponding to the new engine version.